X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fpem%2Fpvkfmt.c;h=281c6cd95a154c171f3bdaf17a450b767ed8465d;hp=4c07aee8f2471ab0a325ad7a57cab974705204a9;hb=c82c3462267afdbbaa53e11da0508ce4e03c02b3;hpb=6286757141a8c6e14d647ec733634ae0c83d9887 diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c index 4c07aee8f2..281c6cd95a 100644 --- a/crypto/pem/pvkfmt.c +++ b/crypto/pem/pvkfmt.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -66,6 +66,9 @@ static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) # define MS_KEYTYPE_KEYX 0x1 # define MS_KEYTYPE_SIGN 0x2 +/* Maximum length of a blob after header */ +# define BLOB_MAX_LENGTH 102400 + /* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */ # define MS_PVKMAGIC 0xb0b5f11eL /* Salt length for PVK files */ @@ -117,6 +120,7 @@ static int do_blob_header(const unsigned char **in, unsigned int length, case MS_DSS1MAGIC: *pisdss = 1; + /* fall thru */ case MS_RSA1MAGIC: if (*pispub == 0) { PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); @@ -126,6 +130,7 @@ static int do_blob_header(const unsigned char **in, unsigned int length, case MS_DSS2MAGIC: *pisdss = 1; + /* fall thru */ case MS_RSA2MAGIC: if (*pispub == 1) { PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); @@ -211,6 +216,10 @@ static EVP_PKEY *do_b2i_bio(BIO *in, int ispub) return NULL; length = blob_length(bitlen, isdss, ispub); + if (length > BLOB_MAX_LENGTH) { + PEMerr(PEM_F_DO_B2I_BIO, PEM_R_HEADER_TOO_LONG); + return NULL; + } buf = OPENSSL_malloc(length); if (buf == NULL) { PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE); @@ -276,14 +285,17 @@ static EVP_PKEY *b2i_dss(const unsigned char **in, goto memerr; BN_CTX_free(ctx); + ctx = NULL; } if (!DSA_set0_pqg(dsa, pbn, qbn, gbn)) goto memerr; pbn = qbn = gbn = NULL; if (!DSA_set0_key(dsa, pub_key, priv_key)) goto memerr; + pub_key = priv_key = NULL; - EVP_PKEY_set1_DSA(ret, dsa); + if (!EVP_PKEY_set1_DSA(ret, dsa)) + goto memerr; DSA_free(dsa); *in = p; return ret; @@ -336,12 +348,19 @@ static EVP_PKEY *b2i_rsa(const unsigned char **in, goto memerr; if (!read_lebn(&pin, nbyte, &d)) goto memerr; - RSA_set0_factors(rsa, p, q); - RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp); + if (!RSA_set0_factors(rsa, p, q)) + goto memerr; + p = q = NULL; + if (!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) + goto memerr; + dmp1 = dmq1 = iqmp = NULL; } - RSA_set0_key(rsa, n, e, d); + if (!RSA_set0_key(rsa, n, e, d)) + goto memerr; + n = e = d = NULL; - EVP_PKEY_set1_RSA(ret, rsa); + if (!EVP_PKEY_set1_RSA(ret, rsa)) + goto memerr; RSA_free(rsa); *in = pin; return ret; @@ -425,9 +444,10 @@ static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) if (*out) p = *out; else { - p = OPENSSL_malloc(outlen); - if (p == NULL) + if ((p = OPENSSL_malloc(outlen)) == NULL) { + PEMerr(PEM_F_DO_I2B, ERR_R_MALLOC_FAILURE); return -1; + } *out = p; noinc = 1; } @@ -467,7 +487,8 @@ static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub) static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic) { int bitlen; - BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL; + const BIGNUM *p = NULL, *q = NULL, *g = NULL; + const BIGNUM *pub_key = NULL, *priv_key = NULL; DSA_get0_pqg(dsa, &p, &q, &g); DSA_get0_key(dsa, &pub_key, &priv_key); @@ -494,9 +515,9 @@ static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic) static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) { int nbyte, hnbyte, bitlen; - BIGNUM *e; + const BIGNUM *e; - RSA_get0_key(rsa, &e, NULL, NULL); + RSA_get0_key(rsa, NULL, &e, NULL); if (BN_num_bits(e) > 32) goto badkey; bitlen = RSA_bits(rsa); @@ -506,7 +527,7 @@ static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) *pmagic = MS_RSA1MAGIC; return bitlen; } else { - BIGNUM *d, *p, *q, *iqmp, *dmp1, *dmq1; + const BIGNUM *d, *p, *q, *iqmp, *dmp1, *dmq1; *pmagic = MS_RSA2MAGIC; @@ -534,13 +555,13 @@ static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) static void write_rsa(unsigned char **out, RSA *rsa, int ispub) { int nbyte, hnbyte; - BIGNUM *n, *d, *e, *p, *q, *iqmp, *dmp1, *dmq1; + const BIGNUM *n, *d, *e, *p, *q, *iqmp, *dmp1, *dmq1; nbyte = RSA_size(rsa); hnbyte = (RSA_bits(rsa) + 15) >> 4; - RSA_get0_key(rsa, &e, &n, &d); + RSA_get0_key(rsa, &n, &e, &d); write_lebn(out, e, 4); - write_lebn(out, n, -1); + write_lebn(out, n, nbyte); if (ispub) return; RSA_get0_factors(rsa, &p, &q); @@ -556,7 +577,8 @@ static void write_rsa(unsigned char **out, RSA *rsa, int ispub) static void write_dsa(unsigned char **out, DSA *dsa, int ispub) { int nbyte; - BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL; + const BIGNUM *p = NULL, *q = NULL, *g = NULL; + const BIGNUM *pub_key = NULL, *priv_key = NULL; DSA_get0_pqg(dsa, &p, &q, &g); DSA_get0_key(dsa, &pub_key, &priv_key); @@ -664,7 +686,7 @@ static EVP_PKEY *do_PVK_body(const unsigned char **in, inlen = cb(psbuf, PEM_BUFSIZE, 0, u); else inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); - if (inlen <= 0) { + if (inlen < 0) { PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ); goto err; } @@ -757,7 +779,7 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, pem_password_cb *cb, void *u) { int outlen = 24, pklen; - unsigned char *p = NULL, *salt = NULL; + unsigned char *p = NULL, *start = NULL, *salt = NULL; EVP_CIPHER_CTX *cctx = NULL; if (enclevel) outlen += PVK_SALTLEN; @@ -770,7 +792,7 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, if (*out != NULL) { p = *out; } else { - p = OPENSSL_malloc(outlen); + start = p = OPENSSL_malloc(outlen); if (p == NULL) { PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE); return -1; @@ -827,14 +849,14 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, EVP_CIPHER_CTX_free(cctx); if (*out == NULL) - *out = p; + *out = start; return outlen; error: EVP_CIPHER_CTX_free(cctx); if (*out == NULL) - OPENSSL_free(p); + OPENSSL_free(start); return -1; }