/*
- * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/rsa.h>
+#include <openssl/kdf.h>
+#include <openssl/core_names.h>
#include "internal/cryptlib.h"
#include "crypto/pem.h"
#include "crypto/evp.h"
case EVP_PKEY_RSA:
if (EVP_PKEY_set1_RSA(pkey, key))
break;
+ ERR_raise(ERR_LIB_PEM, ERR_R_EVP_LIB);
EVP_PKEY_free(pkey);
pkey = NULL;
break;
case EVP_PKEY_DSA:
if (EVP_PKEY_set1_DSA(pkey, key))
break;
+ ERR_raise(ERR_LIB_PEM, ERR_R_EVP_LIB);
EVP_PKEY_free(pkey);
pkey = NULL;
break;
#endif
}
+ } else {
+ ERR_raise(ERR_LIB_PEM, ERR_R_EVP_LIB);
}
switch (evp_type) {
#endif
}
- if (pkey == NULL)
- ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
return pkey;
}
* Read the MSBLOB header and get relevant data from it.
*
* |pisdss| and |pispub| have a double role, as they can be used for
- * discovery as well as to check the the blob meets expectations.
+ * discovery as well as to check the blob meets expectations.
* |*pisdss| is the indicator for whether the key is a DSA key or not.
* |*pispub| is the indicator for whether the key is public or not.
* In both cases, the following input values apply:
return NULL;
}
buf = OPENSSL_malloc(length);
- if (buf == NULL) {
- ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
+ if (buf == NULL)
goto err;
- }
p = buf;
if (BIO_read(in, buf, length) != (int)length) {
ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT);
dsa = DSA_new();
if (dsa == NULL)
- goto memerr;
+ goto dsaerr;
if (!read_lebn(&p, nbyte, &pbn))
- goto memerr;
+ goto bnerr;
if (!read_lebn(&p, 20, &qbn))
- goto memerr;
+ goto bnerr;
if (!read_lebn(&p, nbyte, &gbn))
- goto memerr;
+ goto bnerr;
if (ispub) {
if (!read_lebn(&p, nbyte, &pub_key))
- goto memerr;
+ goto bnerr;
} else {
if (!read_lebn(&p, 20, &priv_key))
- goto memerr;
+ goto bnerr;
/* Set constant time flag before public key calculation */
BN_set_flags(priv_key, BN_FLG_CONSTTIME);
/* Calculate public key */
pub_key = BN_new();
if (pub_key == NULL)
- goto memerr;
+ goto bnerr;
if ((ctx = BN_CTX_new()) == NULL)
- goto memerr;
+ goto bnerr;
if (!BN_mod_exp(pub_key, gbn, priv_key, pbn, ctx))
- goto memerr;
+ goto bnerr;
BN_CTX_free(ctx);
ctx = NULL;
}
if (!DSA_set0_pqg(dsa, pbn, qbn, gbn))
- goto memerr;
+ goto dsaerr;
pbn = qbn = gbn = NULL;
if (!DSA_set0_key(dsa, pub_key, priv_key))
- goto memerr;
+ goto dsaerr;
pub_key = priv_key = NULL;
*in = p;
return dsa;
- memerr:
- ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
+ dsaerr:
+ ERR_raise(ERR_LIB_PEM, ERR_R_DSA_LIB);
+ goto err;
+ bnerr:
+ ERR_raise(ERR_LIB_PEM, ERR_R_BN_LIB);
+
+ err:
DSA_free(dsa);
BN_free(pbn);
BN_free(qbn);
rsa = RSA_new();
if (rsa == NULL)
- goto memerr;
+ goto rsaerr;
e = BN_new();
if (e == NULL)
- goto memerr;
+ goto bnerr;
if (!BN_set_word(e, read_ledword(&pin)))
- goto memerr;
+ goto bnerr;
if (!read_lebn(&pin, nbyte, &n))
- goto memerr;
+ goto bnerr;
if (!ispub) {
if (!read_lebn(&pin, hnbyte, &p))
- goto memerr;
+ goto bnerr;
if (!read_lebn(&pin, hnbyte, &q))
- goto memerr;
+ goto bnerr;
if (!read_lebn(&pin, hnbyte, &dmp1))
- goto memerr;
+ goto bnerr;
if (!read_lebn(&pin, hnbyte, &dmq1))
- goto memerr;
+ goto bnerr;
if (!read_lebn(&pin, hnbyte, &iqmp))
- goto memerr;
+ goto bnerr;
if (!read_lebn(&pin, nbyte, &d))
- goto memerr;
+ goto bnerr;
if (!RSA_set0_factors(rsa, p, q))
- goto memerr;
+ goto rsaerr;
p = q = NULL;
if (!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp))
- goto memerr;
+ goto rsaerr;
dmp1 = dmq1 = iqmp = NULL;
}
if (!RSA_set0_key(rsa, n, e, d))
- goto memerr;
+ goto rsaerr;
n = e = d = NULL;
*in = pin;
return rsa;
- memerr:
- ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
+
+ rsaerr:
+ ERR_raise(ERR_LIB_PEM, ERR_R_RSA_LIB);
+ goto err;
+ bnerr:
+ ERR_raise(ERR_LIB_PEM, ERR_R_BN_LIB);
+
+ err:
BN_free(e);
BN_free(n);
BN_free(p);
p = *out;
else {
if ((p = OPENSSL_malloc(outlen)) == NULL) {
- ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
outlen = -1;
goto end;
}
}
#ifndef OPENSSL_NO_RC4
-static int derive_pvk_key(unsigned char *key,
+static int derive_pvk_key(unsigned char *key, size_t keylen,
const unsigned char *salt, unsigned int saltlen,
const unsigned char *pass, int passlen,
OSSL_LIB_CTX *libctx, const char *propq)
{
- EVP_MD_CTX *mctx = EVP_MD_CTX_new();
- int rv = 0;
- EVP_MD *sha1 = NULL;
-
- if ((sha1 = EVP_MD_fetch(libctx, SN_sha1, propq)) == NULL)
- goto err;
+ EVP_KDF *kdf;
+ EVP_KDF_CTX *ctx;
+ OSSL_PARAM params[5], *p = params;
+ int rv;
- if (mctx == NULL
- || !EVP_DigestInit_ex(mctx, sha1, NULL)
- || !EVP_DigestUpdate(mctx, salt, saltlen)
- || !EVP_DigestUpdate(mctx, pass, passlen)
- || !EVP_DigestFinal_ex(mctx, key, NULL))
- goto err;
+ if ((kdf = EVP_KDF_fetch(libctx, "PVKKDF", propq)) == NULL)
+ return 0;
+ ctx = EVP_KDF_CTX_new(kdf);
+ EVP_KDF_free(kdf);
+ if (ctx == NULL)
+ return 0;
- rv = 1;
-err:
- EVP_MD_CTX_free(mctx);
- EVP_MD_free(sha1);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
+ (void *)salt, saltlen);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
+ (void *)pass, passlen);
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, SN_sha1, 0);
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_PROPERTIES,
+ (char *)propq, 0);
+ *p = OSSL_PARAM_construct_end();
+
+ rv = EVP_KDF_derive(ctx, key, keylen, params);
+ EVP_KDF_CTX_free(ctx);
return rv;
}
#endif
#endif
EVP_CIPHER_CTX *cctx = EVP_CIPHER_CTX_new();
+ if (cctx == NULL) {
+ ERR_raise(ERR_LIB_PEM, ERR_R_EVP_LIB);
+ goto err;
+ }
+
if (saltlen) {
#ifndef OPENSSL_NO_RC4
unsigned int magic;
goto err;
}
enctmp = OPENSSL_malloc(keylen + 8);
- if (enctmp == NULL) {
- ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
+ if (enctmp == NULL)
goto err;
- }
- if (!derive_pvk_key(keybuf, p, saltlen,
+ if (!derive_pvk_key(keybuf, sizeof(keybuf), p, saltlen,
(unsigned char *)psbuf, inlen, libctx, propq))
goto err;
p += saltlen;
return 0;
buflen = (int)keylen + saltlen;
buf = OPENSSL_malloc(buflen);
- if (buf == NULL) {
- ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
+ if (buf == NULL)
return 0;
- }
p = buf;
if (BIO_read(in, buf, buflen) != buflen) {
ERR_raise(ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT);
p = *out;
} else {
start = p = OPENSSL_malloc(outlen);
- if (p == NULL) {
- ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
+ if (p == NULL)
return -1;
- }
}
cctx = EVP_CIPHER_CTX_new();
ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ);
goto error;
}
- if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
+ if (!derive_pvk_key(keybuf, sizeof(keybuf), salt, PVK_SALTLEN,
(unsigned char *)psbuf, inlen, libctx, propq))
goto error;
if ((rc4 = EVP_CIPHER_fetch(libctx, "RC4", propq)) == NULL)