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 [email protected]
Automated List Manager [EMAIL PROTECTED]