diff --git a/configure.ac b/configure.ac index c2033bedd..9d34e6a18 100644 --- a/configure.ac +++ b/configure.ac @@ -1411,7 +1411,7 @@ AC_ARG_ENABLE([certgen], [ ENABLED_CERTGEN=$enableval ], [ ENABLED_CERTGEN=no ] ) -if test "$ENABLED_OPENVPN" = "yes" +if test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_OPENSSH" = "yes" then ENABLED_CERTGEN=yes fi diff --git a/src/ssl.c b/src/ssl.c index 0c877201c..bb01685b6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -100,6 +100,7 @@ #include #include #include + #include #include #include #include @@ -7614,6 +7615,40 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out, return pkey; } +/* helper function to get raw pointer to DER buffer from WOLFSSL_EVP_PKEY */ +static int wolfSSL_EVP_PKEY_get_der(const WOLFSSL_EVP_PKEY* key, unsigned char** der) +{ + unsigned char* pt; + int sz; + + if (!key || !key->pkey_sz) + return WOLFSSL_FATAL_ERROR; + + sz = key->pkey_sz; + if (der) { + pt = (unsigned char*)key->pkey.ptr; + if (*der) { + /* since this function signature has no size value passed in it is + * assumed that the user has allocated a large enough buffer */ + XMEMCPY(*der, pt, sz); + *der += sz; + } + else { + *der = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL); + if (*der == NULL) { + return WOLFSSL_FATAL_ERROR; + } + XMEMCPY(*der, pt, sz); + } + } + return sz; +} + +int wolfSSL_i2d_PUBKEY(const WOLFSSL_EVP_PKEY *key, unsigned char **der) +{ + return wolfSSL_EVP_PKEY_get_der(key, der); +} + /* Reads in a DER format key. If PKCS8 headers are found they are stripped off. * @@ -22488,39 +22523,15 @@ int wolfSSL_i2d_PKCS12_bio(WOLFSSL_BIO *bio, WC_PKCS12 *pkcs12) return ret; } -/* helper function to get raw pointer to DER buffer from WOLFSSL_EVP_PKEY */ -static int wolfSSL_EVP_PKEY_get_der(WOLFSSL_EVP_PKEY* key, unsigned char** der) -{ - if (!key) - return WOLFSSL_FAILURE; - if (der) - *der = (unsigned char*)key->pkey.ptr; - return key->pkey_sz; -} - /* Copies unencrypted DER key buffer into "der". If "der" is null then the size - * of buffer needed is returned + * of buffer needed is returned. If *der == NULL then it allocates a buffer. * NOTE: This also advances the "der" pointer to be at the end of buffer. * * Returns size of key buffer on success */ -int wolfSSL_i2d_PrivateKey(WOLFSSL_EVP_PKEY* key, unsigned char** der) +int wolfSSL_i2d_PrivateKey(const WOLFSSL_EVP_PKEY* key, unsigned char** der) { - if (key == NULL) { - return WOLFSSL_FATAL_ERROR; - } - - if (key->pkey_sz <= 0 || !key->pkey.ptr) { - return WOLFSSL_FATAL_ERROR; - } - - if (der != NULL) { - /* since this function signature has no size value passed in it is - * assumed that the user has allocated a large enough buffer */ - XMEMCPY(*der, key->pkey.ptr, key->pkey_sz); - *der += key->pkey_sz; - } - return key->pkey_sz; + return wolfSSL_EVP_PKEY_get_der(key, der); } /* Creates a new WC_PKCS12 structure @@ -22546,13 +22557,11 @@ WC_PKCS12* wolfSSL_PKCS12_create(char* pass, char* name, WC_PKCS12* pkcs12; WC_DerCertList* list = NULL; word32 passSz; - byte* keyDer; + byte* keyDer = NULL; word32 keyDerSz; byte* certDer; int certDerSz; - int ret; - WOLFSSL_ENTER("wolfSSL_PKCS12_create()"); if (pass == NULL || pkey == NULL || cert == NULL) { @@ -22561,11 +22570,8 @@ WC_PKCS12* wolfSSL_PKCS12_create(char* pass, char* name, } passSz = (word32)XSTRLEN(pass); - if ((ret = wolfSSL_EVP_PKEY_get_der(pkey, &keyDer)) < 0) { - WOLFSSL_LEAVE("wolfSSL_PKCS12_create", ret); - return NULL; - } - keyDerSz = ret; + keyDer = (byte*)pkey->pkey.ptr; + keyDerSz = pkey->pkey_sz; certDer = (byte*)wolfSSL_X509_get_der(cert, &certDerSz); if (certDer == NULL) { @@ -25574,9 +25580,9 @@ int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg, if (ppkalg) *ppkalg = pub->algor->algorithm; if (pk) - wolfSSL_EVP_PKEY_get_der(pub->pkey, (unsigned char **)pk); + *pk = (unsigned char*)pub->pkey->pkey.ptr; if (ppklen) - *ppklen = wolfSSL_EVP_PKEY_get_der(pub->pkey, NULL); + *ppklen = pub->pkey->pkey_sz; return WOLFSSL_SUCCESS; } @@ -31367,7 +31373,8 @@ void *wolfSSL_OPENSSL_malloc(size_t a) #if defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_PEM_TO_DER) static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, - unsigned char* passwd, int passwdSz, byte **cipherInfo) + unsigned char* passwd, int passwdSz, byte **cipherInfo, + int maxDerSz) { int ret, paddingSz; word32 idx, cipherInfoSz; @@ -31420,6 +31427,13 @@ static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, paddingSz = ((*derSz)/info->ivSz + 1) * info->ivSz - (*derSz); if (paddingSz == 0) paddingSz = info->ivSz; + if (maxDerSz < *derSz + paddingSz) { + WOLFSSL_MSG("not enough DER buffer allocated"); +#ifdef WOLFSSL_SMALL_STACK + XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); +#endif + return WOLFSSL_FAILURE; + } XMEMSET(der+(*derSz), (byte)paddingSz, paddingSz); (*derSz) += paddingSz; @@ -31865,9 +31879,20 @@ int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, /* encrypt DER buffer if required */ if (passwd != NULL && passwdSz > 0 && cipher != NULL) { int ret; + int blockSz = wolfSSL_EVP_CIPHER_block_size(cipher); + byte *tmpBuf; + + /* Add space for padding */ + if (!(tmpBuf = XREALLOC(derBuf, derSz + blockSz, NULL, + DYNAMIC_TYPE_TMP_BUFFER))) { + WOLFSSL_MSG("Extending DER buffer failed"); + XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); + return WOLFSSL_FAILURE; + } + derBuf = tmpBuf; ret = EncryptDerKey(derBuf, &derSz, cipher, - passwd, passwdSz, &cipherInfo); + passwd, passwdSz, &cipherInfo, derSz + blockSz); if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("EncryptDerKey failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); @@ -32096,7 +32121,7 @@ int SetECKeyExternal(WOLFSSL_EC_KEY* eckey) /* set group (OID, nid and idx) */ eckey->group->curve_oid = ecc_sets[key->idx].oidSum; - eckey->group->curve_nid = ecc_sets[key->idx].id; + eckey->group->curve_nid = EccEnumToNID(ecc_sets[key->idx].id); eckey->group->curve_idx = key->idx; if (eckey->pub_key->internal != NULL) { @@ -32264,15 +32289,10 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid) { WOLFSSL_EC_KEY *key; int x; - int eccEnum; + int eccEnum = NIDToEccEnum(nid); WOLFSSL_ENTER("wolfSSL_EC_KEY_new_by_curve_name"); - /* If NID passed in is OpenSSL type, convert it to ecc_curve_id enum */ - eccEnum = NIDToEccEnum(nid); - if (eccEnum == -1) - eccEnum = nid; - key = wolfSSL_EC_KEY_new(); if (key == NULL) { WOLFSSL_MSG("wolfSSL_EC_KEY_new failure"); @@ -32280,15 +32300,17 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid) } /* set the nid of the curve */ - key->group->curve_nid = eccEnum; + key->group->curve_nid = nid; - /* search and set the corresponding internal curve idx */ - for (x = 0; ecc_sets[x].size != 0; x++) - if (ecc_sets[x].id == key->group->curve_nid) { - key->group->curve_idx = x; - key->group->curve_oid = ecc_sets[x].oidSum; - break; - } + if (eccEnum != -1) { + /* search and set the corresponding internal curve idx */ + for (x = 0; ecc_sets[x].size != 0; x++) + if (ecc_sets[x].id == eccEnum) { + key->group->curve_idx = x; + key->group->curve_oid = ecc_sets[x].oidSum; + break; + } + } return key; } @@ -32485,6 +32507,7 @@ int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group) int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key) { int initTmpRng = 0; + int eccEnum; WC_RNG* rng = NULL; #ifdef WOLFSSL_SMALL_STACK WC_RNG* tmpRNG = NULL; @@ -32526,8 +32549,11 @@ int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key) return 0; } - if (wc_ecc_make_key_ex(rng, 0, (ecc_key*)key->internal, - key->group->curve_nid) != MP_OKAY) { + /* NIDToEccEnum returns -1 for invalid NID so if key->group->curve_nid + * is 0 then pass ECC_CURVE_DEF as arg */ + eccEnum = key->group->curve_nid ? + NIDToEccEnum(key->group->curve_nid) : ECC_CURVE_DEF; + if (wc_ecc_make_key_ex(rng, 0, (ecc_key*)key->internal, eccEnum) != MP_OKAY) { WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed"); #ifdef WOLFSSL_SMALL_STACK XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); @@ -32838,6 +32864,13 @@ int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b, return 1; } +WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_dup(const WOLFSSL_EC_GROUP *src) +{ + if (!src) + return NULL; + return wolfSSL_EC_GROUP_new_by_curve_name(src->curve_nid); +} + #endif /* HAVE_ECC */ #endif /* OPENSSL_EXTRA */ @@ -32888,9 +32921,6 @@ WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid) /* If NID passed in is OpenSSL type, convert it to ecc_curve_id enum */ eccEnum = NIDToEccEnum(nid); - if (eccEnum == -1) - eccEnum = nid; - /* curve group */ g = (WOLFSSL_EC_GROUP*) XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL, @@ -32902,12 +32932,12 @@ WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid) XMEMSET(g, 0, sizeof(WOLFSSL_EC_GROUP)); /* set the nid of the curve */ - g->curve_nid = eccEnum; + g->curve_nid = nid; - if (eccEnum > ECC_CURVE_DEF) { + if (eccEnum != -1) { /* search and set the corresponding internal curve idx */ for (x = 0; ecc_sets[x].size != 0; x++) - if (ecc_sets[x].id == g->curve_nid) { + if (ecc_sets[x].id == eccEnum) { g->curve_idx = x; g->curve_oid = ecc_sets[x].oidSum; break; @@ -33287,10 +33317,14 @@ int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out) return WOLFSSL_FAILURE; } +#ifdef HAVE_COMP_KEY /* Default to compressed form if not set */ form = in->form == POINT_CONVERSION_UNCOMPRESSED ? POINT_CONVERSION_UNCOMPRESSED: POINT_CONVERSION_COMPRESSED; +#else + form = POINT_CONVERSION_UNCOMPRESSED; +#endif len = wolfSSL_EC_POINT_point2oct(in->group, in->pub_key, form, NULL, 0, NULL); @@ -33323,11 +33357,104 @@ int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out) return (int)len; } +#ifdef HAVE_ECC_KEY_IMPORT +WOLFSSL_EC_KEY *wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY **key, const unsigned char **in, + long len) +{ + WOLFSSL_EC_KEY *eckey = NULL; + WOLFSSL_ENTER("wolfSSL_d2i_ECPrivateKey"); + + if (!in || !*in || len <= 0) { + WOLFSSL_MSG("wolfSSL_d2i_ECPrivateKey Bad arguments"); + return NULL; + } + + if (!(eckey = wolfSSL_EC_KEY_new())) { + WOLFSSL_MSG("wolfSSL_EC_KEY_new error"); + return NULL; + } + + if (wc_ecc_import_private_key(*in, (word32)len, NULL, 0, + (ecc_key*)eckey->internal) != MP_OKAY) { + WOLFSSL_MSG("wc_ecc_import_private_key error"); + goto error; + } + + eckey->inSet = 1; + + if (SetECKeyExternal(eckey) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECKeyExternal error"); + goto error; + } + + if (key) { + *key = eckey; + } + + return eckey; + +error: + wolfSSL_EC_KEY_free(eckey); + return NULL; +} +#endif /* HAVE_ECC_KEY_IMPORT */ + +int wolfSSL_i2d_ECPrivateKey(const WOLFSSL_EC_KEY *in, unsigned char **out) +{ + int len; + byte* buf = NULL; + WOLFSSL_ENTER("wolfSSL_i2d_ECPrivateKey"); + + if (!in) { + WOLFSSL_MSG("wolfSSL_i2d_ECPrivateKey Bad arguments"); + return WOLFSSL_FAILURE; + } + + if (!in->inSet && SetECKeyInternal((WOLFSSL_EC_KEY*)in) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECKeyInternal error"); + return WOLFSSL_FAILURE; + } + + if ((len = wc_ecc_size((ecc_key*)in->internal)) <= 0) { + WOLFSSL_MSG("wc_ecc_size error"); + return WOLFSSL_FAILURE; + } + + if (out) { + if (!(buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { + WOLFSSL_MSG("tmp buffer malloc error"); + return WOLFSSL_FAILURE; + } + + if (wc_ecc_export_private_only((ecc_key*)in->internal, buf, + (word32*)&len) != MP_OKAY) { + WOLFSSL_MSG("wc_ecc_export_private_only error"); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFSSL_FAILURE; + } + + if (*out) { + XMEMCPY(*out, buf, len); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + else { + *out = buf; + } + } + + return len; +} + void wolfSSL_EC_KEY_set_conv_form(WOLFSSL_EC_KEY *eckey, char form) { - if (eckey && (form == POINT_CONVERSION_COMPRESSED || - form == POINT_CONVERSION_UNCOMPRESSED)) { + if (eckey && (form == POINT_CONVERSION_UNCOMPRESSED +#ifdef HAVE_COMP_KEY + || form == POINT_CONVERSION_COMPRESSED +#endif + )) { eckey->form = form; + } else { + WOLFSSL_MSG("Incorrect form or HAVE_COMP_KEY not compiled in"); } } @@ -33369,6 +33496,29 @@ WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group, } #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ +#ifdef USE_ECC_B_PARAM +int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *point, + WOLFSSL_BN_CTX *ctx) +{ + (void)ctx; + WOLFSSL_ENTER("wolfSSL_EC_POINT_is_on_curve"); + + if (!group || !point) { + WOLFSSL_MSG("Invalid arguments"); + return WOLFSSL_FAILURE; + } + + if (!point->inSet && SetECPointInternal((WOLFSSL_EC_POINT*)point)) { + WOLFSSL_MSG("SetECPointInternal error"); + return WOLFSSL_FAILURE; + } + + return wc_ecc_point_is_on_curve((ecc_point*)point->internal, group->curve_idx) + == MP_OKAY ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} +#endif /* USE_ECC_B_PARAM */ + WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group) { WOLFSSL_EC_POINT *p; @@ -33502,6 +33652,112 @@ int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ !defined(HAVE_SELFTEST) #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) +int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, + const WOLFSSL_EC_POINT *p1, + const WOLFSSL_EC_POINT *p2, WOLFSSL_BN_CTX *ctx) +{ + mp_int a, prime, mu; + mp_digit mp = 0; + ecc_point* montP1 = NULL; + ecc_point* montP2 = NULL; + ecc_point* eccP1; + ecc_point* eccP2; + int ret = WOLFSSL_FAILURE; + + (void)ctx; + + if (!group || !r || !p1 || !p2) { + WOLFSSL_MSG("wolfSSL_EC_POINT_add error"); + return WOLFSSL_FAILURE; + } + + if (setupPoint(r) != WOLFSSL_SUCCESS || + setupPoint(p1) != WOLFSSL_SUCCESS || + setupPoint(p2) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("setupPoint error"); + return WOLFSSL_FAILURE; + } + + /* read the curve prime and a */ + if (mp_init_multi(&prime, &a, &mu, NULL, NULL, NULL) != MP_OKAY) { + WOLFSSL_MSG("mp_init_multi error"); + goto cleanup; + } + + if (mp_read_radix(&a, ecc_sets[group->curve_idx].Af, MP_RADIX_HEX) + != MP_OKAY) { + WOLFSSL_MSG("mp_read_radix a error"); + goto cleanup; + } + + if (mp_read_radix(&prime, ecc_sets[group->curve_idx].prime, MP_RADIX_HEX) + != MP_OKAY) { + WOLFSSL_MSG("mp_read_radix prime error"); + goto cleanup; + } + + if (mp_montgomery_setup(&prime, &mp) != MP_OKAY) { + WOLFSSL_MSG("mp_montgomery_setup nqm error"); + goto cleanup; + } + + eccP1 = (ecc_point*)p1->internal; + eccP2 = (ecc_point*)p2->internal; + + if (!(montP1 = wc_ecc_new_point_h(NULL)) || + !(montP2 = wc_ecc_new_point_h(NULL))) { + WOLFSSL_MSG("wc_ecc_new_point_h nqm error"); + goto cleanup; + } + + if ((mp_montgomery_calc_normalization(&mu, &prime)) != MP_OKAY) { + WOLFSSL_MSG("mp_montgomery_calc_normalization error"); + goto cleanup; + } + + /* Convert to Montgomery form */ + if (mp_cmp_d(&mu, 1) == MP_EQ) { + if (wc_ecc_copy_point(eccP1, montP1) != MP_OKAY || + wc_ecc_copy_point(eccP2, montP2) != MP_OKAY) { + WOLFSSL_MSG("wc_ecc_copy_point error"); + goto cleanup; + } + } else { + if (mp_mulmod(eccP1->x, &mu, &prime, montP1->x) != MP_OKAY || + mp_mulmod(eccP1->y, &mu, &prime, montP1->y) != MP_OKAY || + mp_mulmod(eccP1->z, &mu, &prime, montP1->z) != MP_OKAY) { + WOLFSSL_MSG("mp_mulmod error"); + goto cleanup; + } + if (mp_mulmod(eccP2->x, &mu, &prime, montP2->x) != MP_OKAY || + mp_mulmod(eccP2->y, &mu, &prime, montP2->y) != MP_OKAY || + mp_mulmod(eccP2->z, &mu, &prime, montP2->z) != MP_OKAY) { + WOLFSSL_MSG("mp_mulmod error"); + goto cleanup; + } + } + + if (ecc_projective_add_point(montP1, montP2, (ecc_point*)r->internal, + &a, &prime, mp) != MP_OKAY) { + WOLFSSL_MSG("ecc_projective_add_point error"); + goto cleanup; + } + + if (ecc_map((ecc_point*)r->internal, &prime, mp) != MP_OKAY) { + WOLFSSL_MSG("ecc_map error"); + goto cleanup; + } + + ret = WOLFSSL_SUCCESS; +cleanup: + mp_clear(&a); + mp_clear(&prime); + mp_clear(&mu); + wc_ecc_del_point_h(montP1, NULL); + wc_ecc_del_point_h(montP2, NULL); + return ret; +} + /* Calculate the value: generator * n + q * m * return code compliant with OpenSSL : * 1 if success, 0 if error @@ -33582,14 +33838,14 @@ int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, goto cleanup; } /* r = generator * n */ - if (wc_ecc_mulmod((mp_int*)n->internal, result, result, &a, &prime, 1) + if (wc_ecc_mulmod((mp_int*)n->internal, result, result, &a, &prime, 0) != MP_OKAY) { WOLFSSL_MSG("wc_ecc_mulmod nqm error"); goto cleanup; } /* tmp = q * m */ if (wc_ecc_mulmod((mp_int*)m->internal, (ecc_point*)q->internal, - tmp, &a, &prime, 1) != MP_OKAY) { + tmp, &a, &prime, 0) != MP_OKAY) { WOLFSSL_MSG("wc_ecc_mulmod nqm error"); goto cleanup; } @@ -33645,6 +33901,42 @@ cleanup: #endif /* !defined(WOLFSSL_ATECC508A) && defined(ECC_SHAMIR) && * !defined(HAVE_SELFTEST) */ +/* (x, y) -> (x, -y) */ +int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *a, + WOLFSSL_BN_CTX *ctx) +{ + ecc_point* p; + mp_int prime; + + (void)ctx; + + WOLFSSL_ENTER("wolfSSL_EC_POINT_invert"); + + if (!group || !a || !a->internal || setupPoint(a) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + + p = (ecc_point*)a->internal; + + /* read the curve prime and a */ + if (mp_init_multi(&prime, NULL, NULL, NULL, NULL, NULL) != MP_OKAY) { + WOLFSSL_MSG("mp_init_multi error"); + return WOLFSSL_FAILURE; + } + + if (mp_sub(&prime, p->y, p->y) != MP_OKAY) { + WOLFSSL_MSG("mp_sub error"); + return WOLFSSL_FAILURE; + } + + if (SetECPointExternal(a) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECPointExternal error"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *p) { WOLFSSL_ENTER("wolfSSL_EC_POINT_clear_free"); @@ -34354,7 +34646,7 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, int ret; ret = EncryptDerKey(derBuf, &derSz, cipher, - passwd, passwdSz, &cipherInfo); + passwd, passwdSz, &cipherInfo, der_max_len); if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("EncryptDerKey failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); @@ -34664,7 +34956,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, int ret; ret = EncryptDerKey(derBuf, &derSz, cipher, - passwd, passwdSz, &cipherInfo); + passwd, passwdSz, &cipherInfo, der_max_len); if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("EncryptDerKey failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); @@ -37483,6 +37775,46 @@ static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName) #endif /* WOLFSSL_CERT_GEN */ #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name, + unsigned char **in, long length) + { + WOLFSSL_X509_NAME* tmp = NULL; + DecodedCert cert; + + WOLFSSL_ENTER("wolfSSL_d2i_X509_NAME"); + + if (!in || !*in || length <= 0) { + WOLFSSL_MSG("Bad argument"); + return NULL; + } + + /* Set the X509_NAME buffer as the input data for cert. + * in is NOT a full certificate. Just the name. */ + InitDecodedCert(&cert, *in, (word32)length, NULL); + + /* Parse the X509 subject name */ + if (GetName(&cert, SUBJECT, (int)length) != 0) { + WOLFSSL_MSG("WOLFSSL_X509_NAME parse error"); + goto cleanup; + } + + if (!(tmp = wolfSSL_X509_NAME_new())) { + WOLFSSL_MSG("wolfSSL_X509_NAME_new error"); + goto cleanup; + } + + XSTRNCPY(tmp->staticName, cert.subject, ASN_NAME_MAX); + tmp->staticName[ASN_NAME_MAX - 1] = '\0'; + tmp->sz = (int)XSTRLEN(tmp->staticName) + 1; + + if (name) + *name = tmp; +cleanup: + FreeDecodedCert(&cert); + return tmp; + } + + /* Compares the two X509 names. If the size of x is larger then y then a * positive value is returned if x is smaller a negative value is returned. * In the case that the sizes are equal a the value of strcmp between the diff --git a/tests/api.c b/tests/api.c index 847798e5e..5a9edb71b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1882,6 +1882,7 @@ static void test_wolfSSL_EC(void) #if defined(HAVE_ECC) BN_CTX *ctx; EC_GROUP *group; + EC_GROUP *group2; EC_POINT *Gxy, *new_point, *set_point; BIGNUM *k = NULL, *Gx = NULL, *Gy = NULL, *Gz = NULL; BIGNUM *X, *Y; @@ -1921,6 +1922,7 @@ static void test_wolfSSL_EC(void) AssertNotNull(ctx = BN_CTX_new()); AssertNotNull(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); + AssertNotNull(group2 = EC_GROUP_dup(group)); AssertIntEQ((group_bits = EC_GROUP_order_bits(group)), 256); AssertNotNull(Gxy = EC_POINT_new(group)); AssertNotNull(new_point = EC_POINT_new(group)); @@ -1942,6 +1944,7 @@ static void test_wolfSSL_EC(void) #ifndef HAVE_SELFTEST /* perform point multiplication */ + AssertIntEQ(EC_POINT_add(group, new_point, new_point, Gxy, ctx), WOLFSSL_SUCCESS); AssertIntEQ(EC_POINT_mul(group, new_point, Gx, Gxy, k, ctx), WOLFSSL_SUCCESS); AssertIntEQ(BN_is_zero(new_point->X), 0); AssertIntEQ(BN_is_zero(new_point->Y), 0); @@ -1961,6 +1964,13 @@ static void test_wolfSSL_EC(void) AssertIntEQ(BN_is_zero(new_point->Z), 0); #endif + /* check if point X coordinate is zero */ + AssertIntEQ(BN_is_zero(new_point->X), 0); + +#ifdef USE_ECC_B_PARAM + AssertIntEQ(EC_POINT_is_on_curve(group, new_point, ctx), 1); +#endif /* USE_ECC_B_PARAM */ + /* Force non-affine coordinates */ AssertIntEQ(BN_add(new_point->Z, (WOLFSSL_BIGNUM*)BN_value_one(), (WOLFSSL_BIGNUM*)BN_value_one()), 1); @@ -1981,6 +1991,9 @@ static void test_wolfSSL_EC(void) /* Test copying */ AssertIntEQ(EC_POINT_copy(new_point, set_point), 1); + /* Test inverting */ + AssertIntEQ(EC_POINT_invert(group, new_point, ctx), 1); + AssertPtrEq(EC_POINT_point2bn(group, set_point, POINT_CONVERSION_UNCOMPRESSED, set_point_bn, ctx), set_point_bn); @@ -2065,6 +2078,7 @@ static void test_wolfSSL_EC(void) EC_POINT_free(set_point); EC_POINT_free(Gxy); EC_GROUP_free(group); + EC_GROUP_free(group2); BN_CTX_free(ctx); #endif /* HAVE_ECC */ } @@ -2119,6 +2133,36 @@ static void test_wolfSSL_ECDSA_SIG(void) #endif /* HAVE_ECC */ } +static void test_EC_i2d(void) +{ +#if defined(HAVE_ECC) && !defined(HAVE_FIPS) + EC_KEY *key; + EC_KEY *copy; + int len; + unsigned char *buf = NULL; + const unsigned char *tmp = NULL; + + AssertNotNull(key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); + AssertIntEQ(EC_KEY_generate_key(key), 1); + + AssertIntGT((len = i2d_EC_PUBKEY(key, NULL)), 0); + AssertIntEQ(i2d_EC_PUBKEY(key, &buf), len); + + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + buf = NULL; + + AssertIntGT((len = i2d_ECPrivateKey(key, NULL)), 0); + AssertIntEQ(i2d_ECPrivateKey(key, &buf), len); + + tmp = buf; + AssertNotNull(d2i_ECPrivateKey(©, &tmp, len)); + + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + EC_KEY_free(key); + EC_KEY_free(copy); +#endif /* HAVE_ECC */ +} + static void test_ECDSA_size_sign(void) { #if defined(HAVE_ECC) && !defined(NO_ECC256) && !defined(NO_ECC_SECP) @@ -2134,7 +2178,7 @@ static void test_ECDSA_size_sign(void) id = wc_ecc_get_curve_id_from_name("SECP256R1"); AssertIntEQ(id, ECC_SECP256R1); - AssertNotNull(key = wolfSSL_EC_KEY_new_by_curve_name(id)); + AssertNotNull(key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); AssertIntEQ(EC_KEY_generate_key(key), 1); AssertIntEQ(ECDSA_sign(0, hash, sizeof(hash), sig, &sigSz, key), 1); AssertIntGE(ECDSA_size(key), sigSz); @@ -5486,7 +5530,7 @@ static void test_wolfSSL_X509_verify(void) WOLFSSL_X509* server; WOLFSSL_EVP_PKEY* pkey; unsigned char buf[2048]; - const unsigned char* pt; + const unsigned char* pt = NULL; int bufSz; printf(testingFmt, "wolfSSL X509 verify"); @@ -5513,6 +5557,9 @@ static void test_wolfSSL_X509_verify(void) /* success case */ pt = buf; AssertNotNull(pkey = wolfSSL_d2i_PUBKEY(NULL, &pt, bufSz)); + + AssertIntEQ(i2d_PUBKEY(pkey, NULL), bufSz); + AssertIntEQ(wolfSSL_X509_verify(server, pkey), WOLFSSL_SUCCESS); wolfSSL_EVP_PKEY_free(pkey); @@ -20150,7 +20197,8 @@ static int test_wc_ecc_del_point (void) /* * Testing wc_ecc_point_is_at_infinity(), wc_ecc_export_point_der(), - * wc_ecc_import_point_der(), wc_ecc_copy_point(), and wc_ecc_cmp_point() + * wc_ecc_import_point_der(), wc_ecc_copy_point(), wc_ecc_point_is_on_curve(), + * and wc_ecc_cmp_point() */ static int test_wc_ecc_pointFns (void) { @@ -20313,6 +20361,27 @@ static int test_wc_ecc_pointFns (void) printf(resultFmt, ret == 0 ? passed : failed); +#ifdef USE_ECC_B_PARAM + printf(testingFmt, "wc_ecc_point_is_on_curve()"); + /* On curve if ret == 0 */ + if (ret == 0) { + ret = wc_ecc_point_is_on_curve(point, idx); + } + /* Test bad args. */ + if (ret == 0) { + ret = wc_ecc_point_is_on_curve(NULL, idx); + if (ret == BAD_FUNC_ARG) { + ret = wc_ecc_point_is_on_curve(point, 1000); + } + if (ret == ECC_BAD_ARG_E) { + ret = 0; + } else if (ret == 0) { + ret = WOLFSSL_FATAL_ERROR; + } + } + printf(resultFmt, ret == 0 ? passed : failed); +#endif /* USE_ECC_B_PARAM */ + /* Free */ wc_ecc_del_point(point); wc_ecc_del_point(cpypt); @@ -23672,6 +23741,7 @@ static void test_wolfSSL_X509_NAME(void) XFILE f; const X509_NAME* a; const X509_NAME* b; + X509_NAME* d2i_name; int sz; unsigned char* tmp; char file[] = "./certs/ca-cert.der"; @@ -23707,6 +23777,9 @@ static void test_wolfSSL_X509_NAME(void) abort(); } + tmp = buf; + AssertNotNull(d2i_name = d2i_X509_NAME(NULL, &tmp, sz)); + /* retry but with the function creating a buffer */ tmp = NULL; AssertIntGT((sz = i2d_X509_NAME((X509_NAME*)b, &tmp)), 0); @@ -23716,6 +23789,7 @@ static void test_wolfSSL_X509_NAME(void) AssertNotNull(b = X509_NAME_dup((X509_NAME*)a)); AssertIntEQ(X509_NAME_cmp(a, b), 0); X509_NAME_free((X509_NAME*)b); + X509_NAME_free(d2i_name); X509_free(x509); @@ -32490,7 +32564,7 @@ static void test_wolfSSL_i2d_PrivateKey() EVP_PKEY* pkey; const unsigned char* server_key = (const unsigned char*)server_key_der_2048; unsigned char buf[FOURK_BUF]; - unsigned char* pt; + unsigned char* pt = NULL; int bufSz; AssertNotNull(pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &server_key, @@ -32509,7 +32583,7 @@ static void test_wolfSSL_i2d_PrivateKey() const unsigned char* client_key = (const unsigned char*)ecc_clikey_der_256; unsigned char buf[FOURK_BUF]; - unsigned char* pt; + unsigned char* pt = NULL; int bufSz; AssertNotNull((pkey = d2i_PrivateKey(EVP_PKEY_EC, NULL, &client_key, @@ -33045,10 +33119,10 @@ static void test_wc_ecc_get_curve_id_from_dp_params(void) id = wc_ecc_get_curve_id_from_name("SECP256R1"); AssertIntEQ(id, ECC_SECP256R1); - ecKey = wolfSSL_EC_KEY_new_by_curve_name(id); + ecKey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); AssertNotNull(ecKey); - ret = wolfSSL_EC_KEY_generate_key(ecKey); + ret = EC_KEY_generate_key(ecKey); if (ret == 0) { /* normal test */ @@ -36733,6 +36807,7 @@ void ApiTest(void) test_ECDSA_size_sign(); test_ED25519(); test_ED448(); + test_EC_i2d(); #endif #if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && \ !defined(HAVE_SELFTEST) && \ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 84197587b..822b8a866 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5552,7 +5552,7 @@ int CalcHashId(const byte* data, word32 len, byte* hash) /* process NAME, either issuer or subject * returns 0 on success and negative values on fail */ -static int GetName(DecodedCert* cert, int nameType, int maxIdx) +int GetName(DecodedCert* cert, int nameType, int maxIdx) { int length; /* length of all distinguished names */ int dummy; diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 3482a4aea..871a95b36 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4044,6 +4044,35 @@ int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point, #endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */ #endif /* HAVE_ECC_DHE */ +#ifdef USE_ECC_B_PARAM +/* Checks if a point p lies on the curve with index curve_idx */ +int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx) +{ + int err; + DECLARE_CURVE_SPECS(curve, 3); + + if (p == NULL) + return BAD_FUNC_ARG; + + /* is the IDX valid ? */ + if (wc_ecc_is_valid_idx(curve_idx) != 1) { + return ECC_BAD_ARG_E; + } + + ALLOC_CURVE_SPECS(3); + err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve, + ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | + ECC_CURVE_FIELD_BF); + if (err == MP_OKAY) { + err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime); + } + + wc_ecc_curve_free(curve); + FREE_CURVE_SPECS(); + + return err; +} +#endif /* USE_ECC_B_PARAM */ #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ !defined(WOLFSSL_CRYPTOCELL) diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 1f11593fe..477e06ea3 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -148,12 +148,21 @@ int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, WOLFSSL_API int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out); WOLFSSL_API +WOLFSSL_EC_KEY *wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY **key, const unsigned char **in, + long len); +WOLFSSL_API +int wolfSSL_i2d_ECPrivateKey(const WOLFSSL_EC_KEY *in, unsigned char **out); +WOLFSSL_API void wolfSSL_EC_KEY_set_conv_form(WOLFSSL_EC_KEY *eckey, char form); WOLFSSL_API WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group, const WOLFSSL_EC_POINT *p, char form, WOLFSSL_BIGNUM *in, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API +int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *point, + WOLFSSL_BN_CTX *ctx); WOLFSSL_API int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, @@ -198,6 +207,8 @@ WOLFSSL_API int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b, WOLFSSL_BN_CTX *ctx); WOLFSSL_API +WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_dup(const WOLFSSL_EC_GROUP *src); +WOLFSSL_API int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group); WOLFSSL_API int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group); @@ -228,11 +239,18 @@ int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, const WOLFSSL_BIGNUM *y, WOLFSSL_BN_CTX *ctx); WOLFSSL_API +int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, + const WOLFSSL_EC_POINT *p1, + const WOLFSSL_EC_POINT *p2, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx); WOLFSSL_API +int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *a, + WOLFSSL_BN_CTX *ctx); +WOLFSSL_API void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *point); WOLFSSL_API int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group, @@ -277,6 +295,7 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_GROUP_set_asn1_flag wolfSSL_EC_GROUP_set_asn1_flag #define EC_GROUP_new_by_curve_name wolfSSL_EC_GROUP_new_by_curve_name #define EC_GROUP_cmp wolfSSL_EC_GROUP_cmp +#define EC_GROUP_dup wolfSSL_EC_GROUP_dup #define EC_GROUP_get_curve_name wolfSSL_EC_GROUP_get_curve_name #define EC_GROUP_get_degree wolfSSL_EC_GROUP_get_degree #define EC_GROUP_get_order wolfSSL_EC_GROUP_get_order @@ -291,7 +310,9 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, wolfSSL_EC_POINT_get_affine_coordinates_GFp #define EC_POINT_set_affine_coordinates_GFp \ wolfSSL_EC_POINT_set_affine_coordinates_GFp +#define EC_POINT_add wolfSSL_EC_POINT_add #define EC_POINT_mul wolfSSL_EC_POINT_mul +#define EC_POINT_invert wolfSSL_EC_POINT_invert #define EC_POINT_clear_free wolfSSL_EC_POINT_clear_free #define EC_POINT_cmp wolfSSL_EC_POINT_cmp #define EC_POINT_copy wolfSSL_EC_POINT_copy @@ -304,7 +325,11 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_POINT_point2oct wolfSSL_EC_POINT_point2oct #define EC_POINT_oct2point wolfSSL_EC_POINT_oct2point #define EC_POINT_point2bn wolfSSL_EC_POINT_point2bn +#define EC_POINT_is_on_curve wolfSSL_EC_POINT_is_on_curve #define i2o_ECPublicKey wolfSSL_i2o_ECPublicKey +#define i2d_EC_PUBKEY wolfSSL_i2o_ECPublicKey +#define d2i_ECPrivateKey wolfSSL_d2i_ECPrivateKey +#define i2d_ECPrivateKey wolfSSL_i2d_ECPrivateKey #define EC_KEY_set_conv_form wolfSSL_EC_KEY_set_conv_form #ifndef HAVE_SELFTEST diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index cdd4790b3..fe1ec4e80 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -180,11 +180,11 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define PKCS8_PRIV_KEY_INFO_free wolfSSL_EVP_PKEY_free #define d2i_PKCS12_fp wolfSSL_d2i_PKCS12_fp +#define i2d_PUBKEY wolfSSL_i2d_PUBKEY #define d2i_PUBKEY wolfSSL_d2i_PUBKEY #define d2i_PUBKEY_bio wolfSSL_d2i_PUBKEY_bio #define d2i_PrivateKey wolfSSL_d2i_PrivateKey #define d2i_AutoPrivateKey wolfSSL_d2i_AutoPrivateKey -#define i2d_PrivateKey wolfSSL_i2d_PrivateKey #define SSL_use_PrivateKey wolfSSL_use_PrivateKey #define SSL_use_PrivateKey_ASN1 wolfSSL_use_PrivateKey_ASN1 #define SSL_use_RSAPrivateKey_ASN1 wolfSSL_use_RSAPrivateKey_ASN1 @@ -454,6 +454,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define sk_X509_INFO_free wolfSSL_sk_X509_INFO_free #define i2d_X509_NAME wolfSSL_i2d_X509_NAME +#define d2i_X509_NAME wolfSSL_d2i_X509_NAME #define X509_NAME_new wolfSSL_X509_NAME_new #define X509_NAME_free wolfSSL_X509_NAME_free #define X509_NAME_dup wolfSSL_X509_NAME_dup diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 6f8874945..a412b3e36 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1322,6 +1322,8 @@ WOLFSSL_API void wolfSSL_X509_STORE_set_verify_cb(WOLFSSL_X509_STORE *st, WOLFSSL_X509_STORE_CTX_verify_cb verify_cb); WOLFSSL_API int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* n, unsigned char** out); +WOLFSSL_API WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name, + unsigned char **in, long length); #ifndef NO_RSA WOLFSSL_API int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset); #endif @@ -1434,11 +1436,12 @@ WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY** out); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** key, const unsigned char** in, long inSz); +WOLFSSL_API int wolfSSL_i2d_PUBKEY(const WOLFSSL_EVP_PKEY *key, unsigned char **der); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, const unsigned char **in, long inSz); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** key, unsigned char** in, long inSz); -WOLFSSL_API int wolfSSL_i2d_PrivateKey(WOLFSSL_EVP_PKEY* key, +WOLFSSL_API int wolfSSL_i2d_PrivateKey(const WOLFSSL_EVP_PKEY* key, unsigned char** der); WOLFSSL_API int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME*); #ifdef OPENSSL_EXTRA diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 877e5dcf7..e37de4ab5 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1006,6 +1006,7 @@ struct TrustedPeerCert { #endif WOLFSSL_LOCAL int CalcHashId(const byte* data, word32 len, byte* hash); +WOLFSSL_LOCAL int GetName(DecodedCert* cert, int nameType, int maxIdx); WOLFSSL_ASN_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz); diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index a63894bae..c28b6b2d9 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -601,6 +601,8 @@ WOLFSSL_API int wc_ecc_cmp_point(ecc_point* a, ecc_point *b); WOLFSSL_API int wc_ecc_point_is_at_infinity(ecc_point *p); +WOLFSSL_API +int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx); #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) WOLFSSL_API