Skip to content

Commit dba1354

Browse files
committed
OpenBSD 5.7 errata 3, March 19, 2015
Fix several crash causing defects from OpenSSL. These include: CVE-2015-0209 - Use After Free following d2i_ECPrivatekey error CVE-2015-0286 - Segmentation fault in ASN1_TYPE_cmp CVE-2015-0287 - ASN.1 structure reuse memory corruption CVE-2015-0288 - X509_to_X509_REQ NULL pointer deref CVE-2015-0289 - PKCS7 NULL pointer dereferences Several other issues did not apply or were already fixed. Refer to https://www.openssl.org/news/secadv_20150319.txt ok pedro@
1 parent 53e75ae commit dba1354

File tree

13 files changed

+153
-52
lines changed

13 files changed

+153
-52
lines changed

lib/libssl/src/crypto/asn1/a_int.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len)
268268

269269
err:
270270
ASN1err(ASN1_F_C2I_ASN1_INTEGER, i);
271-
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
271+
if (a == NULL || *a != ret)
272272
M_ASN1_INTEGER_free(ret);
273273
return (NULL);
274274
}
@@ -335,7 +335,7 @@ d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
335335

336336
err:
337337
ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i);
338-
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
338+
if (a == NULL || *a != ret)
339339
M_ASN1_INTEGER_free(ret);
340340
return (NULL);
341341
}

lib/libssl/src/crypto/asn1/a_set.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, const unsigned char **pp, long length,
225225
return ret;
226226

227227
err:
228-
if (ret != NULL && (a == NULL || *a != ret)) {
228+
if (a == NULL || *a != ret) {
229229
if (free_func != NULL)
230230
sk_OPENSSL_BLOCK_pop_free(ret, free_func);
231231
else

lib/libssl/src/crypto/asn1/a_type.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
119119
case V_ASN1_OBJECT:
120120
result = OBJ_cmp(a->value.object, b->value.object);
121121
break;
122-
122+
case V_ASN1_BOOLEAN:
123+
result = a->value.boolean - b->value.boolean;
124+
break;
123125
case V_ASN1_NULL:
124126
result = 0; /* They do not have content. */
125127
break;

lib/libssl/src/crypto/asn1/d2i_pr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length)
118118
return (ret);
119119

120120
err:
121-
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
121+
if (a == NULL || *a != ret)
122122
EVP_PKEY_free(ret);
123123
return (NULL);
124124
}

lib/libssl/src/crypto/asn1/d2i_pu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length)
130130
return (ret);
131131

132132
err:
133-
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
133+
if (a == NULL || *a != ret)
134134
EVP_PKEY_free(ret);
135135
return (NULL);
136136
}

lib/libssl/src/crypto/asn1/n_pkey.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,11 @@ d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
340340
return NULL;
341341
}
342342

343-
if ((enckey->os->length != 11) || (strncmp("private-key",
344-
(char *)enckey->os->data, 11) != 0)) {
343+
/* XXX 11 == strlen("private-key") */
344+
if (enckey->os->length != 11 ||
345+
memcmp("private-key", enckey->os->data, 11) != 0) {
345346
ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_PRIVATE_KEY_HEADER_MISSING);
346-
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
347-
return NULL;
347+
goto err;
348348
}
349349
if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) {
350350
ASN1err(ASN1_F_D2I_RSA_NET,

lib/libssl/src/crypto/asn1/tasn_dec.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,16 @@ ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
238238
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
239239
goto auxerr;
240240

241-
/* Allocate structure */
242-
if (!*pval && !ASN1_item_ex_new(pval, it)) {
241+
if (*pval) {
242+
/* Free up and zero CHOICE value if initialised */
243+
i = asn1_get_choice_selector(pval, it);
244+
if ((i >= 0) && (i < it->tcount)) {
245+
tt = it->templates + i;
246+
pchptr = asn1_get_field_ptr(pval, tt);
247+
ASN1_template_free(pchptr, tt);
248+
asn1_set_choice_selector(pval, -1, it);
249+
}
250+
} else if (!ASN1_item_ex_new(pval, it)) {
243251
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
244252
ERR_R_NESTED_ASN1_ERROR);
245253
goto err;
@@ -325,6 +333,19 @@ ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
325333
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
326334
goto auxerr;
327335

336+
/* Free up and zero any ADB found */
337+
for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
338+
if (tt->flags & ASN1_TFLG_ADB_MASK) {
339+
const ASN1_TEMPLATE *seqtt;
340+
ASN1_VALUE **pseqval;
341+
seqtt = asn1_do_adb(pval, tt, 1);
342+
if (!seqtt)
343+
goto err;
344+
pseqval = asn1_get_field_ptr(pval, seqtt);
345+
ASN1_template_free(pseqval, seqtt);
346+
}
347+
}
348+
328349
/* Get each field entry */
329350
for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
330351
const ASN1_TEMPLATE *seqtt;

lib/libssl/src/crypto/asn1/x_x509.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,16 +313,20 @@ d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
313313

314314
/* Save start position */
315315
q = *pp;
316-
ret = d2i_X509(a, pp, length);
316+
ret = d2i_X509(NULL, pp, length);
317317
/* If certificate unreadable then forget it */
318318
if (!ret)
319319
return NULL;
320320
/* update length */
321321
length -= *pp - q;
322-
if (!length)
323-
return ret;
324-
if (!d2i_X509_CERT_AUX(&ret->aux, pp, length))
325-
goto err;
322+
if (length > 0) {
323+
if (!d2i_X509_CERT_AUX(&ret->aux, pp, length))
324+
goto err;
325+
}
326+
if (a != NULL) {
327+
X509_free(*a);
328+
*a = ret;
329+
}
326330
return ret;
327331

328332
err:

lib/libssl/src/crypto/ec/ec_asn1.c

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -999,19 +999,19 @@ d2i_ECPKParameters(EC_GROUP ** a, const unsigned char **in, long len)
999999

10001000
if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
10011001
ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
1002-
ECPKPARAMETERS_free(params);
1003-
return NULL;
1002+
goto err;
10041003
}
10051004
if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
10061005
ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
1007-
ECPKPARAMETERS_free(params);
1008-
return NULL;
1006+
goto err;
10091007
}
1010-
if (a && *a)
1008+
1009+
if (a != NULL) {
10111010
EC_GROUP_clear_free(*a);
1012-
if (a)
10131011
*a = group;
1012+
}
10141013

1014+
err:
10151015
ECPKPARAMETERS_free(params);
10161016
return (group);
10171017
}
@@ -1039,7 +1039,6 @@ i2d_ECPKParameters(const EC_GROUP * a, unsigned char **out)
10391039
EC_KEY *
10401040
d2i_ECPrivateKey(EC_KEY ** a, const unsigned char **in, long len)
10411041
{
1042-
int ok = 0;
10431042
EC_KEY *ret = NULL;
10441043
EC_PRIVATEKEY *priv_key = NULL;
10451044

@@ -1054,12 +1053,9 @@ d2i_ECPrivateKey(EC_KEY ** a, const unsigned char **in, long len)
10541053
}
10551054
if (a == NULL || *a == NULL) {
10561055
if ((ret = EC_KEY_new()) == NULL) {
1057-
ECerr(EC_F_D2I_ECPRIVATEKEY,
1058-
ERR_R_MALLOC_FAILURE);
1056+
ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
10591057
goto err;
10601058
}
1061-
if (a)
1062-
*a = ret;
10631059
} else
10641060
ret = *a;
10651061

@@ -1109,17 +1105,19 @@ d2i_ECPrivateKey(EC_KEY ** a, const unsigned char **in, long len)
11091105
goto err;
11101106
}
11111107
}
1112-
ok = 1;
1108+
1109+
EC_PRIVATEKEY_free(priv_key);
1110+
if (a != NULL)
1111+
*a = ret;
1112+
return (ret);
1113+
11131114
err:
1114-
if (!ok) {
1115-
if (ret)
1116-
EC_KEY_free(ret);
1117-
ret = NULL;
1118-
}
1115+
if (a == NULL || *a != ret)
1116+
EC_KEY_free(ret);
11191117
if (priv_key)
11201118
EC_PRIVATEKEY_free(priv_key);
11211119

1122-
return (ret);
1120+
return (NULL);
11231121
}
11241122

11251123
int
@@ -1232,15 +1230,16 @@ d2i_ECParameters(EC_KEY ** a, const unsigned char **in, long len)
12321230
ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
12331231
return NULL;
12341232
}
1235-
if (a)
1236-
*a = ret;
12371233
} else
12381234
ret = *a;
12391235

12401236
if (!d2i_ECPKParameters(&ret->group, in, len)) {
12411237
ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
12421238
return NULL;
12431239
}
1240+
1241+
if (a != NULL)
1242+
*a = ret;
12441243
return ret;
12451244
}
12461245

lib/libssl/src/crypto/pkcs7/pk7_doit.c

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,28 @@ PKCS7_dataInit(PKCS7 *p7, BIO *bio)
261261
PKCS7_RECIP_INFO *ri = NULL;
262262
ASN1_OCTET_STRING *os = NULL;
263263

264+
if (p7 == NULL) {
265+
PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
266+
return NULL;
267+
}
268+
269+
/*
270+
* The content field in the PKCS7 ContentInfo is optional,
271+
* but that really only applies to inner content (precisely,
272+
* detached signatures).
273+
*
274+
* When reading content, missing outer content is therefore
275+
* treated as an error.
276+
*
277+
* When creating content, PKCS7_content_new() must be called
278+
* before calling this method, so a NULL p7->d is always
279+
* an error.
280+
*/
281+
if (p7->d.ptr == NULL) {
282+
PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
283+
return NULL;
284+
}
285+
264286
i = OBJ_obj2nid(p7->type);
265287
p7->state = PKCS7_S_HEADER;
266288

@@ -417,6 +439,17 @@ PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
417439
unsigned char *ek = NULL, *tkey = NULL;
418440
int eklen = 0, tkeylen = 0;
419441

442+
if (p7 == NULL) {
443+
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
444+
PKCS7_R_INVALID_NULL_POINTER);
445+
return NULL;
446+
}
447+
448+
if (p7->d.ptr == NULL) {
449+
PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
450+
return NULL;
451+
}
452+
420453
i = OBJ_obj2nid(p7->type);
421454
p7->state = PKCS7_S_HEADER;
422455

@@ -691,6 +724,17 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
691724
STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
692725
ASN1_OCTET_STRING *os = NULL;
693726

727+
if (p7 == NULL) {
728+
PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
729+
PKCS7_R_INVALID_NULL_POINTER);
730+
return 0;
731+
}
732+
733+
if (p7->d.ptr == NULL) {
734+
PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
735+
return 0;
736+
}
737+
694738
EVP_MD_CTX_init(&ctx_tmp);
695739
i = OBJ_obj2nid(p7->type);
696740
p7->state = PKCS7_S_HEADER;
@@ -736,6 +780,7 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
736780
/* If detached data then the content is excluded */
737781
if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
738782
M_ASN1_OCTET_STRING_free(os);
783+
os = NULL;
739784
p7->d.sign->contents->d.data = NULL;
740785
}
741786
break;
@@ -750,6 +795,7 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
750795
if (PKCS7_type_is_data(p7->d.digest->contents) &&
751796
p7->detached) {
752797
M_ASN1_OCTET_STRING_free(os);
798+
os = NULL;
753799
p7->d.digest->contents->d.data = NULL;
754800
}
755801
break;
@@ -815,22 +861,32 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
815861
M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
816862
}
817863

818-
if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF)) {
819-
char *cont;
820-
long contlen;
821-
btmp = BIO_find_type(bio, BIO_TYPE_MEM);
822-
if (btmp == NULL) {
823-
PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
824-
PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
864+
if (!PKCS7_is_detached(p7)) {
865+
/*
866+
* NOTE: only reach os == NULL here because detached
867+
* digested data support is broken?
868+
*/
869+
if (os == NULL)
825870
goto err;
871+
if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
872+
char *cont;
873+
long contlen;
874+
875+
btmp = BIO_find_type(bio, BIO_TYPE_MEM);
876+
if (btmp == NULL) {
877+
PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
878+
PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
879+
goto err;
880+
}
881+
contlen = BIO_get_mem_data(btmp, &cont);
882+
/*
883+
* Mark the BIO read only then we can use its copy
884+
* of the data instead of making an extra copy.
885+
*/
886+
BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
887+
BIO_set_mem_eof_return(btmp, 0);
888+
ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
826889
}
827-
contlen = BIO_get_mem_data(btmp, &cont);
828-
/* Mark the BIO read only then we can use its copy of the data
829-
* instead of making an extra copy.
830-
*/
831-
BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
832-
BIO_set_mem_eof_return(btmp, 0);
833-
ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
834890
}
835891
ret = 1;
836892
err:
@@ -905,6 +961,17 @@ PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
905961
STACK_OF(X509) *cert;
906962
X509 *x509;
907963

964+
if (p7 == NULL) {
965+
PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
966+
PKCS7_R_INVALID_NULL_POINTER);
967+
return 0;
968+
}
969+
970+
if (p7->d.ptr == NULL) {
971+
PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
972+
return 0;
973+
}
974+
908975
if (PKCS7_type_is_signed(p7)) {
909976
cert = p7->d.sign->cert;
910977
} else if (PKCS7_type_is_signedAndEnveloped(p7)) {
@@ -941,6 +1008,7 @@ PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
9411008

9421009
return PKCS7_signatureVerify(bio, p7, si, x509);
9431010
err:
1011+
9441012
return ret;
9451013
}
9461014

0 commit comments

Comments
 (0)