X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fpem%2Fpem_pkey.c;h=beecf62e158266f01c1f80df477e9fef6b7056c0;hp=42ec933efdbad8b0ceb408e7405eb4dc9a31fe1e;hb=1531241c54b36be74967753cdea78c16831f7aa5;hpb=02fd47c8b0930dff9b188fd13bfb9da5e59444a8 diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index 42ec933efd..beecf62e15 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html @@ -17,94 +17,80 @@ #include #include #include -#include "internal/asn1_int.h" -#include "internal/evp_int.h" +#include +#include +#include +#include "crypto/store.h" +#include "crypto/asn1.h" +#include "crypto/evp.h" +#include "pem_local.h" int pem_check_suffix(const char *pem_str, const char *suffix); -EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, - void *u) +EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u, OPENSSL_CTX *libctx, + const char *propq) { - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - int slen; EVP_PKEY *ret = NULL; + OSSL_STORE_CTX *ctx = NULL; + OSSL_STORE_INFO *info = NULL; + UI_METHOD *ui_method = NULL; - if (!PEM_bytes_read_bio_secmem(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, - cb, u)) + if ((ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) == NULL) return NULL; - p = data; - - if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf; - p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); - if (!p8inf) - goto p8err; - ret = EVP_PKCS82PKEY(p8inf); - if (x) { - EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; - } - PKCS8_PRIV_KEY_INFO_free(p8inf); - } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf; - X509_SIG *p8; - int klen; - char psbuf[PEM_BUFSIZE]; - p8 = d2i_X509_SIG(NULL, &p, len); - if (!p8) - goto p8err; - if (cb) - klen = cb(psbuf, PEM_BUFSIZE, 0, u); - else - klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); - if (klen <= 0) { - PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ); - X509_SIG_free(p8); + + if ((ctx = ossl_store_attach_pem_bio(bp, ui_method, u, libctx, + propq)) == NULL) + goto err; +#ifndef OPENSSL_NO_SECURE_HEAP + { + int on = 1; + if (!OSSL_STORE_ctrl(ctx, OSSL_STORE_C_USE_SECMEM, &on)) goto err; + } +#endif + + while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) { + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) { + ret = OSSL_STORE_INFO_get1_PKEY(info); + break; } - p8inf = PKCS8_decrypt(p8, psbuf, klen); - X509_SIG_free(p8); - OPENSSL_cleanse(psbuf, klen); - if (!p8inf) - goto p8err; - ret = EVP_PKCS82PKEY(p8inf); - if (x) { - EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; - } - PKCS8_PRIV_KEY_INFO_free(p8inf); - } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) { - const EVP_PKEY_ASN1_METHOD *ameth; - ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); - if (!ameth || !ameth->old_priv_decode) - goto p8err; - ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len); + OSSL_STORE_INFO_free(info); } - p8err: - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB); + + if (ret != NULL && x != NULL) + *x = ret; + err: - OPENSSL_secure_free(nm); - OPENSSL_secure_free(data); - return (ret); + ossl_store_detach_pem_bio(ctx); + UI_destroy_method(ui_method); + OSSL_STORE_INFO_free(info); + return ret; } -int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) +EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + return PEM_read_bio_PrivateKey_ex(bp, x, cb, u, NULL, NULL); +} + +PEM_write_cb_fnsig(PrivateKey, EVP_PKEY, BIO, write_bio) { + IMPLEMENT_PEM_provided_write_body_vars(EVP_PKEY, PrivateKey); + + IMPLEMENT_PEM_provided_write_body_pass(); + IMPLEMENT_PEM_provided_write_body_main(EVP_PKEY, bio); + + legacy: if (x->ameth == NULL || x->ameth->priv_encode != NULL) - return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, - (char *)kstr, klen, cb, u); - return PEM_write_bio_PrivateKey_traditional(bp, x, enc, kstr, klen, cb, u); + return PEM_write_bio_PKCS8PrivateKey(out, x, enc, + (const char *)kstr, klen, cb, u); + return PEM_write_bio_PrivateKey_traditional(out, x, enc, kstr, klen, cb, u); } -int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x, +int PEM_write_bio_PrivateKey_traditional(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, + const unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { char pem_str[80]; @@ -115,72 +101,72 @@ int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x, EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) { - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - int slen; EVP_PKEY *ret = NULL; + OSSL_STORE_CTX *ctx = NULL; + OSSL_STORE_INFO *info = NULL; - if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS, - bp, 0, NULL)) - return NULL; - p = data; + if ((ctx = ossl_store_attach_pem_bio(bp, UI_null(), NULL, NULL, NULL)) == NULL) + goto err; - if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) { - ret = EVP_PKEY_new(); - if (ret == NULL) - goto err; - if (!EVP_PKEY_set_type_str(ret, nm, slen) - || !ret->ameth->param_decode - || !ret->ameth->param_decode(ret, &p, len)) { - EVP_PKEY_free(ret); - ret = NULL; - goto err; - } - if (x) { - EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; + while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) { + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PARAMS) { + ret = OSSL_STORE_INFO_get1_PARAMS(info); + break; } + OSSL_STORE_INFO_free(info); } + + if (ret != NULL && x != NULL) + *x = ret; + err: - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS, ERR_R_ASN1_LIB); - OPENSSL_free(nm); - OPENSSL_free(data); - return (ret); + ossl_store_detach_pem_bio(ctx); + OSSL_STORE_INFO_free(info); + return ret; } -int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x) +PEM_write_fnsig(Parameters, EVP_PKEY, BIO, write_bio) { char pem_str[80]; + IMPLEMENT_PEM_provided_write_body_vars(EVP_PKEY, Parameters); + + IMPLEMENT_PEM_provided_write_body_main(EVP_PKEY, bio); + + legacy: if (!x->ameth || !x->ameth->param_encode) return 0; BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str); return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode, - pem_str, bp, x, NULL, NULL, 0, 0, NULL); + pem_str, out, x, NULL, NULL, 0, 0, NULL); } #ifndef OPENSSL_NO_STDIO -EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, - void *u) +EVP_PKEY *PEM_read_PrivateKey_ex(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u, OPENSSL_CTX *libctx, + const char *propq) { BIO *b; EVP_PKEY *ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_READ_PRIVATEKEY, ERR_R_BUF_LIB); - return (0); + PEMerr(0, ERR_R_BUF_LIB); + return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_read_bio_PrivateKey(b, x, cb, u); + ret = PEM_read_bio_PrivateKey_ex(b, x, cb, u, libctx, propq); BIO_free(b); - return (ret); + return ret; } -int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, +EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + return PEM_read_PrivateKey_ex(fp, x, cb, u, NULL, NULL); +} + +int PEM_write_PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { BIO *b; @@ -203,25 +189,37 @@ int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) { - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; DH *ret = NULL; + EVP_PKEY *pkey = NULL; + OSSL_STORE_CTX *ctx = NULL; + OSSL_STORE_INFO *info = NULL; + UI_METHOD *ui_method = NULL; - if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u)) + if ((ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) == NULL) return NULL; - p = data; - if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0) - ret = d2i_DHxparams(x, &p, len); - else - ret = d2i_DHparams(x, &p, len); + if ((ctx = ossl_store_attach_pem_bio(bp, ui_method, u, NULL, NULL)) == NULL) + goto err; + + while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) { + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PARAMS) { + pkey = OSSL_STORE_INFO_get0_PARAMS(info); + if (EVP_PKEY_id(pkey) == EVP_PKEY_DHX + || EVP_PKEY_id(pkey) == EVP_PKEY_DH) { + ret = EVP_PKEY_get1_DH(pkey); + break; + } + } + OSSL_STORE_INFO_free(info); + } + + if (ret != NULL && x != NULL) + *x = ret; - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_DHPARAMS, ERR_R_ASN1_LIB); - OPENSSL_free(nm); - OPENSSL_free(data); + err: + ossl_store_detach_pem_bio(ctx); + UI_destroy_method(ui_method); + OSSL_STORE_INFO_free(info); return ret; } @@ -233,12 +231,12 @@ DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u) if ((b = BIO_new(BIO_s_file())) == NULL) { PEMerr(PEM_F_PEM_READ_DHPARAMS, ERR_R_BUF_LIB); - return (0); + return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); ret = PEM_read_bio_DHparams(b, x, cb, u); BIO_free(b); - return (ret); + return ret; } # endif