From: "(4401 440) Cedric Izoard (France)" <cedric.izoard@xxxxxxxxxxxx> As BoringSSL version of i2d_PUBKEY doesn't respect the POINT_CONVERSION_COMPRESSED flag redefine specific crypto_ec_key_get_subject_public_key version for BoringSSL (based on dpp_bootstrap_key_der) The only other "user" of crypto_ec_key_get_subject_public_key is SAE PK for which Public Key should also be formatted using compressed format. Signed-off-by: Cedric Izoard <cedric.izoard@xxxxxxxxxxxx> --- src/common/dpp.c | 2 - src/common/dpp_crypto.c | 89 +----------------------------------- src/crypto/crypto_openssl.c | 91 ++++++++++++++++++++++++++++++++++++- tests/hwsim/test_dpp.py | 2 +- 4 files changed, 93 insertions(+), 91 deletions(-) diff --git a/src/common/dpp.c b/src/common/dpp.c index 63189c169..1fd074f05 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -8,8 +8,6 @@ */ #include "utils/includes.h" -#include <openssl/evp.h> -#include <openssl/x509.h> #include "utils/common.h" #include "utils/base64.h" diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c index 77782b9e2..964a27ef9 100644 --- a/src/common/dpp_crypto.c +++ b/src/common/dpp_crypto.c @@ -8,10 +8,6 @@ */ #include "utils/includes.h" -#include <openssl/err.h> -#include <openssl/asn1.h> -#include <openssl/asn1t.h> -#include <openssl/pem.h> #include "utils/common.h" #include "utils/base64.h" @@ -295,93 +291,12 @@ struct crypto_ec_key * dpp_set_keypair(const struct dpp_curve_params **curve, } -typedef struct { - /* AlgorithmIdentifier ecPublicKey with optional parameters present - * as an OID identifying the curve */ - X509_ALGOR *alg; - /* Compressed format public key per ANSI X9.63 */ - ASN1_BIT_STRING *pub_key; -} DPP_BOOTSTRAPPING_KEY; - -ASN1_SEQUENCE(DPP_BOOTSTRAPPING_KEY) = { - ASN1_SIMPLE(DPP_BOOTSTRAPPING_KEY, alg, X509_ALGOR), - ASN1_SIMPLE(DPP_BOOTSTRAPPING_KEY, pub_key, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END(DPP_BOOTSTRAPPING_KEY); - -IMPLEMENT_ASN1_FUNCTIONS(DPP_BOOTSTRAPPING_KEY); - - -static struct wpabuf * dpp_bootstrap_key_der(struct crypto_ec_key *key) -{ - unsigned char *der = NULL; - int der_len; - const EC_KEY *eckey; - struct wpabuf *ret = NULL; - size_t len; - const EC_GROUP *group; - const EC_POINT *point; - BN_CTX *ctx; - DPP_BOOTSTRAPPING_KEY *bootstrap = NULL; - int nid; - - ctx = BN_CTX_new(); - eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key); - if (!ctx || !eckey) - goto fail; - - group = EC_KEY_get0_group(eckey); - point = EC_KEY_get0_public_key(eckey); - if (!group || !point) - goto fail; - nid = EC_GROUP_get_curve_name(group); - - bootstrap = DPP_BOOTSTRAPPING_KEY_new(); - if (!bootstrap || - X509_ALGOR_set0(bootstrap->alg, OBJ_nid2obj(EVP_PKEY_EC), - V_ASN1_OBJECT, (void *) OBJ_nid2obj(nid)) != 1) - goto fail; - - len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, - NULL, 0, ctx); - if (len == 0) - goto fail; - - der = OPENSSL_malloc(len); - if (!der) - goto fail; - len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, - der, len, ctx); - - OPENSSL_free(bootstrap->pub_key->data); - bootstrap->pub_key->data = der; - der = NULL; - bootstrap->pub_key->length = len; - /* No unused bits */ - bootstrap->pub_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - bootstrap->pub_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; - - der_len = i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der); - if (der_len <= 0) { - wpa_printf(MSG_ERROR, - "DDP: Failed to build DER encoded public key"); - goto fail; - } - - ret = wpabuf_alloc_copy(der, der_len); -fail: - DPP_BOOTSTRAPPING_KEY_free(bootstrap); - OPENSSL_free(der); - BN_CTX_free(ctx); - return ret; -} - - int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi) { struct wpabuf *der; int res; - der = dpp_bootstrap_key_der(bi->pubkey); + der = crypto_ec_key_get_subject_public_key(bi->pubkey); if (!der) return -1; wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)", @@ -416,7 +331,7 @@ int dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve, goto fail; bi->own = 1; - der = dpp_bootstrap_key_der(bi->pubkey); + der = crypto_ec_key_get_subject_public_key(bi->pubkey); if (!der) goto fail; wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)", diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c index 4cd99978b..30ea36d75 100644 --- a/src/crypto/crypto_openssl.c +++ b/src/crypto/crypto_openssl.c @@ -2502,13 +2502,102 @@ void crypto_ec_key_deinit(struct crypto_ec_key *key) EVP_PKEY_free((EVP_PKEY *) key); } +#ifdef OPENSSL_IS_BORINGSSL +/* BoringSSL version of i2d_PUBKEY always output public EC key using + * uncompressed form so define, as such define a custom function to + * export EC pubkey using compressed format */ +#include <openssl/asn1.h> +#include <openssl/asn1t.h> +typedef struct { + /* AlgorithmIdentifier ecPublicKey with optional parameters present + * as an OID identifying the curve */ + X509_ALGOR *alg; + /* Compressed format public key per ANSI X9.63 */ + ASN1_BIT_STRING *pub_key; +} EC_COMP_PUBKEY; + +ASN1_SEQUENCE(EC_COMP_PUBKEY) = { + ASN1_SIMPLE(EC_COMP_PUBKEY, alg, X509_ALGOR), + ASN1_SIMPLE(EC_COMP_PUBKEY, pub_key, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(EC_COMP_PUBKEY); + +IMPLEMENT_ASN1_FUNCTIONS(EC_COMP_PUBKEY); +struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) +{ + unsigned char *der = NULL; + int der_len; + const EC_KEY *eckey; + struct wpabuf *ret = NULL; + size_t len; + const EC_GROUP *group; + const EC_POINT *point; + BN_CTX *ctx; + EC_COMP_PUBKEY *pubkey = NULL; + int nid; + + ctx = BN_CTX_new(); + eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)key); + if (!ctx || !eckey) + goto fail; + + group = EC_KEY_get0_group(eckey); + point = EC_KEY_get0_public_key(eckey); + if (!group || !point) + goto fail; + nid = EC_GROUP_get_curve_name(group); + + pubkey = EC_COMP_PUBKEY_new(); + if (!pubkey || + X509_ALGOR_set0(pubkey->alg, OBJ_nid2obj(EVP_PKEY_EC), + V_ASN1_OBJECT, (void *) OBJ_nid2obj(nid)) != 1) + goto fail; + + len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, + NULL, 0, ctx); + if (len == 0) + goto fail; + + der = OPENSSL_malloc(len); + if (!der) + goto fail; + len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, + der, len, ctx); + + OPENSSL_free(pubkey->pub_key->data); + pubkey->pub_key->data = der; + der = NULL; + pubkey->pub_key->length = len; + /* No unused bits */ + pubkey->pub_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pubkey->pub_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; + + der_len = i2d_EC_COMP_PUBKEY(pubkey, &der); + if (der_len <= 0) { + wpa_printf(MSG_ERROR, + "DDP: Failed to build DER encoded public key"); + goto fail; + } + + ret = wpabuf_alloc_copy(der, der_len); +fail: + EC_COMP_PUBKEY_free(pubkey); + OPENSSL_free(der); + BN_CTX_free(ctx); + return ret; +} + +#else struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) { unsigned char *der = NULL; int der_len; struct wpabuf *buf; + /* For now, all users expect COMPRESSED form */ + EC_KEY_set_conv_form(EVP_PKEY_get0_EC_KEY((EVP_PKEY *)key), + POINT_CONVERSION_COMPRESSED); + der_len = i2d_PUBKEY((EVP_PKEY *) key, &der); if (der_len <= 0) { wpa_printf(MSG_INFO, "OpenSSL: i2d_PUBKEY() failed: %s", @@ -2520,7 +2609,7 @@ struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) OPENSSL_free(der); return buf; } - +#endif /* OPENSSL_IS_BORINGSSL */ struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, bool include_pub) diff --git a/tests/hwsim/test_dpp.py b/tests/hwsim/test_dpp.py index 558f882cd..efcdb318c 100644 --- a/tests/hwsim/test_dpp.py +++ b/tests/hwsim/test_dpp.py @@ -214,7 +214,7 @@ def test_dpp_qr_code_keygen_fail(dev, apdev): """DPP QR Code and keygen failure""" check_dpp_capab(dev[0]) - with alloc_fail(dev[0], 1, "dpp_bootstrap_key_der;dpp_keygen"): + with alloc_fail(dev[0], 1, "crypto_ec_key_get_subject_public_key;dpp_keygen"): if "FAIL" not in dev[0].request("DPP_BOOTSTRAP_GEN type=qrcode"): raise Exception("Failure not reported") -- 2.25.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap