Hi,
I have a slight problem manipulating optional ASN.1 fields. I'm
encoding/decoding a simple DigestInfo structure (by the way, this
corresponds to X509_SIG - I just rebuild my own for the fun ;-)).

First, I populate my DigestInfo structure and encode it. As the
"parameters" field is optional, note I allocate a new ASN1_TYPE object.
Looks like it's the way to do it, to my understanding. So, then, in the
end, when I have encoded the structure and finally free everything, I
take care to call ASN1_TYPE_free.

Then, I decode my DER encoded buffer. Strangely, I get
"OID: (nid=0) - undefined" for the OID !

If, during encoding, I do NOT free the ASN1_TYPE, then I do retrieve my
OID at decoding time !
"OID: (nid=64) - sha1"

I don't understand it, as the DER sequence is the same ! Does somebody
have a hint ?

Thanks
Axelle.

typedef struct {
  ASN1_OBJECT *id;
  ASN1_TYPE *parameters;
} AlgorithmIdentifier;

typedef struct {
  AlgorithmIdentifier *digestAlgorithm;
  ASN1_OCTET_STRING *digest;
} DigestInfo;

ASN1_SEQUENCE(AlgorithmIdentifier) = {
  ASN1_SIMPLE(AlgorithmIdentifier, id, ASN1_OBJECT),
  ASN1_OPT(AlgorithmIdentifier, parameters, ASN1_ANY)
  } ASN1_SEQUENCE_END(AlgorithmIdentifier)
IMPLEMENT_ASN1_FUNCTIONS(AlgorithmIdentifier)

ASN1_SEQUENCE(DigestInfo) = {
  ASN1_SIMPLE(DigestInfo, digestAlgorithm, AlgorithmIdentifier),
  ASN1_SIMPLE(DigestInfo, digest, ASN1_OCTET_STRING)
  } ASN1_SEQUENCE_END(DigestInfo)
IMPLEMENT_ASN1_FUNCTIONS(DigestInfo)

int encode_digestinfo(unsigned char **der) {
  DigestInfo *dinfo = DigestInfo_new();
  unsigned char digest[] = { 0x01,  ... }; // whatever ! (20 bytes long)
  int len;

  dinfo->digestAlgorithm->id = OBJ_nid2obj(NID_sha1);
  dinfo->digestAlgorithm->parameters = ASN1_TYPE_new();
  ASN1_TYPE_set(dinfo->digestAlgorithm->parameters, V_ASN1_NULL, NULL);
  ASN1_OCTET_STRING_set(dinfo->digest, digest, sizeof(digest));

  len = i2d_DigestInfo(dinfo, der);

  ASN1_TYPE_free(dinfo->digestAlgorithm->parameters);
  DigestInfo_free(dinfo);
  return len;
}


void decode_digestinfo(const unsigned char *der, int len) {
  DigestInfo *dinfo;
  int nid;

  // decode
  dinfo = d2i_DigestInfo(NULL, &der, (long)len);

  // retrieve OID
  nid = OBJ_obj2nid(dinfo->digestAlgorithm->id);
  printf("--> OID: (nid=%d) - %s\n", nid, OBJ_nid2ln(nid));

  // retrieve parameters if any
  if (dinfo->digestAlgorithm->parameters) {
    switch(ASN1_TYPE_get(dinfo->digestAlgorithm->parameters)) {
    case V_ASN1_NULL:
      printf("--> NULL parameters\n");
      break;
    }
  }

  // retrieve digest
  printf("--> Digest: \n");
  dump_buffer(dinfo->digest->data, dinfo->digest->length);

  // free
  DigestInfo_free(dinfo);
}

int main(int argc, char **argv) {
  unsigned char *der = NULL;
  int len;

  len = encode_digestinfo(&der);
  printf("DER encoded sequence: \n");
  dump_buffer(der, len);

  printf("Decoding...\n");
  decode_digestinfo(der, len);

  free(der);
  return 1;
}
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to