summaryrefslogtreecommitdiff
blob: facb77d203a1ddf0667b3ea293abf76a56b64fb9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
--- openssl-0.9.8ze/crypto/asn1/a_type.c
+++ openssl-0.9.8ze/crypto/asn1/a_type.c
@@ -121,6 +121,9 @@
 	case V_ASN1_OBJECT:
 		result = OBJ_cmp(a->value.object, b->value.object);
 		break;
+	case V_ASN1_BOOLEAN:
+		result = a->value.boolean - b->value.boolean;
+		break;
 	case V_ASN1_NULL:
 		result = 0;	/* They do not have content. */
 		break;
--- openssl-0.9.8ze/crypto/asn1/tasn_dec.c
+++ openssl-0.9.8ze/crypto/asn1/tasn_dec.c
@@ -128,11 +128,17 @@
 	{
 	ASN1_TLC c;
 	ASN1_VALUE *ptmpval = NULL;
-	if (!pval)
-		pval = &ptmpval;
 	c.valid = 0;
-	if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 
-		return *pval;
+	if (pval && *pval && it->itype == ASN1_ITYPE_PRIMITIVE)
+	    ptmpval = *pval;
+	if (ASN1_item_ex_d2i(&ptmpval, in, len, it, -1, 0, 0, &c) > 0) {
+	    if (pval && it->itype != ASN1_ITYPE_PRIMITIVE) {
+		if (*pval)
+		    ASN1_item_free(*pval, it);
+		*pval = ptmpval;
+	    }
+	    return ptmpval;
+	}
 	return NULL;
 	}
 
@@ -309,9 +315,16 @@
 		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
 				goto auxerr;
 
-		/* Allocate structure */
-		if (!*pval && !ASN1_item_ex_new(pval, it))
-			{
+		if (*pval) {
+		    /* Free up and zero CHOICE value if initialised */
+		    i = asn1_get_choice_selector(pval, it);
+		    if ((i >= 0) && (i < it->tcount)) {
+			tt = it->templates + i;
+			pchptr = asn1_get_field_ptr(pval, tt);
+			ASN1_template_free(pchptr, tt);
+			asn1_set_choice_selector(pval, -1, it);
+		    }
+		} else if (!ASN1_item_ex_new(pval, it)) {
 			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
 						ERR_R_NESTED_ASN1_ERROR);
 			goto err;
@@ -405,6 +418,17 @@
 		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
 				goto auxerr;
 
+		/* Free up and zero any ADB found */
+		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+		    if (tt->flags & ASN1_TFLG_ADB_MASK) {
+			const ASN1_TEMPLATE *seqtt;
+			ASN1_VALUE **pseqval;
+			seqtt = asn1_do_adb(pval, tt, 1);
+			pseqval = asn1_get_field_ptr(pval, seqtt);
+			ASN1_template_free(pseqval, seqtt);
+		    }
+		}
+
 		/* Get each field entry */
 		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
 			{
--- openssl-0.9.8ze/crypto/pkcs7/pk7_doit.c
+++ openssl-0.9.8ze/crypto/pkcs7/pk7_doit.c
@@ -151,6 +151,25 @@
 	EVP_PKEY *pkey;
 	ASN1_OCTET_STRING *os=NULL;
 
+    if (p7 == NULL) {
+	PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
+	return NULL;
+    }
+    /*
+     * The content field in the PKCS7 ContentInfo is optional, but that really
+     * only applies to inner content (precisely, detached signatures).
+     *
+     * When reading content, missing outer content is therefore treated as an
+     * error.
+     *
+     * When creating content, PKCS7_content_new() must be called before
+     * calling this method, so a NULL p7->d is always an error.
+     */
+    if (p7->d.ptr == NULL) {
+	PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
+	return NULL;
+    }
+
 	i=OBJ_obj2nid(p7->type);
 	p7->state=PKCS7_S_HEADER;
 
@@ -344,6 +363,16 @@
 	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
 	PKCS7_RECIP_INFO *ri=NULL;
 
+    if (p7 == NULL) {
+	PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER);
+	return NULL;
+    }
+    
+    if (p7->d.ptr == NULL) {
+	PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+	return NULL;
+    }
+
 	i=OBJ_obj2nid(p7->type);
 	p7->state=PKCS7_S_HEADER;
 
@@ -637,6 +666,16 @@
 	STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
 	ASN1_OCTET_STRING *os=NULL;
 
+    if (p7 == NULL) {
+	PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
+	return 0;
+    }
+
+    if (p7->d.ptr == NULL) {
+	PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
+	return 0;
+    }
+
 	EVP_MD_CTX_init(&ctx_tmp);
 	i=OBJ_obj2nid(p7->type);
 	p7->state=PKCS7_S_HEADER;
@@ -668,6 +707,7 @@
 		/* If detached data then the content is excluded */
 		if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
 			M_ASN1_OCTET_STRING_free(os);
+			os = NULL;
 			p7->d.sign->contents->d.data = NULL;
 		}
 		break;
@@ -678,6 +718,7 @@
 		if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
 			{
 			M_ASN1_OCTET_STRING_free(os);
+			os = NULL;
 			p7->d.digest->contents->d.data = NULL;
 			}
 		break;
@@ -815,6 +856,11 @@
 
 	if (!PKCS7_is_detached(p7))
 		{
+		/*
+		 * NOTE(emilia): I think we only reach os == NULL here because detached
+		 */
+		if (os == NULL)
+		    goto err;
 		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
 		if (btmp == NULL)
 			{
@@ -849,6 +895,16 @@
 	STACK_OF(X509) *cert;
 	X509 *x509;
 
+    if (p7 == NULL) {
+	PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER);
+	return 0;
+    }
+
+    if (p7->d.ptr == NULL) {
+	PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
+	return 0;
+    }
+
 	if (PKCS7_type_is_signed(p7))
 		{
 		cert=p7->d.sign->cert;
--- openssl-0.9.8ze/crypto/pkcs7/pk7_lib.c
+++ openssl-0.9.8ze/crypto/pkcs7/pk7_lib.c
@@ -70,6 +70,7 @@
 
 	switch (cmd)
 		{
+	/* NOTE(emilia): does not support detached digested data. */
 	case PKCS7_OP_SET_DETACHED_SIGNATURE:
 		if (nid == NID_pkcs7_signed)
 			{
@@ -473,6 +474,8 @@
 
 STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
 	{
+	if (p7 == NULL || p7->d.ptr == NULL)
+		return NULL;
 	if (PKCS7_type_is_signed(p7))
 		{
 		return(p7->d.sign->signer_info);
--- openssl-0.9.8ze/doc/crypto/d2i_X509.pod
+++ openssl-0.9.8ze/doc/crypto/d2i_X509.pod
@@ -199,6 +199,12 @@
 persist if they are not present in the new one. As a result the use
 of this "reuse" behaviour is strongly discouraged.
 
+Current versions of OpenSSL will not modify B<*px> if an error occurs.
+If parsing succeeds then B<*px> is freed (if it is not NULL) and then
+set to the value of the newly decoded structure. As a result B<*px>
+B<must not> be allocated on the stack or an attempt will be made to
+free an invalid pointer.
+
 i2d_X509() will not return an error in many versions of OpenSSL,
 if mandatory fields are not initialized due to a programming error
 then the encoded structure may contain invalid data or omit the
@@ -210,7 +216,9 @@
 
 d2i_X509(), d2i_X509_bio() and d2i_X509_fp() return a valid B<X509> structure
 or B<NULL> if an error occurs. The error code that can be obtained by
-L<ERR_get_error(3)|ERR_get_error(3)>. 
+L<ERR_get_error(3)|ERR_get_error(3)>. If the "reuse" capability has been used
+with a valid X509 structure being passed in via B<px> then the object is not
+modified in the event of error.
 
 i2d_X509() returns the number of bytes successfully encoded or a negative
 value if an error occurs. The error code can be obtained by
--- openssl-0.9.8ze/ssl/s2_lib.c
+++ openssl-0.9.8ze/ssl/s2_lib.c
@@ -410,7 +410,7 @@
 
 		OPENSSL_assert(s->session->master_key_length >= 0
 		    && s->session->master_key_length
-		    < (int)sizeof(s->session->master_key));
+		    <= (int)sizeof(s->session->master_key));
 		EVP_DigestUpdate(&ctx,s->session->master_key,s->session->master_key_length);
 		EVP_DigestUpdate(&ctx,&c,1);
 		c++;
--- openssl-0.9.8ze/ssl/s2_srvr.c
+++ openssl-0.9.8ze/ssl/s2_srvr.c
@@ -446,10 +446,6 @@
 		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY);
 		return(-1);
 		}
-	i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc,
-		&(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]),
-		(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
-
 	is_export=SSL_C_IS_EXPORT(s->session->cipher);
 	
 	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
@@ -467,21 +463,59 @@
 	else
 		ek=5;
 
+	/*
+	 * The format of the CLIENT-MASTER-KEY message is
+	 * 1 byte message type
+	 * 3 bytes cipher
+	 * 2-byte clear key length (stored in s->s2->tmp.clear)
+	 * 2-byte encrypted key length (stored in s->s2->tmp.enc)
+	 * 2-byte key args length (IV etc)
+	 * clear key
+	 * encrypted key
+	 * key args
+	 *
+	 * If the cipher is an export cipher, then the encrypted key bytes
+	 * are a fixed portion of the total key (5 or 8 bytes). The size of
+	 * this portion is in |ek|. If the cipher is not an export cipher,
+	 * then the entire key material is encrypted (i.e., clear key length
+	 * must be zero).
+	 */
+	if ((!is_export && s->s2->tmp.clear != 0) ||
+	    (is_export && s->s2->tmp.clear + ek != EVP_CIPHER_key_length(c))) {
+	    ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+	    SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH);
+	    return -1;
+	}
+	/*
+	 * The encrypted blob must decrypt to the encrypted portion of the key.
+	 * Decryption can't be expanding, so if we don't have enough encrypted
+	 * bytes to fit the key in the buffer, stop now.
+	 */
+	if ((is_export && s->s2->tmp.enc < ek) ||
+	    (!is_export && s->s2->tmp.enc < EVP_CIPHER_key_length(c))) {
+	    ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+	    SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT);
+	    return -1;
+	}
+
+	i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc,
+				    &(p[s->s2->tmp.clear]),
+				    &(p[s->s2->tmp.clear]),
+				    (s->s2->ssl2_rollback) ? RSA_SSLV23_PADDING :
+				    RSA_PKCS1_PADDING);
+
 	/* bad decrypt */
 #if 1
 	/* If a bad decrypt, continue with protocol but with a
 	 * random master secret (Bleichenbacher attack) */
-	if ((i < 0) ||
-		((!is_export && (i != EVP_CIPHER_key_length(c)))
-		|| (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i !=
-			(unsigned int)EVP_CIPHER_key_length(c))))))
-		{
+	if ((i < 0) || ((!is_export && i != EVP_CIPHER_key_length(c))
+			|| (is_export && i != ek))) {
 		ERR_clear_error();
 		if (is_export)
 			i=ek;
 		else
 			i=EVP_CIPHER_key_length(c);
-		if (RAND_pseudo_bytes(p,i) <= 0)
+		if (RAND_pseudo_bytes(&p[s->s2->tmp.clear], i) <= 0)
 			return 0;
 		}
 #else
@@ -505,7 +539,8 @@
 		}
 #endif
 
-	if (is_export) i+=s->s2->tmp.clear;
+	if (is_export)
+		i = EVP_CIPHER_key_length(c);
 
 	if (i > SSL_MAX_MASTER_KEY_LENGTH)
 		{