diff --git a/lib/hx509/cert.c b/lib/hx509/cert.c index 06e6c8a71..223ff655c 100644 --- a/lib/hx509/cert.c +++ b/lib/hx509/cert.c @@ -233,6 +233,32 @@ hx509_cert_init(hx509_context context, const Certificate *c, hx509_cert *cert) return ret; } +int +hx509_cert_init_data(hx509_context context, + const void *ptr, + size_t len, + hx509_cert *cert) +{ + Certificate t; + size_t size; + int ret; + + ret = decode_Certificate(ptr, len, &t, &size); + if (ret) { + hx509_set_error_string(context, 0, ret, "Failed to decode certificate"); + return ret; + } + if (size != len) { + hx509_set_error_string(context, 0, HX509_EXTRA_DATA_AFTER_STRUCTURE, + "Extra data after certificate"); + return HX509_EXTRA_DATA_AFTER_STRUCTURE; + } + + ret = hx509_cert_init(context, &t, cert); + free_Certificate(&t); + return ret; +} + void _hx509_cert_set_release(hx509_cert cert, _hx509_cert_release_func release, diff --git a/lib/hx509/cms.c b/lib/hx509/cms.c index 6d8319fb9..c17fcee77 100644 --- a/lib/hx509/cms.c +++ b/lib/hx509/cms.c @@ -585,22 +585,12 @@ any_to_certs(hx509_context context, const SignedData *sd, hx509_certs certs) return 0; for (i = 0; i < sd->certificates->len; i++) { - Certificate cert; hx509_cert c; - const void *p = sd->certificates->val[i].data; - size_t size, length = sd->certificates->val[i].length; - - ret = decode_Certificate(p, length, &cert, &size); - if (ret) { - hx509_set_error_string(context, 0, ret, - "Failed to decode certificate %d " - "in SignedData.certificates", i); - return ret; - } - - ret = hx509_cert_init(context, &cert, &c); - free_Certificate(&cert); + ret = hx509_cert_init_data(context, + sd->certificates->val[i].data, + sd->certificates->val[i].length, + &c); if (ret) return ret; ret = hx509_certs_add(context, certs, c); diff --git a/lib/hx509/ks_file.c b/lib/hx509/ks_file.c index 7eeab5e3b..24304fed0 100644 --- a/lib/hx509/ks_file.c +++ b/lib/hx509/ks_file.c @@ -105,20 +105,9 @@ parse_certificate(hx509_context context, const char *fn, const void *data, size_t len) { hx509_cert cert; - Certificate t; - size_t size; int ret; - ret = decode_Certificate(data, len, &t, &size); - if (ret) { - hx509_set_error_string(context, 0, ret, - "Failed to parse certificate in %s", - fn); - return ret; - } - - ret = hx509_cert_init(context, &t, &cert); - free_Certificate(&t); + ret = hx509_cert_init_data(context, data, len, &cert); if (ret) return ret; diff --git a/lib/hx509/ks_keychain.c b/lib/hx509/ks_keychain.c index 155ecc9e6..7036b4d6d 100644 --- a/lib/hx509/ks_keychain.c +++ b/lib/hx509/ks_keychain.c @@ -347,25 +347,19 @@ keychain_iter_start(hx509_context context, return ENOMEM; } for (i = 0; i < CFArrayGetCount(anchors); i++) { - Certificate t; + SecCertificateRef cr; hx509_cert cert; - - SecCertificateRef cr = - (SecCertificateRef)CFArrayGetValueAtIndex(anchors, i); CSSM_DATA cssm; + cr = (SecCertificateRef)CFArrayGetValueAtIndex(anchors, i); + SecCertificateGetData(cr, &cssm); - ret = decode_Certificate(cssm.Data, cssm.Length, &t, NULL); - if (ret) - continue; - - ret = hx509_cert_init(context, &t, &cert); + ret = hx509_cert_init_data(context, cssm.Data, cssm.Length, &cert); if (ret) continue; ret = hx509_certs_add(context, iter->certs, cert); - free_Certificate(&t); hx509_cert_free(cert); } CFRelease(anchors); @@ -412,11 +406,9 @@ keychain_iter(hx509_context context, SecKeychainItemRef itemRef; SecItemAttr item; struct iter *iter = cursor; - Certificate t; OSStatus ret; UInt32 len; void *ptr = NULL; - size_t size; if (iter->certs) return hx509_certs_next_cert(context, iter->certs, iter->cursor, cert); @@ -444,15 +436,7 @@ keychain_iter(hx509_context context, if (ret) return EINVAL; - ret = decode_Certificate(ptr, len, &t, &size); - CFRelease(itemRef); - if (ret) { - hx509_set_error_string(context, 0, ret, "Failed to parse certificate"); - goto out; - } - - ret = hx509_cert_init(context, &t, cert); - free_Certificate(&t); + ret = hx509_cert_init_data(context, ptr, len, cert); if (ret) goto out; diff --git a/lib/hx509/ks_p11.c b/lib/hx509/ks_p11.c index cafbd2bdc..19cdb3190 100644 --- a/lib/hx509/ks_p11.c +++ b/lib/hx509/ks_p11.c @@ -682,7 +682,6 @@ collect_cert(hx509_context context, { struct hx509_collector *collector = ptr; hx509_cert cert; - Certificate t; int ret; if ((CK_LONG)query[0].ulValueLen == -1 || @@ -691,16 +690,8 @@ collect_cert(hx509_context context, return 0; } - - ret = decode_Certificate(query[1].pValue, query[1].ulValueLen, - &t, NULL); - if (ret) { - hx509_clear_error_string(context); - return 0; - } - - ret = hx509_cert_init(context, &t, &cert); - free_Certificate(&t); + ret = hx509_cert_init_data(context, query[1].pValue, + query[1].ulValueLen, &cert); if (ret) return ret; diff --git a/lib/hx509/ks_p12.c b/lib/hx509/ks_p12.c index 5728cbc4b..bdb99e059 100644 --- a/lib/hx509/ks_p12.c +++ b/lib/hx509/ks_p12.c @@ -132,7 +132,6 @@ certBag_parser(hx509_context context, const PKCS12_Attributes *attrs) { heim_octet_string os; - Certificate t; hx509_cert cert; PKCS12_CertBag cb; int ret; @@ -154,16 +153,11 @@ certBag_parser(hx509_context context, if (ret) return ret; - ret = decode_Certificate(os.data, os.length, &t, NULL); + ret = hx509_cert_init_data(context, os.data, os.length, &cert); der_free_octet_string(&os); if (ret) return ret; - ret = hx509_cert_init(context, &t, &cert); - free_Certificate(&t); - if (ret) - return ret; - ret = _hx509_collector_certs_add(context, c, cert); if (ret) { hx509_cert_free(cert);