diff options
author | jsing <> | 2019-04-10 16:23:55 +0000 |
---|---|---|
committer | jsing <> | 2019-04-10 16:23:55 +0000 |
commit | 0eabad513bdb13f3dc8134e8f7b37906897211df (patch) | |
tree | 0a9c02f6209b3ff040902c8d9c0757be964ad0eb /src | |
parent | 725560f8660d40321b5c2f8964b9eb5081895c1e (diff) | |
download | openbsd-0eabad513bdb13f3dc8134e8f7b37906897211df.tar.gz openbsd-0eabad513bdb13f3dc8134e8f7b37906897211df.tar.bz2 openbsd-0eabad513bdb13f3dc8134e8f7b37906897211df.zip |
Avoid an overread caused by d2i_PrivateKey().
There are cases where the old_priv_decode() function can fail but consume
bytes. This will result in the pp pointer being advanced, which causes
d2i_PKCS8_PRIV_KEY_INFO() to be called with an advanced pointer and
incorrect length.
Fixes oss-fuzz #13803 and #14142.
ok deraadt@ tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/asn1/d2i_pr.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/src/lib/libcrypto/asn1/d2i_pr.c b/src/lib/libcrypto/asn1/d2i_pr.c index a657a1f3cd..e450dee12f 100644 --- a/src/lib/libcrypto/asn1/d2i_pr.c +++ b/src/lib/libcrypto/asn1/d2i_pr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: d2i_pr.c,v 1.16 2018/04/14 07:09:21 tb Exp $ */ | 1 | /* $OpenBSD: d2i_pr.c,v 1.17 2019/04/10 16:23:55 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -76,6 +76,7 @@ | |||
76 | EVP_PKEY * | 76 | EVP_PKEY * |
77 | d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) | 77 | d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) |
78 | { | 78 | { |
79 | const unsigned char *p = *pp; | ||
79 | EVP_PKEY *ret; | 80 | EVP_PKEY *ret; |
80 | 81 | ||
81 | if ((a == NULL) || (*a == NULL)) { | 82 | if ((a == NULL) || (*a == NULL)) { |
@@ -100,6 +101,7 @@ d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) | |||
100 | !ret->ameth->old_priv_decode(ret, pp, length)) { | 101 | !ret->ameth->old_priv_decode(ret, pp, length)) { |
101 | if (ret->ameth->priv_decode) { | 102 | if (ret->ameth->priv_decode) { |
102 | PKCS8_PRIV_KEY_INFO *p8 = NULL; | 103 | PKCS8_PRIV_KEY_INFO *p8 = NULL; |
104 | *pp = p; /* XXX */ | ||
103 | p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, pp, length); | 105 | p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, pp, length); |
104 | if (!p8) | 106 | if (!p8) |
105 | goto err; | 107 | goto err; |