@@ -41,11 +41,15 @@ struct asn1_object serial_number; struct asn1_object signature_algo; struct asn1_object issuer; struct asn1_object validity; struct asn1_object subject; - struct asn1_object signature; + struct asn1_object pubkeyinfo; + struct asn1_object pubkey_algoid; + struct asn1_object pubkey_algo; + struct asn1_object pubkey_algoparm; + struct asn1_object pubkey; }; static int _asn1_x509_read_asn1_object(unsigned char *buf, size_t buflen, va_list *args) { unsigned char small_object_size; unsigned char *buf_p; @@ -67,10 +71,15 @@ buf_p++; buflen--; if (buflen == 0) { return(-1); } + + /* NULL Tag -- no size is required */ + if (outbuf->tag == 0x00) { + return(_asn1_x509_read_asn1_object(buf_p, buflen, args)); + } small_object_size = *buf_p; buf_p++; buflen--; if (buflen == 0) { @@ -132,11 +141,16 @@ read_ret = asn1_x509_read_asn1_object(outbuf->wholething.contents, outbuf->wholething.size, &outbuf->certificate, NULL); if (read_ret != 0) { return(-1); } - read_ret = asn1_x509_read_asn1_object(outbuf->certificate.contents, outbuf->certificate.size, &outbuf->version, &outbuf->serial_number, &outbuf->signature_algo, &outbuf->issuer, &outbuf->validity, &outbuf->subject, NULL); + read_ret = asn1_x509_read_asn1_object(outbuf->certificate.contents, outbuf->certificate.size, &outbuf->version, &outbuf->serial_number, &outbuf->signature_algo, &outbuf->issuer, &outbuf->validity, &outbuf->subject, &outbuf->pubkeyinfo, NULL); + if (read_ret != 0) { + return(-1); + } + + read_ret = asn1_x509_read_asn1_object(outbuf->pubkeyinfo.contents, outbuf->pubkeyinfo.size, &outbuf->pubkey_algoid, &outbuf->pubkey, NULL); if (read_ret != 0) { return(-1); } return(0); @@ -187,10 +201,34 @@ *outbuf = x509.serial_number.asn1rep; } return(x509.serial_number.asn1rep_len); } + +ssize_t x509_to_keysize(void *x509_der_buf, size_t x509_der_buf_len) { + struct asn1_object null, pubkey, modulus, exponent; + struct x509_object x509; + int read_ret; + + read_ret = asn1_x509_read_object(x509_der_buf, x509_der_buf_len, &x509); + if (read_ret != 0) { + return(-1); + } + + /* The structure of "pubkey" is specified in PKCS #1 */ + read_ret = asn1_x509_read_asn1_object(x509.pubkey.contents, x509.pubkey.size, &null, &pubkey, NULL); + if (read_ret != 0) { + return(-1); + } + + read_ret = asn1_x509_read_asn1_object(pubkey.contents, pubkey.size, &modulus, &exponent, NULL); + if (read_ret != 0) { + return(-1); + } + + return(modulus.size - 1); +} /* * http://www.blackberry.com/developers/docs/4.6.0api/javax/microedition/pki/Certificate.html */ static const char *_x509_objectid_to_label_string(void *buf, size_t buflen) {