diff --git a/src/common/dpp.c b/src/common/dpp.c index 9a87c2b73..e4a00aef4 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -2560,7 +2560,7 @@ static int dpp_parse_cred_dot1x(struct dpp_authentication *auth, return -1; } wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Received certBag", conf->certbag); - conf->certs = dpp_pkcs7_certs(conf->certbag); + conf->certs = crypto_pkcs7_get_certificates(conf->certbag); if (!conf->certs) { dpp_auth_fail(auth, "No certificates in certBag"); return -1; diff --git a/src/common/dpp.h b/src/common/dpp.h index e8863c636..a47c685f6 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -631,7 +631,6 @@ void dpp_pfs_free(struct dpp_pfs *pfs); struct wpabuf * dpp_build_csr(struct dpp_authentication *auth, const char *name); -struct wpabuf * dpp_pkcs7_certs(const struct wpabuf *pkcs7); int dpp_validate_csr(struct dpp_authentication *auth, const struct wpabuf *csr); struct dpp_bootstrap_info * dpp_add_qr_code(struct dpp_global *dpp, diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c index d9a959447..b90e4db42 100644 --- a/src/common/dpp_crypto.c +++ b/src/common/dpp_crypto.c @@ -2252,94 +2252,6 @@ fail: } -struct wpabuf * dpp_pkcs7_certs(const struct wpabuf *pkcs7) -{ -#ifdef OPENSSL_IS_BORINGSSL - CBS pkcs7_cbs; -#else /* OPENSSL_IS_BORINGSSL */ - PKCS7 *p7 = NULL; - const unsigned char *p = wpabuf_head(pkcs7); -#endif /* OPENSSL_IS_BORINGSSL */ - STACK_OF(X509) *certs; - int i, num; - BIO *out = NULL; - size_t rlen; - struct wpabuf *pem = NULL; - int res; - -#ifdef OPENSSL_IS_BORINGSSL - certs = sk_X509_new_null(); - if (!certs) - goto fail; - CBS_init(&pkcs7_cbs, wpabuf_head(pkcs7), wpabuf_len(pkcs7)); - if (!PKCS7_get_certificates(certs, &pkcs7_cbs)) { - wpa_printf(MSG_INFO, "DPP: Could not parse PKCS#7 object: %s", - ERR_error_string(ERR_get_error(), NULL)); - goto fail; - } -#else /* OPENSSL_IS_BORINGSSL */ - p7 = d2i_PKCS7(NULL, &p, wpabuf_len(pkcs7)); - if (!p7) { - wpa_printf(MSG_INFO, "DPP: Could not parse PKCS#7 object: %s", - ERR_error_string(ERR_get_error(), NULL)); - goto fail; - } - - switch (OBJ_obj2nid(p7->type)) { - case NID_pkcs7_signed: - certs = p7->d.sign->cert; - break; - case NID_pkcs7_signedAndEnveloped: - certs = p7->d.signed_and_enveloped->cert; - break; - default: - certs = NULL; - break; - } -#endif /* OPENSSL_IS_BORINGSSL */ - - if (!certs || ((num = sk_X509_num(certs)) == 0)) { - wpa_printf(MSG_INFO, - "DPP: No certificates found in PKCS#7 object"); - goto fail; - } - - out = BIO_new(BIO_s_mem()); - if (!out) - goto fail; - - for (i = 0; i < num; i++) { - X509 *cert = sk_X509_value(certs, i); - - PEM_write_bio_X509(out, cert); - } - - rlen = BIO_ctrl_pending(out); - pem = wpabuf_alloc(rlen); - if (!pem) - goto fail; - res = BIO_read(out, wpabuf_put(pem, 0), rlen); - if (res <= 0) { - wpabuf_free(pem); - pem = NULL; - goto fail; - } - wpabuf_put(pem, res); - -fail: -#ifdef OPENSSL_IS_BORINGSSL - if (certs) - sk_X509_pop_free(certs, X509_free); -#else /* OPENSSL_IS_BORINGSSL */ - PKCS7_free(p7); -#endif /* OPENSSL_IS_BORINGSSL */ - if (out) - BIO_free_all(out); - - return pem; -} - - int dpp_validate_csr(struct dpp_authentication *auth, const struct wpabuf *csr) { X509_REQ *req; diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 556e20648..9c18971d8 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -495,6 +495,13 @@ int rc4_skip(const u8 *key, size_t keylen, size_t skip, */ int crypto_get_random(void *buf, size_t len); +/** + * crypto_pkcs7_get_certificates - Extract X.509 certificates from PKCS#7 data + * @pkcs7: DER encoded PKCS#7 data + * Returns: Buffer of the extracted PEM X.509 certificates or %NULL on failure + */ +struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7); + /** * struct crypto_bignum - bignum diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c index 949cf1a5c..73e5c635d 100644 --- a/src/crypto/crypto_openssl.c +++ b/src/crypto/crypto_openssl.c @@ -22,6 +22,7 @@ #ifdef CONFIG_ECC #include #include +#include #endif /* CONFIG_ECC */ #include "common.h" @@ -2805,4 +2806,94 @@ void crypto_ec_key_debug_print(const struct crypto_ec_key *key, BIO_free(out); } + +struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7) +{ +#ifdef OPENSSL_IS_BORINGSSL + CBS pkcs7_cbs; +#else /* OPENSSL_IS_BORINGSSL */ + PKCS7 *p7 = NULL; + const unsigned char *p = wpabuf_head(pkcs7); +#endif /* OPENSSL_IS_BORINGSSL */ + STACK_OF(X509) *certs; + int i, num; + BIO *out = NULL; + size_t rlen; + struct wpabuf *pem = NULL; + int res; + +#ifdef OPENSSL_IS_BORINGSSL + certs = sk_X509_new_null(); + if (!certs) + goto fail; + CBS_init(&pkcs7_cbs, wpabuf_head(pkcs7), wpabuf_len(pkcs7)); + if (!PKCS7_get_certificates(certs, &pkcs7_cbs)) { + wpa_printf(MSG_INFO, + "OpenSSL: Could not parse PKCS#7 object: %s", + ERR_error_string(ERR_get_error(), NULL)); + goto fail; + } +#else /* OPENSSL_IS_BORINGSSL */ + p7 = d2i_PKCS7(NULL, &p, wpabuf_len(pkcs7)); + if (!p7) { + wpa_printf(MSG_INFO, + "OpenSSL: Could not parse PKCS#7 object: %s", + ERR_error_string(ERR_get_error(), NULL)); + goto fail; + } + + switch (OBJ_obj2nid(p7->type)) { + case NID_pkcs7_signed: + certs = p7->d.sign->cert; + break; + case NID_pkcs7_signedAndEnveloped: + certs = p7->d.signed_and_enveloped->cert; + break; + default: + certs = NULL; + break; + } +#endif /* OPENSSL_IS_BORINGSSL */ + + if (!certs || ((num = sk_X509_num(certs)) == 0)) { + wpa_printf(MSG_INFO, + "OpenSSL: No certificates found in PKCS#7 object"); + goto fail; + } + + out = BIO_new(BIO_s_mem()); + if (!out) + goto fail; + + for (i = 0; i < num; i++) { + X509 *cert = sk_X509_value(certs, i); + + PEM_write_bio_X509(out, cert); + } + + rlen = BIO_ctrl_pending(out); + pem = wpabuf_alloc(rlen); + if (!pem) + goto fail; + res = BIO_read(out, wpabuf_put(pem, 0), rlen); + if (res <= 0) { + wpabuf_free(pem); + pem = NULL; + goto fail; + } + wpabuf_put(pem, res); + +fail: +#ifdef OPENSSL_IS_BORINGSSL + if (certs) + sk_X509_pop_free(certs, X509_free); +#else /* OPENSSL_IS_BORINGSSL */ + PKCS7_free(p7); +#endif /* OPENSSL_IS_BORINGSSL */ + if (out) + BIO_free_all(out); + + return pem; +} + #endif /* CONFIG_ECC */