#include <pkix_messages.h>
#include <stdio.h>
#include <Init.h>

int main(int argc, char * argv[]) {

  CertRequest * req;
  buffer_t buf;

  uint32 status;

/*
class EXPORTCLASS CertRequest : public asn_sequence {
public:
  asn_integer		certReqId;	
  CertTemplate		certTemplate;
  Controls		controls;
  CertRequest(security_t s = ASN_PUBLIC) : asn_sequence(s) {
    strcpy(objType, "CertRequest");
    controls.set_optional();
    register_child(&certReqId);
    register_child(&certTemplate);
    register_child(&controls);
  };
};


class EXPORTCLASS CertTemplate : public asn_sequence {
public:
  asn_explicit<asn_integer, CLASS_CONTEXT_SPECIFIC, 0> 		version;
  asn_explicit<asn_integer, CLASS_CONTEXT_SPECIFIC, 1>		serialNumber;
  asn_explicit<AlgorithmIdentifier, CLASS_CONTEXT_SPECIFIC, 2>	signingAlg;
  asn_explicit<asn_x500name, CLASS_CONTEXT_SPECIFIC, 3>		issuer;
  asn_explicit<OptionalValidity, CLASS_CONTEXT_SPECIFIC, 4>	validity;
  asn_explicit<asn_x500name, CLASS_CONTEXT_SPECIFIC, 5>		subject;
  asn_explicit<SubjectPublicKeyInfo, CLASS_CONTEXT_SPECIFIC, 6>	publicKey;
  asn_explicit<UniqueIdentifier, CLASS_CONTEXT_SPECIFIC, 7>	issuerUID;
  asn_explicit<UniqueIdentifier, CLASS_CONTEXT_SPECIFIC, 8>	subjectUID;
  asn_explicit<x509_Extensions, CLASS_CONTEXT_SPECIFIC, 9>	extensions;
  CertTemplate(security_t s = ASN_PUBLIC) : asn_sequence(s) {
    strcpy(objType, "CertTemplate");
    version.set_optional();
    serialNumber.set_optional();
    signingAlg.set_optional();
    issuer.set_optional();
    validity.set_optional();
    subject.set_optional();
    publicKey.set_optional();
    issuerUID.set_optional();
    subjectUID.set_optional();
    extensions.set_optional();
    register_child(&version);
    register_child(&serialNumber);
    register_child(&signingAlg);
    register_child(&issuer);
    register_child(&validity);
    register_child(&subject);
    register_child(&publicKey);
    register_child(&issuerUID);
    register_child(&subjectUID);
    register_child(&extensions);
  };
};
  
*/

  Init(Init_CA);

  req = new CertRequest;
  if ((status = req->certReqId.set_value(42)) != 0) {
    fprintf(stdout, "Set_value failed\n");
    fprintf(stderr, "Error %lu setting int value\n", status);
  };
  buf.clear();
  req->display_state_flags(buf);
  fprintf(stdout, "Only first int set, before write:\n%.*s", buf.data_len, buf.data);
  buf.clear();
  if ((status = req->write(buf)) != 0) {
    fprintf(stdout, "First write failed\n");
    fprintf(stderr, "Error %lu on first write\n", status);
  };
  buf.clear();
  req->display_state_flags(buf);
  fprintf(stdout, "After write:\n%.*s", buf.data_len, buf.data);
  if ((status = req->certTemplate.signingAlg.value.algorithm.set_value("DSS")) != 0) {
    fprintf(stdout, "set_value(alg) failed\n");
    fprintf(stderr, "Error %lu setting alg value\n", status);
  };
  buf.clear();
  req->display_state_flags(buf);
  fprintf(stdout, "After set_value of algIdent.alg:\n%.*s", buf.data_len, buf.data);
  buf.clear();
  if ((status = req->write(buf)) != 0) {
    fprintf(stdout, "Secoind write failed\n");
    fprintf(stderr, "Error %lu on write\n", status);
  };
  buf.clear();
  req->display_state_flags(buf);
  fprintf(stdout, "After write:\n%.*s", buf.data_len, buf.data);
  return 0;
}