mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-01-31 01:09:16 +01:00
Init SoftHSMv2 support
- wolfSSL_EVP_PKEY_set1_DH: If both private and public present, output private key - ToTraditionalInline_ex2: Add DH checking - wc_ecc_get_curve_id: check index is not negative - Fix i2d_PKCS8_PRIV_KEY_INFO to actually output pkcs8 instead of just der - wolfSSL_EVP_PKEY2PKCS8: Create duplicate to avoid double free - wolfSSL_DH_generate_key: Fix case where not enough buffer was allocated for 128 bit case - pkcs8_encode: Add DSA and DH support - wolfSSL_d2i_PKCS8_PKEY: Correctly advance buffer - RSA_LOW_MEM: export all integers in compat layer - Add softhsm action - Define - OPENSSL_DH_MAX_MODULUS_BITS - OPENSSL_DSA_MAX_MODULUS_BITS - OPENSSL_RSA_MAX_MODULUS_BITS - Implement - BN_mul_word - i2d_ECPKParameters - PEM_write_bio_PKCS8_PRIV_KEY_INFO - PEM_read_bio_PKCS8_PRIV_KEY_INFO - i2d_PKCS8_PRIV_KEY_INFO - RSA_padding_add_PKCS1_PSS_mgf1 - RSA_verify_PKCS1_PSS_mgf1
This commit is contained in:
234
src/pk.c
234
src/pk.c
@@ -2598,6 +2598,7 @@ int SetRsaExternal(WOLFSSL_RSA* rsa)
|
||||
}
|
||||
|
||||
if (key->type == RSA_PRIVATE) {
|
||||
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
|
||||
if (ret == 1) {
|
||||
/* Copy private exponent. */
|
||||
ret = wolfssl_bn_set_value(&rsa->d, &key->d);
|
||||
@@ -2619,7 +2620,8 @@ int SetRsaExternal(WOLFSSL_RSA* rsa)
|
||||
WOLFSSL_ERROR_MSG("rsa q error");
|
||||
}
|
||||
}
|
||||
#ifndef RSA_LOW_MEM
|
||||
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
|
||||
!defined(RSA_LOW_MEM)
|
||||
if (ret == 1) {
|
||||
/* Copy d mod p-1. */
|
||||
ret = wolfssl_bn_set_value(&rsa->dmp1, &key->dP);
|
||||
@@ -2641,7 +2643,11 @@ int SetRsaExternal(WOLFSSL_RSA* rsa)
|
||||
WOLFSSL_ERROR_MSG("rsa u error");
|
||||
}
|
||||
}
|
||||
#endif /* !RSA_LOW_MEM */
|
||||
#endif
|
||||
#else
|
||||
WOLFSSL_ERROR_MSG("rsa private key not compiled in ");
|
||||
ret = 0;
|
||||
#endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
|
||||
}
|
||||
}
|
||||
if (ret == 1) {
|
||||
@@ -2696,6 +2702,7 @@ int SetRsaInternal(WOLFSSL_RSA* rsa)
|
||||
/* Enough numbers for public key */
|
||||
key->type = RSA_PUBLIC;
|
||||
|
||||
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
|
||||
/* Copy down private exponent if available. */
|
||||
if ((ret == 1) && (rsa->d != NULL)) {
|
||||
if (wolfssl_bn_get_value(rsa->d, &key->d) != 1) {
|
||||
@@ -2722,7 +2729,7 @@ int SetRsaInternal(WOLFSSL_RSA* rsa)
|
||||
ret = WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
#ifndef RSA_LOW_MEM
|
||||
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
|
||||
/* Copy down d mod p-1 if available. */
|
||||
if ((ret == 1) && (rsa->dmp1 != NULL) &&
|
||||
(wolfssl_bn_get_value(rsa->dmp1, &key->dP) != 1)) {
|
||||
@@ -2743,7 +2750,8 @@ int SetRsaInternal(WOLFSSL_RSA* rsa)
|
||||
WOLFSSL_ERROR_MSG("rsa u key error");
|
||||
ret = WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
#endif /* !RSA_LOW_MEM */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (ret == 1) {
|
||||
/* All available numbers have been set down. */
|
||||
@@ -3523,12 +3531,15 @@ int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* e,
|
||||
* @param [out] em Encoded message.
|
||||
* @param [in[ mHash Message hash.
|
||||
* @param [in] hashAlg Hash algorithm.
|
||||
* @param [in] mgf1Hash MGF algorithm.
|
||||
* @param [in] saltLen Length of salt to generate.
|
||||
* @return 1 on success.
|
||||
* @return 0 on failure.
|
||||
*/
|
||||
int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
|
||||
const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg, int saltLen)
|
||||
|
||||
int wolfSSL_RSA_padding_add_PKCS1_PSS_mgf1(WOLFSSL_RSA *rsa, unsigned char *em,
|
||||
const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg,
|
||||
const WOLFSSL_EVP_MD *mgf1Hash, int saltLen)
|
||||
{
|
||||
int ret = 1;
|
||||
enum wc_HashType hashType;
|
||||
@@ -3551,6 +3562,9 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (mgf1Hash == NULL)
|
||||
mgf1Hash = hashAlg;
|
||||
|
||||
if (ret == 1) {
|
||||
/* Get/create an RNG. */
|
||||
rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng);
|
||||
@@ -3576,7 +3590,7 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
|
||||
}
|
||||
if (ret == 1) {
|
||||
/* Get the wolfCrypt MGF algorithm from hash algorithm. */
|
||||
mgf = wc_hash2mgf(hashType);
|
||||
mgf = wc_hash2mgf(EvpMd2MacType(mgf1Hash));
|
||||
if (mgf == WC_MGF1NONE) {
|
||||
WOLFSSL_ERROR_MSG("wc_hash2mgf error");
|
||||
ret = 0;
|
||||
@@ -3647,6 +3661,13 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
|
||||
const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg, int saltLen)
|
||||
{
|
||||
return wolfSSL_RSA_padding_add_PKCS1_PSS_mgf1(rsa, em, mHash, hashAlg, NULL,
|
||||
saltLen);
|
||||
}
|
||||
|
||||
/* Checks that the hash is valid for the RSA PKCS#1 PSS encoded message.
|
||||
*
|
||||
* Refer to wolfSSL_RSA_padding_add_PKCS1_PSS for a diagram.
|
||||
@@ -3654,14 +3675,15 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
|
||||
* @param [in] rsa RSA key.
|
||||
* @param [in[ mHash Message hash.
|
||||
* @param [in] hashAlg Hash algorithm.
|
||||
* @param [in] mgf1Hash MGF algorithm.
|
||||
* @param [in] em Encoded message.
|
||||
* @param [in] saltLen Length of salt to generate.
|
||||
* @return 1 on success.
|
||||
* @return 0 on failure.
|
||||
*/
|
||||
int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
|
||||
const WOLFSSL_EVP_MD *hashAlg,
|
||||
const unsigned char *em, int saltLen)
|
||||
int wolfSSL_RSA_verify_PKCS1_PSS_mgf1(WOLFSSL_RSA *rsa,
|
||||
const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg,
|
||||
const WOLFSSL_EVP_MD *mgf1Hash, const unsigned char *em, int saltLen)
|
||||
{
|
||||
int ret = 1;
|
||||
int hashLen = 0;
|
||||
@@ -3679,6 +3701,9 @@ int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (mgf1Hash == NULL)
|
||||
mgf1Hash = hashAlg;
|
||||
|
||||
/* TODO: use wolfCrypt RSA key to get emLen and bits? */
|
||||
/* Set the external data from the wolfCrypt RSA key if not done. */
|
||||
if ((ret == 1) && (!rsa->exSet)) {
|
||||
@@ -3741,7 +3766,7 @@ int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
|
||||
|
||||
if (ret == 1) {
|
||||
/* Get the wolfCrypt MGF algorithm from hash algorithm. */
|
||||
if ((mgf = wc_hash2mgf(hashType)) == WC_MGF1NONE) {
|
||||
if ((mgf = wc_hash2mgf(EvpMd2MacType(mgf1Hash))) == WC_MGF1NONE) {
|
||||
WOLFSSL_ERROR_MSG("wc_hash2mgf error");
|
||||
ret = 0;
|
||||
}
|
||||
@@ -3784,6 +3809,14 @@ int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
|
||||
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
|
||||
const WOLFSSL_EVP_MD *hashAlg,
|
||||
const unsigned char *em, int saltLen)
|
||||
{
|
||||
return wolfSSL_RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, hashAlg, NULL, em,
|
||||
saltLen);
|
||||
}
|
||||
#endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */
|
||||
#endif /* WC_RSA_PSS && (OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY ||
|
||||
* WOLFSSL_NGINX) */
|
||||
@@ -5434,11 +5467,11 @@ WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig,
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_SELFTEST */
|
||||
|
||||
/* return 1 on success, < 0 otherwise */
|
||||
int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
|
||||
WOLFSSL_DSA* dsa)
|
||||
#endif /* !HAVE_SELFTEST */
|
||||
|
||||
static int dsa_do_sign(const unsigned char* d, int dLen, unsigned char* sigRet,
|
||||
WOLFSSL_DSA* dsa)
|
||||
{
|
||||
int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
|
||||
int initTmpRng = 0;
|
||||
@@ -5449,8 +5482,6 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
|
||||
WC_RNG tmpRng[1];
|
||||
#endif
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
|
||||
|
||||
if (d == NULL || sigRet == NULL || dsa == NULL) {
|
||||
WOLFSSL_MSG("Bad function arguments");
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
@@ -5486,10 +5517,18 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
|
||||
}
|
||||
|
||||
if (rng) {
|
||||
if (wc_DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
|
||||
WOLFSSL_MSG("DsaSign failed");
|
||||
#ifdef HAVE_SELFTEST
|
||||
if (dLen != WC_SHA_DIGEST_SIZE ||
|
||||
wc_DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
|
||||
WOLFSSL_MSG("wc_DsaSign failed or dLen wrong length");
|
||||
ret = WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
#else
|
||||
if (wc_DsaSign_ex(d, dLen, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
|
||||
WOLFSSL_MSG("wc_DsaSign_ex failed");
|
||||
ret = WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
@@ -5503,6 +5542,15 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* return 1 on success, < 0 otherwise */
|
||||
int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
|
||||
WOLFSSL_DSA* dsa)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
|
||||
|
||||
return dsa_do_sign(d, WC_SHA_DIGEST_SIZE, sigRet, dsa);
|
||||
}
|
||||
|
||||
#ifndef HAVE_SELFTEST
|
||||
WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest,
|
||||
int inLen, WOLFSSL_DSA* dsa)
|
||||
@@ -5513,12 +5561,12 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest,
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_DSA_do_sign_ex");
|
||||
|
||||
if (!digest || !dsa || inLen != WC_SHA_DIGEST_SIZE) {
|
||||
if (!digest || !dsa) {
|
||||
WOLFSSL_MSG("Bad function arguments");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wolfSSL_DSA_do_sign(digest, sigBin, dsa) != 1) {
|
||||
if (dsa_do_sign(digest, inLen, sigBin, dsa) != 1) {
|
||||
WOLFSSL_MSG("wolfSSL_DSA_do_sign error");
|
||||
return NULL;
|
||||
}
|
||||
@@ -5537,15 +5585,13 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest,
|
||||
/* 2 * sigLen for the two points r and s */
|
||||
return wolfSSL_d2i_DSA_SIG(NULL, &tmp, 2 * sigLen);
|
||||
}
|
||||
#endif /* !HAVE_SELFTEST */
|
||||
#endif
|
||||
|
||||
int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
|
||||
static int dsa_do_verify(const unsigned char* d, int dLen, unsigned char* sig,
|
||||
WOLFSSL_DSA* dsa, int *dsacheck)
|
||||
{
|
||||
int ret;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
|
||||
|
||||
if (d == NULL || sig == NULL || dsa == NULL) {
|
||||
WOLFSSL_MSG("Bad function arguments");
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
@@ -5560,13 +5606,30 @@ int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
|
||||
}
|
||||
}
|
||||
|
||||
ret = DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck);
|
||||
if (ret != 0 || *dsacheck != 1) {
|
||||
#ifdef HAVE_SELFTEST
|
||||
ret = dLen == WC_SHA_DIGEST_SIZE ?
|
||||
wc_DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck) : BAD_FUNC_ARG;
|
||||
#else
|
||||
ret = wc_DsaVerify_ex(d, dLen, sig, (DsaKey*)dsa->internal, dsacheck);
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("DsaVerify failed");
|
||||
return ret;
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
if (*dsacheck != 1) {
|
||||
WOLFSSL_MSG("DsaVerify sig failed");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
|
||||
WOLFSSL_DSA* dsa, int *dsacheck)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
|
||||
|
||||
return dsa_do_verify(d, WC_SHA_DIGEST_SIZE, sig, dsa, dsacheck);
|
||||
}
|
||||
|
||||
|
||||
@@ -5591,7 +5654,7 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len,
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_DSA_do_verify_ex");
|
||||
|
||||
if (!digest || !sig || !dsa || digest_len != WC_SHA_DIGEST_SIZE) {
|
||||
if (!digest || !sig || !dsa) {
|
||||
WOLFSSL_MSG("Bad function arguments");
|
||||
return 0;
|
||||
}
|
||||
@@ -5643,14 +5706,14 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len,
|
||||
if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == -1)
|
||||
return 0;
|
||||
|
||||
if ((wolfSSL_DSA_do_verify(digest, sigBin, dsa, &dsacheck)
|
||||
if ((dsa_do_verify(digest, digest_len, sigBin, dsa, &dsacheck)
|
||||
!= 1) || dsacheck != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* !HAVE_SELFTEST */
|
||||
#endif
|
||||
|
||||
int wolfSSL_i2d_DSAparams(const WOLFSSL_DSA* dsa,
|
||||
unsigned char** out)
|
||||
@@ -8606,6 +8669,10 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
|
||||
/* Private key size can be as much as the size of the prime. */
|
||||
if (dh->length) {
|
||||
privSz = (word32)(dh->length / 8); /* to bytes */
|
||||
/* Special case where priv key is larger than dh->length / 8
|
||||
* See GeneratePrivateDh */
|
||||
if (dh->length == 128)
|
||||
privSz = 21;
|
||||
}
|
||||
else {
|
||||
privSz = pubSz;
|
||||
@@ -9373,6 +9440,47 @@ WOLFSSL_EC_GROUP *wolfSSL_d2i_ECPKParameters(WOLFSSL_EC_GROUP **out,
|
||||
{
|
||||
return wolfssl_ec_group_d2i(out, in, len);
|
||||
}
|
||||
|
||||
int wolfSSL_i2d_ECPKParameters(const WOLFSSL_EC_GROUP* grp, unsigned char** pp)
|
||||
{
|
||||
unsigned char* out = NULL;
|
||||
int len = 0;
|
||||
int idx;
|
||||
const byte* oid = NULL;
|
||||
word32 oidSz = 0;
|
||||
|
||||
if (grp == NULL || !wc_ecc_is_valid_idx(grp->curve_idx) ||
|
||||
grp->curve_idx < 0)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
/* Get the actual DER encoding of the OID. ecc_sets[grp->curve_idx].oid
|
||||
* is just the numerical representation. */
|
||||
if (wc_ecc_get_oid(grp->curve_oid, &oid, &oidSz) < 0)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
len = SetObjectId(oidSz, NULL) + oidSz;
|
||||
|
||||
if (pp == NULL)
|
||||
return len;
|
||||
|
||||
if (*pp == NULL) {
|
||||
out = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1);
|
||||
if (out == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
else {
|
||||
out = *pp;
|
||||
}
|
||||
|
||||
idx = SetObjectId(oidSz, out);
|
||||
XMEMCPY(out + idx, oid, oidSz);
|
||||
if (*pp == NULL)
|
||||
*pp = out;
|
||||
else
|
||||
*pp += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
#endif /* !NO_BIO */
|
||||
|
||||
#if defined(OPENSSL_ALL) && !defined(NO_CERTS)
|
||||
@@ -9663,6 +9771,12 @@ int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret == 1 &&
|
||||
(group->curve_idx < 0 || !wc_ecc_is_valid_idx(group->curve_idx))) {
|
||||
WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order Bad group idx");
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret == 1) {
|
||||
mp = (mp_int*)order->internal;
|
||||
}
|
||||
@@ -15645,6 +15759,13 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
|
||||
PKCS8_PRIV_KEY_INFO* wolfSSL_PEM_read_bio_PKCS8_PRIV_KEY_INFO(WOLFSSL_BIO* bio,
|
||||
PKCS8_PRIV_KEY_INFO** key, wc_pem_password_cb* cb, void* arg)
|
||||
{
|
||||
return wolfSSL_PEM_read_bio_PrivateKey(bio, key, cb, arg);
|
||||
}
|
||||
#endif /* !NO_BIO */
|
||||
|
||||
#if !defined(NO_FILESYSTEM)
|
||||
@@ -16278,8 +16399,6 @@ int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data, long* len,
|
||||
#ifdef OPENSSL_ALL
|
||||
#if !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
|
||||
|
||||
#if !defined(NO_BIO) || (!defined(NO_FILESYSTEM) && \
|
||||
!defined(NO_STDIO_FILESYSTEM))
|
||||
/* Encrypt the key into a buffer using PKCS$8 and a password.
|
||||
*
|
||||
* @param [in] pkey Private key to encrypt.
|
||||
@@ -16292,7 +16411,7 @@ int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data, long* len,
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when EVP cipher not supported.
|
||||
*/
|
||||
static int pem_pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
|
||||
int pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
|
||||
const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz, byte* key,
|
||||
word32* keySz)
|
||||
{
|
||||
@@ -16356,7 +16475,7 @@ static int pem_pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
|
||||
* @param On out, size of encoded key in bytes.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
static int pem_pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
|
||||
int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
|
||||
{
|
||||
int ret = 0;
|
||||
int algId;
|
||||
@@ -16379,6 +16498,34 @@ static int pem_pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
|
||||
curveOid = NULL;
|
||||
oidSz = 0;
|
||||
}
|
||||
else if (pkey->type == EVP_PKEY_DSA) {
|
||||
/* DSA has no curve information. */
|
||||
algId = DSAk;
|
||||
curveOid = NULL;
|
||||
oidSz = 0;
|
||||
}
|
||||
else if (pkey->type == EVP_PKEY_DH) {
|
||||
if (pkey->dh == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (pkey->dh->priv_key != NULL || pkey->dh->pub_key != NULL) {
|
||||
/* Special case. DH buffer is always in PKCS8 format */
|
||||
if (keySz == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
*keySz = pkey->pkey_sz;
|
||||
if (key == NULL)
|
||||
return LENGTH_ONLY_E;
|
||||
|
||||
XMEMCPY(key, pkey->pkey.ptr, pkey->pkey_sz);
|
||||
return pkey->pkey_sz;
|
||||
}
|
||||
|
||||
/* DH has no curve information. */
|
||||
algId = DHk;
|
||||
curveOid = NULL;
|
||||
oidSz = 0;
|
||||
}
|
||||
else {
|
||||
ret = NOT_COMPILED_IN;
|
||||
}
|
||||
@@ -16392,6 +16539,8 @@ static int pem_pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(NO_BIO) || (!defined(NO_FILESYSTEM) && \
|
||||
!defined(NO_STDIO_FILESYSTEM))
|
||||
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
|
||||
*
|
||||
* @param [out] pem Buffer holding PEM encoding.
|
||||
@@ -16424,7 +16573,7 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
|
||||
|
||||
if (res == 1) {
|
||||
/* Guestimate key size and PEM size. */
|
||||
if (pem_pkcs8_encode(pkey, NULL, &keySz) != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
|
||||
if (pkcs8_encode(pkey, NULL, &keySz) != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
@@ -16472,7 +16621,7 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
|
||||
|
||||
if (res == 1) {
|
||||
/* Encrypt the private key. */
|
||||
ret = pem_pkcs8_encrypt(pkey, enc, passwd, passwdSz, key, &keySz);
|
||||
ret = pkcs8_encrypt(pkey, enc, passwd, passwdSz, key, &keySz);
|
||||
if (ret <= 0) {
|
||||
res = 0;
|
||||
}
|
||||
@@ -16488,7 +16637,7 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
|
||||
type = PKCS8_PRIVATEKEY_TYPE;
|
||||
|
||||
/* Encode private key in PKCS#8 format. */
|
||||
ret = pem_pkcs8_encode(pkey, key, &keySz);
|
||||
ret = pkcs8_encode(pkey, key, &keySz);
|
||||
if (ret < 0) {
|
||||
res = 0;
|
||||
}
|
||||
@@ -16554,6 +16703,13 @@ int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
|
||||
XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return res;
|
||||
}
|
||||
|
||||
int wolfSSL_PEM_write_bio_PKCS8_PRIV_KEY_INFO(WOLFSSL_BIO* bio,
|
||||
PKCS8_PRIV_KEY_INFO* keyInfo)
|
||||
{
|
||||
return wolfSSL_PEM_write_bio_PKCS8PrivateKey(bio, keyInfo, NULL, NULL, 0,
|
||||
NULL, NULL);
|
||||
}
|
||||
#endif /* !NO_BIO */
|
||||
|
||||
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
|
||||
|
||||
87
src/ssl.c
87
src/ssl.c
@@ -7241,29 +7241,51 @@ WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY(
|
||||
WOLFSSL_PKCS8_PRIV_KEY_INFO* pkcs8 = NULL;
|
||||
#ifdef WOLFSSL_PEM_TO_DER
|
||||
int ret;
|
||||
DerBuffer* der = NULL;
|
||||
DerBuffer* pkcs8Der = NULL;
|
||||
DerBuffer rawDer;
|
||||
EncryptedInfo info;
|
||||
int advanceLen = 0;
|
||||
|
||||
XMEMSET(&info, 0, sizeof(info));
|
||||
XMEMSET(&rawDer, 0, sizeof(rawDer));
|
||||
|
||||
if (keyBuf == NULL || *keyBuf == NULL || keyLen <= 0) {
|
||||
WOLFSSL_MSG("Bad key PEM/DER args");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = PemToDer(*keyBuf, keyLen, PRIVATEKEY_TYPE, &der, NULL, NULL, NULL);
|
||||
ret = PemToDer(*keyBuf, keyLen, PRIVATEKEY_TYPE, &pkcs8Der, NULL, &info,
|
||||
NULL);
|
||||
if (ret < 0) {
|
||||
WOLFSSL_MSG("Not PEM format");
|
||||
ret = AllocDer(&der, (word32)keyLen, PRIVATEKEY_TYPE, NULL);
|
||||
ret = AllocDer(&pkcs8Der, (word32)keyLen, PRIVATEKEY_TYPE, NULL);
|
||||
if (ret == 0) {
|
||||
XMEMCPY(der->buffer, *keyBuf, keyLen);
|
||||
XMEMCPY(pkcs8Der->buffer, *keyBuf, keyLen);
|
||||
}
|
||||
}
|
||||
else {
|
||||
advanceLen = (int)info.consumed;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Verify this is PKCS8 Key */
|
||||
word32 inOutIdx = 0;
|
||||
word32 algId;
|
||||
ret = ToTraditionalInline_ex(der->buffer, &inOutIdx, der->length,
|
||||
&algId);
|
||||
ret = ToTraditionalInline_ex(pkcs8Der->buffer, &inOutIdx,
|
||||
pkcs8Der->length, &algId);
|
||||
if (ret >= 0) {
|
||||
if (advanceLen == 0) /* Set only if not PEM */
|
||||
advanceLen = inOutIdx + ret;
|
||||
if (algId == DHk) {
|
||||
/* Special case for DH as we expect the DER buffer to be always
|
||||
* be in PKCS8 format */
|
||||
rawDer.buffer = pkcs8Der->buffer;
|
||||
rawDer.length = inOutIdx + ret;
|
||||
}
|
||||
else {
|
||||
rawDer.buffer = pkcs8Der->buffer + inOutIdx;
|
||||
rawDer.length = ret;
|
||||
}
|
||||
ret = 0; /* good DER */
|
||||
}
|
||||
}
|
||||
@@ -7274,21 +7296,24 @@ WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY(
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
pkcs8->pkey.ptr = (char*)XMALLOC(der->length, NULL,
|
||||
pkcs8->pkey.ptr = (char*)XMALLOC(rawDer.length, NULL,
|
||||
DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
if (pkcs8->pkey.ptr == NULL)
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
XMEMCPY(pkcs8->pkey.ptr, der->buffer, der->length);
|
||||
pkcs8->pkey_sz = (int)der->length;
|
||||
XMEMCPY(pkcs8->pkey.ptr, rawDer.buffer, rawDer.length);
|
||||
pkcs8->pkey_sz = (int)rawDer.length;
|
||||
}
|
||||
|
||||
FreeDer(&der);
|
||||
FreeDer(&pkcs8Der);
|
||||
if (ret != 0) {
|
||||
wolfSSL_EVP_PKEY_free(pkcs8);
|
||||
pkcs8 = NULL;
|
||||
}
|
||||
else {
|
||||
*keyBuf += advanceLen;
|
||||
}
|
||||
if (pkey != NULL) {
|
||||
*pkey = pkcs8;
|
||||
}
|
||||
@@ -7301,6 +7326,48 @@ WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY(
|
||||
return pkcs8;
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_ALL
|
||||
int wolfSSL_i2d_PKCS8_PKEY(WOLFSSL_PKCS8_PRIV_KEY_INFO* key, unsigned char** pp)
|
||||
{
|
||||
word32 keySz = 0;
|
||||
unsigned char* out;
|
||||
int len;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_i2d_PKCS8_PKEY");
|
||||
|
||||
if (key == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
if (pkcs8_encode(key, NULL, &keySz) != WC_NO_ERR_TRACE(LENGTH_ONLY_E))
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
len = (int)keySz;
|
||||
|
||||
if (pp == NULL)
|
||||
return len;
|
||||
|
||||
if (*pp == NULL) {
|
||||
out = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1);
|
||||
if (out == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
else {
|
||||
out = *pp;
|
||||
}
|
||||
|
||||
if (pkcs8_encode(key, out, &keySz) != len) {
|
||||
if (*pp == NULL)
|
||||
XFREE(out, NULL, DYNAMIC_TYPE_ASN1);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
if (*pp == NULL)
|
||||
*pp = out;
|
||||
else
|
||||
*pp += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_BIO
|
||||
/* put SSL type in extra for now, not very common */
|
||||
|
||||
81
src/ssl_bn.c
81
src/ssl_bn.c
@@ -1312,7 +1312,7 @@ static int wolfssl_bn_add_word_int(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w,
|
||||
#endif
|
||||
|
||||
/* Validate parameters. */
|
||||
if (BN_IS_NULL(bn)) {
|
||||
if (ret == 1 && BN_IS_NULL(bn)) {
|
||||
WOLFSSL_MSG("bn NULL error");
|
||||
ret = 0;
|
||||
}
|
||||
@@ -1419,6 +1419,85 @@ int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wolfSSL_BN_mul_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
|
||||
{
|
||||
int ret = 1;
|
||||
#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT)
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
mp_int* w_mp = NULL;
|
||||
#else
|
||||
mp_int w_mp[1];
|
||||
#endif /* WOLFSSL_SMALL_STACK */
|
||||
#endif
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_BN_mul_word");
|
||||
|
||||
#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT)
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
/* Allocate temporary MP integer. */
|
||||
w_mp = (mp_int*)XMALLOC(sizeof(*w_mp), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (w_mp == NULL) {
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
#endif /* WOLFSSL_SMALL_STACK */
|
||||
{
|
||||
/* Clear out MP integer so it can be freed. */
|
||||
XMEMSET(w_mp, 0, sizeof(*w_mp));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Validate parameters. */
|
||||
if (ret == 1 && BN_IS_NULL(bn)) {
|
||||
WOLFSSL_MSG("bn NULL error");
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret == 1) {
|
||||
int rc = 0;
|
||||
#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT)
|
||||
if (w > (WOLFSSL_BN_ULONG)MP_MASK) {
|
||||
/* Initialize temporary MP integer. */
|
||||
if (mp_init(w_mp) != MP_OKAY) {
|
||||
ret = 0;
|
||||
}
|
||||
/* Set value into temporary MP integer. */
|
||||
if ((ret == 1) && (mp_set_int(w_mp, w) != MP_OKAY)) {
|
||||
ret = 0;
|
||||
}
|
||||
if (ret == 1) {
|
||||
rc = mp_mul((mp_int*)bn->internal, w_mp,
|
||||
(mp_int*)bn->internal);
|
||||
if (rc != MP_OKAY) {
|
||||
WOLFSSL_MSG("mp_mul error");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
rc = mp_mul_d((mp_int*)bn->internal, (mp_digit)w,
|
||||
(mp_int*)bn->internal);
|
||||
if (rc != MP_OKAY) {
|
||||
WOLFSSL_MSG("mp_mul_d error");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT)
|
||||
mp_free(w_mp);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(w_mp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif /* WOLFSSL_SMALL_STACK */
|
||||
#endif
|
||||
|
||||
WOLFSSL_LEAVE("wolfSSL_BN_mul_word", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_RSA) || !defined(NO_DH) || \
|
||||
!defined(NO_DSA))
|
||||
/* Calculate bn modulo word w. bn % w
|
||||
|
||||
Reference in New Issue
Block a user