diff options
author | tedu <> | 2014-08-09 16:56:04 +0000 |
---|---|---|
committer | tedu <> | 2014-08-09 16:56:04 +0000 |
commit | 1dd7af2e746703b8d2ee93724205923573237ce8 (patch) | |
tree | 19756b55573afc4ccf4757666b0b38f71c913394 | |
parent | 3041d573373b96f84209a8cfd4306fb3276dc24a (diff) | |
download | openbsd-1dd7af2e746703b8d2ee93724205923573237ce8.tar.gz openbsd-1dd7af2e746703b8d2ee93724205923573237ce8.tar.bz2 openbsd-1dd7af2e746703b8d2ee93724205923573237ce8.zip |
backport relevant security fixes from openssl 1.0.1i
tested by bcook jsg
-rw-r--r-- | src/lib/libssl/src/crypto/asn1/a_object.c | 30 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/ec/ec_lib.c | 2 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/ec/ecp_smpl.c | 174 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/d1_both.c | 82 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/d1_clnt.c | 31 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/d1_srvr.c | 14 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s23_lib.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s23_srvr.c | 30 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_clnt.c | 24 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_enc.c | 12 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_pkt.c | 2 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_srvr.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/ssl_lib.c | 5 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/t1_lib.c | 69 |
14 files changed, 296 insertions, 193 deletions
diff --git a/src/lib/libssl/src/crypto/asn1/a_object.c b/src/lib/libssl/src/crypto/asn1/a_object.c index 3978c9150d..77b2768967 100644 --- a/src/lib/libssl/src/crypto/asn1/a_object.c +++ b/src/lib/libssl/src/crypto/asn1/a_object.c | |||
@@ -283,17 +283,29 @@ err: | |||
283 | ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); | 283 | ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); |
284 | return(NULL); | 284 | return(NULL); |
285 | } | 285 | } |
286 | |||
286 | ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, | 287 | ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, |
287 | long len) | 288 | long len) |
288 | { | 289 | { |
289 | ASN1_OBJECT *ret=NULL; | 290 | ASN1_OBJECT *ret=NULL; |
290 | const unsigned char *p; | 291 | const unsigned char *p; |
291 | unsigned char *data; | 292 | unsigned char *data; |
292 | int i; | 293 | int i, length; |
293 | /* Sanity check OID encoding: can't have leading 0x80 in | 294 | |
294 | * subidentifiers, see: X.690 8.19.2 | 295 | /* Sanity check OID encoding. |
296 | * Need at least one content octet. | ||
297 | * MSB must be clear in the last octet. | ||
298 | * can't have leading 0x80 in subidentifiers, see: X.690 8.19.2 | ||
295 | */ | 299 | */ |
296 | for (i = 0, p = *pp; i < len; i++, p++) | 300 | if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL || |
301 | p[len - 1] & 0x80) | ||
302 | { | ||
303 | ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING); | ||
304 | return NULL; | ||
305 | } | ||
306 | /* Now 0 < len <= INT_MAX, so the cast is safe. */ | ||
307 | length = (int)len; | ||
308 | for (i = 0; i < length; i++, p++) | ||
297 | { | 309 | { |
298 | if (*p == 0x80 && (!i || !(p[-1] & 0x80))) | 310 | if (*p == 0x80 && (!i || !(p[-1] & 0x80))) |
299 | { | 311 | { |
@@ -316,23 +328,23 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, | |||
316 | data = (unsigned char *)ret->data; | 328 | data = (unsigned char *)ret->data; |
317 | ret->data = NULL; | 329 | ret->data = NULL; |
318 | /* once detached we can change it */ | 330 | /* once detached we can change it */ |
319 | if ((data == NULL) || (ret->length < len)) | 331 | if ((data == NULL) || (ret->length < length)) |
320 | { | 332 | { |
321 | ret->length=0; | 333 | ret->length=0; |
322 | if (data != NULL) OPENSSL_free(data); | 334 | if (data != NULL) OPENSSL_free(data); |
323 | data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); | 335 | data=(unsigned char *)OPENSSL_malloc(length); |
324 | if (data == NULL) | 336 | if (data == NULL) |
325 | { i=ERR_R_MALLOC_FAILURE; goto err; } | 337 | { i=ERR_R_MALLOC_FAILURE; goto err; } |
326 | ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; | 338 | ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; |
327 | } | 339 | } |
328 | memcpy(data,p,(int)len); | 340 | memcpy(data,p,length); |
329 | /* reattach data to object, after which it remains const */ | 341 | /* reattach data to object, after which it remains const */ |
330 | ret->data =data; | 342 | ret->data =data; |
331 | ret->length=(int)len; | 343 | ret->length=length; |
332 | ret->sn=NULL; | 344 | ret->sn=NULL; |
333 | ret->ln=NULL; | 345 | ret->ln=NULL; |
334 | /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ | 346 | /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ |
335 | p+=len; | 347 | p+=length; |
336 | 348 | ||
337 | if (a != NULL) (*a)=ret; | 349 | if (a != NULL) (*a)=ret; |
338 | *pp=p; | 350 | *pp=p; |
diff --git a/src/lib/libssl/src/crypto/ec/ec_lib.c b/src/lib/libssl/src/crypto/ec/ec_lib.c index 25247b5803..1474031259 100644 --- a/src/lib/libssl/src/crypto/ec/ec_lib.c +++ b/src/lib/libssl/src/crypto/ec/ec_lib.c | |||
@@ -942,7 +942,7 @@ int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX * | |||
942 | 942 | ||
943 | int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) | 943 | int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) |
944 | { | 944 | { |
945 | if (group->meth->dbl == 0) | 945 | if (group->meth->invert == 0) |
946 | { | 946 | { |
947 | ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | 947 | ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
948 | return 0; | 948 | return 0; |
diff --git a/src/lib/libssl/src/crypto/ec/ecp_smpl.c b/src/lib/libssl/src/crypto/ec/ecp_smpl.c index 7cbb321f9a..ef5285477a 100644 --- a/src/lib/libssl/src/crypto/ec/ecp_smpl.c +++ b/src/lib/libssl/src/crypto/ec/ecp_smpl.c | |||
@@ -1181,9 +1181,8 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ct | |||
1181 | int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) | 1181 | int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) |
1182 | { | 1182 | { |
1183 | BN_CTX *new_ctx = NULL; | 1183 | BN_CTX *new_ctx = NULL; |
1184 | BIGNUM *tmp0, *tmp1; | 1184 | BIGNUM *tmp, *tmp_Z; |
1185 | size_t pow2 = 0; | 1185 | BIGNUM **prod_Z = NULL; |
1186 | BIGNUM **heap = NULL; | ||
1187 | size_t i; | 1186 | size_t i; |
1188 | int ret = 0; | 1187 | int ret = 0; |
1189 | 1188 | ||
@@ -1198,124 +1197,104 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT | |||
1198 | } | 1197 | } |
1199 | 1198 | ||
1200 | BN_CTX_start(ctx); | 1199 | BN_CTX_start(ctx); |
1201 | tmp0 = BN_CTX_get(ctx); | 1200 | tmp = BN_CTX_get(ctx); |
1202 | tmp1 = BN_CTX_get(ctx); | 1201 | tmp_Z = BN_CTX_get(ctx); |
1203 | if (tmp0 == NULL || tmp1 == NULL) goto err; | 1202 | if (tmp == NULL || tmp_Z == NULL) goto err; |
1204 | 1203 | ||
1205 | /* Before converting the individual points, compute inverses of all Z values. | 1204 | prod_Z = OPENSSL_malloc(num * sizeof prod_Z[0]); |
1206 | * Modular inversion is rather slow, but luckily we can do with a single | 1205 | if (prod_Z == NULL) goto err; |
1207 | * explicit inversion, plus about 3 multiplications per input value. | 1206 | for (i = 0; i < num; i++) |
1208 | */ | 1207 | { |
1208 | prod_Z[i] = BN_new(); | ||
1209 | if (prod_Z[i] == NULL) goto err; | ||
1210 | } | ||
1209 | 1211 | ||
1210 | pow2 = 1; | 1212 | /* Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z, |
1211 | while (num > pow2) | 1213 | * skipping any zero-valued inputs (pretend that they're 1). */ |
1212 | pow2 <<= 1; | ||
1213 | /* Now pow2 is the smallest power of 2 satifsying pow2 >= num. | ||
1214 | * We need twice that. */ | ||
1215 | pow2 <<= 1; | ||
1216 | 1214 | ||
1217 | heap = OPENSSL_malloc(pow2 * sizeof heap[0]); | 1215 | if (!BN_is_zero(&points[0]->Z)) |
1218 | if (heap == NULL) goto err; | ||
1219 | |||
1220 | /* The array is used as a binary tree, exactly as in heapsort: | ||
1221 | * | ||
1222 | * heap[1] | ||
1223 | * heap[2] heap[3] | ||
1224 | * heap[4] heap[5] heap[6] heap[7] | ||
1225 | * heap[8]heap[9] heap[10]heap[11] heap[12]heap[13] heap[14] heap[15] | ||
1226 | * | ||
1227 | * We put the Z's in the last line; | ||
1228 | * then we set each other node to the product of its two child-nodes (where | ||
1229 | * empty or 0 entries are treated as ones); | ||
1230 | * then we invert heap[1]; | ||
1231 | * then we invert each other node by replacing it by the product of its | ||
1232 | * parent (after inversion) and its sibling (before inversion). | ||
1233 | */ | ||
1234 | heap[0] = NULL; | ||
1235 | for (i = pow2/2 - 1; i > 0; i--) | ||
1236 | heap[i] = NULL; | ||
1237 | for (i = 0; i < num; i++) | ||
1238 | heap[pow2/2 + i] = &points[i]->Z; | ||
1239 | for (i = pow2/2 + num; i < pow2; i++) | ||
1240 | heap[i] = NULL; | ||
1241 | |||
1242 | /* set each node to the product of its children */ | ||
1243 | for (i = pow2/2 - 1; i > 0; i--) | ||
1244 | { | 1216 | { |
1245 | heap[i] = BN_new(); | 1217 | if (!BN_copy(prod_Z[0], &points[0]->Z)) goto err; |
1246 | if (heap[i] == NULL) goto err; | 1218 | } |
1247 | 1219 | else | |
1248 | if (heap[2*i] != NULL) | 1220 | { |
1221 | if (group->meth->field_set_to_one != 0) | ||
1249 | { | 1222 | { |
1250 | if ((heap[2*i + 1] == NULL) || BN_is_zero(heap[2*i + 1])) | 1223 | if (!group->meth->field_set_to_one(group, prod_Z[0], ctx)) goto err; |
1251 | { | 1224 | } |
1252 | if (!BN_copy(heap[i], heap[2*i])) goto err; | 1225 | else |
1253 | } | 1226 | { |
1254 | else | 1227 | if (!BN_one(prod_Z[0])) goto err; |
1255 | { | ||
1256 | if (BN_is_zero(heap[2*i])) | ||
1257 | { | ||
1258 | if (!BN_copy(heap[i], heap[2*i + 1])) goto err; | ||
1259 | } | ||
1260 | else | ||
1261 | { | ||
1262 | if (!group->meth->field_mul(group, heap[i], | ||
1263 | heap[2*i], heap[2*i + 1], ctx)) goto err; | ||
1264 | } | ||
1265 | } | ||
1266 | } | 1228 | } |
1267 | } | 1229 | } |
1268 | 1230 | ||
1269 | /* invert heap[1] */ | 1231 | for (i = 1; i < num; i++) |
1270 | if (!BN_is_zero(heap[1])) | ||
1271 | { | 1232 | { |
1272 | if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx)) | 1233 | if (!BN_is_zero(&points[i]->Z)) |
1273 | { | 1234 | { |
1274 | ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB); | 1235 | if (!group->meth->field_mul(group, prod_Z[i], prod_Z[i - 1], &points[i]->Z, ctx)) goto err; |
1275 | goto err; | 1236 | } |
1237 | else | ||
1238 | { | ||
1239 | if (!BN_copy(prod_Z[i], prod_Z[i - 1])) goto err; | ||
1276 | } | 1240 | } |
1277 | } | 1241 | } |
1242 | |||
1243 | /* Now use a single explicit inversion to replace every | ||
1244 | * non-zero points[i]->Z by its inverse. */ | ||
1245 | |||
1246 | if (!BN_mod_inverse(tmp, prod_Z[num - 1], &group->field, ctx)) | ||
1247 | { | ||
1248 | ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB); | ||
1249 | goto err; | ||
1250 | } | ||
1278 | if (group->meth->field_encode != 0) | 1251 | if (group->meth->field_encode != 0) |
1279 | { | 1252 | { |
1280 | /* in the Montgomery case, we just turned R*H (representing H) | 1253 | /* In the Montgomery case, we just turned R*H (representing H) |
1281 | * into 1/(R*H), but we need R*(1/H) (representing 1/H); | 1254 | * into 1/(R*H), but we need R*(1/H) (representing 1/H); |
1282 | * i.e. we have need to multiply by the Montgomery factor twice */ | 1255 | * i.e. we need to multiply by the Montgomery factor twice. */ |
1283 | if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err; | 1256 | if (!group->meth->field_encode(group, tmp, tmp, ctx)) goto err; |
1284 | if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err; | 1257 | if (!group->meth->field_encode(group, tmp, tmp, ctx)) goto err; |
1285 | } | 1258 | } |
1286 | 1259 | ||
1287 | /* set other heap[i]'s to their inverses */ | 1260 | for (i = num - 1; i > 0; --i) |
1288 | for (i = 2; i < pow2/2 + num; i += 2) | ||
1289 | { | 1261 | { |
1290 | /* i is even */ | 1262 | /* Loop invariant: tmp is the product of the inverses of |
1291 | if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1])) | 1263 | * points[0]->Z .. points[i]->Z (zero-valued inputs skipped). */ |
1292 | { | 1264 | if (!BN_is_zero(&points[i]->Z)) |
1293 | if (!group->meth->field_mul(group, tmp0, heap[i/2], heap[i + 1], ctx)) goto err; | ||
1294 | if (!group->meth->field_mul(group, tmp1, heap[i/2], heap[i], ctx)) goto err; | ||
1295 | if (!BN_copy(heap[i], tmp0)) goto err; | ||
1296 | if (!BN_copy(heap[i + 1], tmp1)) goto err; | ||
1297 | } | ||
1298 | else | ||
1299 | { | 1265 | { |
1300 | if (!BN_copy(heap[i], heap[i/2])) goto err; | 1266 | /* Set tmp_Z to the inverse of points[i]->Z (as product |
1267 | * of Z inverses 0 .. i, Z values 0 .. i - 1). */ | ||
1268 | if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx)) goto err; | ||
1269 | /* Update tmp to satisfy the loop invariant for i - 1. */ | ||
1270 | if (!group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx)) goto err; | ||
1271 | /* Replace points[i]->Z by its inverse. */ | ||
1272 | if (!BN_copy(&points[i]->Z, tmp_Z)) goto err; | ||
1301 | } | 1273 | } |
1302 | } | 1274 | } |
1303 | 1275 | ||
1304 | /* we have replaced all non-zero Z's by their inverses, now fix up all the points */ | 1276 | if (!BN_is_zero(&points[0]->Z)) |
1277 | { | ||
1278 | /* Replace points[0]->Z by its inverse. */ | ||
1279 | if (!BN_copy(&points[0]->Z, tmp)) goto err; | ||
1280 | } | ||
1281 | |||
1282 | /* Finally, fix up the X and Y coordinates for all points. */ | ||
1283 | |||
1305 | for (i = 0; i < num; i++) | 1284 | for (i = 0; i < num; i++) |
1306 | { | 1285 | { |
1307 | EC_POINT *p = points[i]; | 1286 | EC_POINT *p = points[i]; |
1308 | 1287 | ||
1309 | if (!BN_is_zero(&p->Z)) | 1288 | if (!BN_is_zero(&p->Z)) |
1310 | { | 1289 | { |
1311 | /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */ | 1290 | /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */ |
1312 | 1291 | ||
1313 | if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx)) goto err; | 1292 | if (!group->meth->field_sqr(group, tmp, &p->Z, ctx)) goto err; |
1314 | if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx)) goto err; | 1293 | if (!group->meth->field_mul(group, &p->X, &p->X, tmp, ctx)) goto err; |
1294 | |||
1295 | if (!group->meth->field_mul(group, tmp, tmp, &p->Z, ctx)) goto err; | ||
1296 | if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) goto err; | ||
1315 | 1297 | ||
1316 | if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx)) goto err; | ||
1317 | if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx)) goto err; | ||
1318 | |||
1319 | if (group->meth->field_set_to_one != 0) | 1298 | if (group->meth->field_set_to_one != 0) |
1320 | { | 1299 | { |
1321 | if (!group->meth->field_set_to_one(group, &p->Z, ctx)) goto err; | 1300 | if (!group->meth->field_set_to_one(group, &p->Z, ctx)) goto err; |
@@ -1329,20 +1308,19 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT | |||
1329 | } | 1308 | } |
1330 | 1309 | ||
1331 | ret = 1; | 1310 | ret = 1; |
1332 | 1311 | ||
1333 | err: | 1312 | err: |
1334 | BN_CTX_end(ctx); | 1313 | BN_CTX_end(ctx); |
1335 | if (new_ctx != NULL) | 1314 | if (new_ctx != NULL) |
1336 | BN_CTX_free(new_ctx); | 1315 | BN_CTX_free(new_ctx); |
1337 | if (heap != NULL) | 1316 | if (prod_Z != NULL) |
1338 | { | 1317 | { |
1339 | /* heap[pow2/2] .. heap[pow2-1] have not been allocated locally! */ | 1318 | for (i = 0; i < num; i++) |
1340 | for (i = pow2/2 - 1; i > 0; i--) | ||
1341 | { | 1319 | { |
1342 | if (heap[i] != NULL) | 1320 | if (prod_Z[i] != NULL) |
1343 | BN_clear_free(heap[i]); | 1321 | BN_clear_free(prod_Z[i]); |
1344 | } | 1322 | } |
1345 | OPENSSL_free(heap); | 1323 | OPENSSL_free(prod_Z); |
1346 | } | 1324 | } |
1347 | return ret; | 1325 | return ret; |
1348 | } | 1326 | } |
diff --git a/src/lib/libssl/src/ssl/d1_both.c b/src/lib/libssl/src/ssl/d1_both.c index 0e0afd38be..dd75329461 100644 --- a/src/lib/libssl/src/ssl/d1_both.c +++ b/src/lib/libssl/src/ssl/d1_both.c | |||
@@ -580,29 +580,32 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) | |||
580 | return 0; | 580 | return 0; |
581 | } | 581 | } |
582 | 582 | ||
583 | /* dtls1_max_handshake_message_len returns the maximum number of bytes | ||
584 | * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but may | ||
585 | * be greater if the maximum certificate list size requires it. */ | ||
586 | static unsigned long dtls1_max_handshake_message_len(const SSL *s) | ||
587 | { | ||
588 | unsigned long max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; | ||
589 | if (max_len < (unsigned long)s->max_cert_list) | ||
590 | return s->max_cert_list; | ||
591 | return max_len; | ||
592 | } | ||
583 | 593 | ||
584 | static int | 594 | static int |
585 | dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) | 595 | dtls1_reassemble_fragment(SSL *s, const struct hm_header_st* msg_hdr, int *ok) |
586 | { | 596 | { |
587 | hm_fragment *frag = NULL; | 597 | hm_fragment *frag = NULL; |
588 | pitem *item = NULL; | 598 | pitem *item = NULL; |
589 | int i = -1, is_complete; | 599 | int i = -1, is_complete; |
590 | unsigned char seq64be[8]; | 600 | unsigned char seq64be[8]; |
591 | unsigned long frag_len = msg_hdr->frag_len, max_len; | 601 | unsigned long frag_len = msg_hdr->frag_len; |
592 | 602 | ||
593 | if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) | 603 | if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len || |
604 | msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) | ||
594 | goto err; | 605 | goto err; |
595 | 606 | ||
596 | /* Determine maximum allowed message size. Depends on (user set) | 607 | if (frag_len == 0) |
597 | * maximum certificate length, but 16k is minimum. | 608 | return DTLS1_HM_FRAGMENT_RETRY; |
598 | */ | ||
599 | if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH < s->max_cert_list) | ||
600 | max_len = s->max_cert_list; | ||
601 | else | ||
602 | max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; | ||
603 | |||
604 | if ((msg_hdr->frag_off+frag_len) > max_len) | ||
605 | goto err; | ||
606 | 609 | ||
607 | /* Try to find item in queue */ | 610 | /* Try to find item in queue */ |
608 | memset(seq64be,0,sizeof(seq64be)); | 611 | memset(seq64be,0,sizeof(seq64be)); |
@@ -629,7 +632,8 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) | |||
629 | } | 632 | } |
630 | 633 | ||
631 | /* If message is already reassembled, this must be a | 634 | /* If message is already reassembled, this must be a |
632 | * retransmit and can be dropped. | 635 | * retransmit and can be dropped. In this case item != NULL and so frag |
636 | * does not need to be freed. | ||
633 | */ | 637 | */ |
634 | if (frag->reassembly == NULL) | 638 | if (frag->reassembly == NULL) |
635 | { | 639 | { |
@@ -649,7 +653,9 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) | |||
649 | /* read the body of the fragment (header has already been read */ | 653 | /* read the body of the fragment (header has already been read */ |
650 | i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | 654 | i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, |
651 | frag->fragment + msg_hdr->frag_off,frag_len,0); | 655 | frag->fragment + msg_hdr->frag_off,frag_len,0); |
652 | if (i<=0 || (unsigned long)i!=frag_len) | 656 | if ((unsigned long)i!=frag_len) |
657 | i=-1; | ||
658 | if (i<=0) | ||
653 | goto err; | 659 | goto err; |
654 | 660 | ||
655 | RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, | 661 | RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, |
@@ -666,10 +672,6 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) | |||
666 | 672 | ||
667 | if (item == NULL) | 673 | if (item == NULL) |
668 | { | 674 | { |
669 | memset(seq64be,0,sizeof(seq64be)); | ||
670 | seq64be[6] = (unsigned char)(msg_hdr->seq>>8); | ||
671 | seq64be[7] = (unsigned char)(msg_hdr->seq); | ||
672 | |||
673 | item = pitem_new(seq64be, frag); | 675 | item = pitem_new(seq64be, frag); |
674 | if (item == NULL) | 676 | if (item == NULL) |
675 | { | 677 | { |
@@ -677,21 +679,25 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) | |||
677 | i = -1; | 679 | i = -1; |
678 | } | 680 | } |
679 | 681 | ||
680 | pqueue_insert(s->d1->buffered_messages, item); | 682 | item = pqueue_insert(s->d1->buffered_messages, item); |
683 | /* pqueue_insert fails iff a duplicate item is inserted. | ||
684 | * However, |item| cannot be a duplicate. If it were, | ||
685 | * |pqueue_find|, above, would have returned it and control | ||
686 | * would never have reached this branch. */ | ||
687 | OPENSSL_assert(item != NULL); | ||
681 | } | 688 | } |
682 | 689 | ||
683 | return DTLS1_HM_FRAGMENT_RETRY; | 690 | return DTLS1_HM_FRAGMENT_RETRY; |
684 | 691 | ||
685 | err: | 692 | err: |
686 | if (frag != NULL) dtls1_hm_fragment_free(frag); | 693 | if (frag != NULL && item == NULL) dtls1_hm_fragment_free(frag); |
687 | if (item != NULL) OPENSSL_free(item); | ||
688 | *ok = 0; | 694 | *ok = 0; |
689 | return i; | 695 | return i; |
690 | } | 696 | } |
691 | 697 | ||
692 | 698 | ||
693 | static int | 699 | static int |
694 | dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) | 700 | dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st* msg_hdr, int *ok) |
695 | { | 701 | { |
696 | int i=-1; | 702 | int i=-1; |
697 | hm_fragment *frag = NULL; | 703 | hm_fragment *frag = NULL; |
@@ -711,7 +717,7 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) | |||
711 | /* If we already have an entry and this one is a fragment, | 717 | /* If we already have an entry and this one is a fragment, |
712 | * don't discard it and rather try to reassemble it. | 718 | * don't discard it and rather try to reassemble it. |
713 | */ | 719 | */ |
714 | if (item != NULL && frag_len < msg_hdr->msg_len) | 720 | if (item != NULL && frag_len != msg_hdr->msg_len) |
715 | item = NULL; | 721 | item = NULL; |
716 | 722 | ||
717 | /* Discard the message if sequence number was already there, is | 723 | /* Discard the message if sequence number was already there, is |
@@ -736,9 +742,12 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) | |||
736 | } | 742 | } |
737 | else | 743 | else |
738 | { | 744 | { |
739 | if (frag_len && frag_len < msg_hdr->msg_len) | 745 | if (frag_len != msg_hdr->msg_len) |
740 | return dtls1_reassemble_fragment(s, msg_hdr, ok); | 746 | return dtls1_reassemble_fragment(s, msg_hdr, ok); |
741 | 747 | ||
748 | if (frag_len > dtls1_max_handshake_message_len(s)) | ||
749 | goto err; | ||
750 | |||
742 | frag = dtls1_hm_fragment_new(frag_len, 0); | 751 | frag = dtls1_hm_fragment_new(frag_len, 0); |
743 | if ( frag == NULL) | 752 | if ( frag == NULL) |
744 | goto err; | 753 | goto err; |
@@ -750,26 +759,31 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) | |||
750 | /* read the body of the fragment (header has already been read */ | 759 | /* read the body of the fragment (header has already been read */ |
751 | i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | 760 | i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, |
752 | frag->fragment,frag_len,0); | 761 | frag->fragment,frag_len,0); |
753 | if (i<=0 || (unsigned long)i!=frag_len) | 762 | if ((unsigned long)i!=frag_len) |
763 | i = -1; | ||
764 | if (i<=0) | ||
754 | goto err; | 765 | goto err; |
755 | } | 766 | } |
756 | 767 | ||
757 | memset(seq64be,0,sizeof(seq64be)); | ||
758 | seq64be[6] = (unsigned char)(msg_hdr->seq>>8); | ||
759 | seq64be[7] = (unsigned char)(msg_hdr->seq); | ||
760 | |||
761 | item = pitem_new(seq64be, frag); | 768 | item = pitem_new(seq64be, frag); |
762 | if ( item == NULL) | 769 | if ( item == NULL) |
763 | goto err; | 770 | goto err; |
764 | 771 | ||
765 | pqueue_insert(s->d1->buffered_messages, item); | 772 | item = pqueue_insert(s->d1->buffered_messages, item); |
773 | /* pqueue_insert fails iff a duplicate item is inserted. | ||
774 | * However, |item| cannot be a duplicate. If it were, | ||
775 | * |pqueue_find|, above, would have returned it. Then, either | ||
776 | * |frag_len| != |msg_hdr->msg_len| in which case |item| is set | ||
777 | * to NULL and it will have been processed with | ||
778 | * |dtls1_reassemble_fragment|, above, or the record will have | ||
779 | * been discarded. */ | ||
780 | OPENSSL_assert(item != NULL); | ||
766 | } | 781 | } |
767 | 782 | ||
768 | return DTLS1_HM_FRAGMENT_RETRY; | 783 | return DTLS1_HM_FRAGMENT_RETRY; |
769 | 784 | ||
770 | err: | 785 | err: |
771 | if ( frag != NULL) dtls1_hm_fragment_free(frag); | 786 | if (frag != NULL && item == NULL) dtls1_hm_fragment_free(frag); |
772 | if ( item != NULL) OPENSSL_free(item); | ||
773 | *ok = 0; | 787 | *ok = 0; |
774 | return i; | 788 | return i; |
775 | } | 789 | } |
@@ -1170,6 +1184,8 @@ dtls1_buffer_message(SSL *s, int is_ccs) | |||
1170 | OPENSSL_assert(s->init_off == 0); | 1184 | OPENSSL_assert(s->init_off == 0); |
1171 | 1185 | ||
1172 | frag = dtls1_hm_fragment_new(s->init_num, 0); | 1186 | frag = dtls1_hm_fragment_new(s->init_num, 0); |
1187 | if (!frag) | ||
1188 | return 0; | ||
1173 | 1189 | ||
1174 | memcpy(frag->fragment, s->init_buf->data, s->init_num); | 1190 | memcpy(frag->fragment, s->init_buf->data, s->init_num); |
1175 | 1191 | ||
diff --git a/src/lib/libssl/src/ssl/d1_clnt.c b/src/lib/libssl/src/ssl/d1_clnt.c index a6ed09c51d..d428f70a24 100644 --- a/src/lib/libssl/src/ssl/d1_clnt.c +++ b/src/lib/libssl/src/ssl/d1_clnt.c | |||
@@ -868,12 +868,18 @@ int dtls1_client_hello(SSL *s) | |||
868 | *(p++)=0; /* Add the NULL method */ | 868 | *(p++)=0; /* Add the NULL method */ |
869 | 869 | ||
870 | #ifndef OPENSSL_NO_TLSEXT | 870 | #ifndef OPENSSL_NO_TLSEXT |
871 | /* TLS extensions*/ | ||
872 | if (ssl_prepare_clienthello_tlsext(s) <= 0) | ||
873 | { | ||
874 | SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); | ||
875 | goto err; | ||
876 | } | ||
871 | if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) | 877 | if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) |
872 | { | 878 | { |
873 | SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); | 879 | SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); |
874 | goto err; | 880 | goto err; |
875 | } | 881 | } |
876 | #endif | 882 | #endif |
877 | 883 | ||
878 | l=(p-d); | 884 | l=(p-d); |
879 | d=buf; | 885 | d=buf; |
@@ -982,6 +988,13 @@ int dtls1_send_client_key_exchange(SSL *s) | |||
982 | RSA *rsa; | 988 | RSA *rsa; |
983 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; | 989 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; |
984 | 990 | ||
991 | if (s->session->sess_cert == NULL) | ||
992 | { | ||
993 | /* We should always have a server certificate with SSL_kRSA. */ | ||
994 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); | ||
995 | goto err; | ||
996 | } | ||
997 | |||
985 | if (s->session->sess_cert->peer_rsa_tmp != NULL) | 998 | if (s->session->sess_cert->peer_rsa_tmp != NULL) |
986 | rsa=s->session->sess_cert->peer_rsa_tmp; | 999 | rsa=s->session->sess_cert->peer_rsa_tmp; |
987 | else | 1000 | else |
@@ -1172,6 +1185,13 @@ int dtls1_send_client_key_exchange(SSL *s) | |||
1172 | { | 1185 | { |
1173 | DH *dh_srvr,*dh_clnt; | 1186 | DH *dh_srvr,*dh_clnt; |
1174 | 1187 | ||
1188 | if (s->session->sess_cert == NULL) | ||
1189 | { | ||
1190 | ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); | ||
1191 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); | ||
1192 | goto err; | ||
1193 | } | ||
1194 | |||
1175 | if (s->session->sess_cert->peer_dh_tmp != NULL) | 1195 | if (s->session->sess_cert->peer_dh_tmp != NULL) |
1176 | dh_srvr=s->session->sess_cert->peer_dh_tmp; | 1196 | dh_srvr=s->session->sess_cert->peer_dh_tmp; |
1177 | else | 1197 | else |
@@ -1231,6 +1251,13 @@ int dtls1_send_client_key_exchange(SSL *s) | |||
1231 | int ecdh_clnt_cert = 0; | 1251 | int ecdh_clnt_cert = 0; |
1232 | int field_size = 0; | 1252 | int field_size = 0; |
1233 | 1253 | ||
1254 | if (s->session->sess_cert == NULL) | ||
1255 | { | ||
1256 | ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); | ||
1257 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); | ||
1258 | goto err; | ||
1259 | } | ||
1260 | |||
1234 | /* Did we send out the client's | 1261 | /* Did we send out the client's |
1235 | * ECDH share for use in premaster | 1262 | * ECDH share for use in premaster |
1236 | * computation as part of client certificate? | 1263 | * computation as part of client certificate? |
@@ -1706,5 +1733,3 @@ int dtls1_send_client_certificate(SSL *s) | |||
1706 | /* SSL3_ST_CW_CERT_D */ | 1733 | /* SSL3_ST_CW_CERT_D */ |
1707 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | 1734 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); |
1708 | } | 1735 | } |
1709 | |||
1710 | |||
diff --git a/src/lib/libssl/src/ssl/d1_srvr.c b/src/lib/libssl/src/ssl/d1_srvr.c index 29421da9aa..c7765847c6 100644 --- a/src/lib/libssl/src/ssl/d1_srvr.c +++ b/src/lib/libssl/src/ssl/d1_srvr.c | |||
@@ -597,10 +597,11 @@ int dtls1_accept(SSL *s) | |||
597 | s->state = SSL3_ST_SR_CLNT_HELLO_C; | 597 | s->state = SSL3_ST_SR_CLNT_HELLO_C; |
598 | } | 598 | } |
599 | else { | 599 | else { |
600 | /* could be sent for a DH cert, even if we | 600 | if (s->s3->tmp.cert_request) |
601 | * have not asked for it :-) */ | 601 | { |
602 | ret=ssl3_get_client_certificate(s); | 602 | ret=ssl3_get_client_certificate(s); |
603 | if (ret <= 0) goto end; | 603 | if (ret <= 0) goto end; |
604 | } | ||
604 | s->init_num=0; | 605 | s->init_num=0; |
605 | s->state=SSL3_ST_SR_KEY_EXCH_A; | 606 | s->state=SSL3_ST_SR_KEY_EXCH_A; |
606 | } | 607 | } |
@@ -969,6 +970,11 @@ int dtls1_send_server_hello(SSL *s) | |||
969 | #endif | 970 | #endif |
970 | 971 | ||
971 | #ifndef OPENSSL_NO_TLSEXT | 972 | #ifndef OPENSSL_NO_TLSEXT |
973 | if (ssl_prepare_serverhello_tlsext(s) <= 0) | ||
974 | { | ||
975 | SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT); | ||
976 | return -1; | ||
977 | } | ||
972 | if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) | 978 | if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) |
973 | { | 979 | { |
974 | SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); | 980 | SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); |
diff --git a/src/lib/libssl/src/ssl/s23_lib.c b/src/lib/libssl/src/ssl/s23_lib.c index 3bf728318a..f3c29d1dde 100644 --- a/src/lib/libssl/src/ssl/s23_lib.c +++ b/src/lib/libssl/src/ssl/s23_lib.c | |||
@@ -107,6 +107,13 @@ int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) | |||
107 | long l; | 107 | long l; |
108 | 108 | ||
109 | /* We can write SSLv2 and SSLv3 ciphers */ | 109 | /* We can write SSLv2 and SSLv3 ciphers */ |
110 | /* but no ECC ciphers */ | ||
111 | if (c->algorithm_mkey == SSL_kECDHr || | ||
112 | c->algorithm_mkey == SSL_kECDHe || | ||
113 | c->algorithm_mkey == SSL_kEECDH || | ||
114 | c->algorithm_auth == SSL_aECDH || | ||
115 | c->algorithm_auth == SSL_aECDSA) | ||
116 | return 0; | ||
110 | if (p != NULL) | 117 | if (p != NULL) |
111 | { | 118 | { |
112 | l=c->id; | 119 | l=c->id; |
diff --git a/src/lib/libssl/src/ssl/s23_srvr.c b/src/lib/libssl/src/ssl/s23_srvr.c index 4877849013..2901a6bd01 100644 --- a/src/lib/libssl/src/ssl/s23_srvr.c +++ b/src/lib/libssl/src/ssl/s23_srvr.c | |||
@@ -348,23 +348,19 @@ int ssl23_get_client_hello(SSL *s) | |||
348 | * Client Hello message, this would be difficult, and we'd have | 348 | * Client Hello message, this would be difficult, and we'd have |
349 | * to read more records to find out. | 349 | * to read more records to find out. |
350 | * No known SSL 3.0 client fragments ClientHello like this, | 350 | * No known SSL 3.0 client fragments ClientHello like this, |
351 | * so we simply assume TLS 1.0 to avoid protocol version downgrade | 351 | * so we simply reject such connections to avoid |
352 | * attacks. */ | 352 | * protocol version downgrade attacks. */ |
353 | if (p[3] == 0 && p[4] < 6) | 353 | if (p[3] == 0 && p[4] < 6) |
354 | { | 354 | { |
355 | #if 0 | ||
356 | SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL); | 355 | SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL); |
357 | goto err; | 356 | goto err; |
358 | #else | ||
359 | v[1] = TLS1_VERSION_MINOR; | ||
360 | #endif | ||
361 | } | 357 | } |
362 | /* if major version number > 3 set minor to a value | 358 | /* if major version number > 3 set minor to a value |
363 | * which will use the highest version 3 we support. | 359 | * which will use the highest version 3 we support. |
364 | * If TLS 2.0 ever appears we will need to revise | 360 | * If TLS 2.0 ever appears we will need to revise |
365 | * this.... | 361 | * this.... |
366 | */ | 362 | */ |
367 | else if (p[9] > SSL3_VERSION_MAJOR) | 363 | if (p[9] > SSL3_VERSION_MAJOR) |
368 | v[1]=0xff; | 364 | v[1]=0xff; |
369 | else | 365 | else |
370 | v[1]=p[10]; /* minor version according to client_version */ | 366 | v[1]=p[10]; /* minor version according to client_version */ |
@@ -444,14 +440,34 @@ int ssl23_get_client_hello(SSL *s) | |||
444 | v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ | 440 | v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ |
445 | v[1] = p[4]; | 441 | v[1] = p[4]; |
446 | 442 | ||
443 | /* An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 | ||
444 | * header is sent directly on the wire, not wrapped as a TLS | ||
445 | * record. It's format is: | ||
446 | * Byte Content | ||
447 | * 0-1 msg_length | ||
448 | * 2 msg_type | ||
449 | * 3-4 version | ||
450 | * 5-6 cipher_spec_length | ||
451 | * 7-8 session_id_length | ||
452 | * 9-10 challenge_length | ||
453 | * ... ... | ||
454 | */ | ||
447 | n=((p[0]&0x7f)<<8)|p[1]; | 455 | n=((p[0]&0x7f)<<8)|p[1]; |
448 | if (n > (1024*4)) | 456 | if (n > (1024*4)) |
449 | { | 457 | { |
450 | SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE); | 458 | SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE); |
451 | goto err; | 459 | goto err; |
452 | } | 460 | } |
461 | if (n < 9) | ||
462 | { | ||
463 | SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH); | ||
464 | goto err; | ||
465 | } | ||
453 | 466 | ||
454 | j=ssl23_read_bytes(s,n+2); | 467 | j=ssl23_read_bytes(s,n+2); |
468 | /* We previously read 11 bytes, so if j > 0, we must have | ||
469 | * j == n+2 == s->packet_length. We have at least 11 valid | ||
470 | * packet bytes. */ | ||
455 | if (j <= 0) return(j); | 471 | if (j <= 0) return(j); |
456 | 472 | ||
457 | ssl3_finish_mac(s, s->packet+2, s->packet_length-2); | 473 | ssl3_finish_mac(s, s->packet+2, s->packet_length-2); |
diff --git a/src/lib/libssl/src/ssl/s3_clnt.c b/src/lib/libssl/src/ssl/s3_clnt.c index 18a4bdaf21..516202f12f 100644 --- a/src/lib/libssl/src/ssl/s3_clnt.c +++ b/src/lib/libssl/src/ssl/s3_clnt.c | |||
@@ -511,6 +511,7 @@ int ssl3_connect(SSL *s) | |||
511 | s->method->ssl3_enc->client_finished_label, | 511 | s->method->ssl3_enc->client_finished_label, |
512 | s->method->ssl3_enc->client_finished_label_len); | 512 | s->method->ssl3_enc->client_finished_label_len); |
513 | if (ret <= 0) goto end; | 513 | if (ret <= 0) goto end; |
514 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | ||
514 | s->state=SSL3_ST_CW_FLUSH; | 515 | s->state=SSL3_ST_CW_FLUSH; |
515 | 516 | ||
516 | /* clear flags */ | 517 | /* clear flags */ |
@@ -902,6 +903,7 @@ int ssl3_get_server_hello(SSL *s) | |||
902 | { | 903 | { |
903 | s->session->cipher = pref_cipher ? | 904 | s->session->cipher = pref_cipher ? |
904 | pref_cipher : ssl_get_cipher_by_char(s, p+j); | 905 | pref_cipher : ssl_get_cipher_by_char(s, p+j); |
906 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | ||
905 | } | 907 | } |
906 | } | 908 | } |
907 | #endif /* OPENSSL_NO_TLSEXT */ | 909 | #endif /* OPENSSL_NO_TLSEXT */ |
@@ -953,6 +955,15 @@ int ssl3_get_server_hello(SSL *s) | |||
953 | SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED); | 955 | SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED); |
954 | goto f_err; | 956 | goto f_err; |
955 | } | 957 | } |
958 | #ifndef OPENSSL_NO_SRP | ||
959 | if (((c->algorithm_mkey & SSL_kSRP) || (c->algorithm_auth & SSL_aSRP)) && | ||
960 | !(s->srp_ctx.srp_Mask & SSL_kSRP)) | ||
961 | { | ||
962 | al=SSL_AD_ILLEGAL_PARAMETER; | ||
963 | SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED); | ||
964 | goto f_err; | ||
965 | } | ||
966 | #endif /* OPENSSL_NO_SRP */ | ||
956 | p+=ssl_put_cipher_by_char(s,NULL,NULL); | 967 | p+=ssl_put_cipher_by_char(s,NULL,NULL); |
957 | 968 | ||
958 | sk=ssl_get_ciphers_by_id(s); | 969 | sk=ssl_get_ciphers_by_id(s); |
@@ -1456,6 +1467,12 @@ int ssl3_get_key_exchange(SSL *s) | |||
1456 | p+=i; | 1467 | p+=i; |
1457 | n-=param_len; | 1468 | n-=param_len; |
1458 | 1469 | ||
1470 | if (!srp_verify_server_param(s, &al)) | ||
1471 | { | ||
1472 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_CIPHER_RETURNED); | ||
1473 | goto f_err; | ||
1474 | } | ||
1475 | |||
1459 | /* We must check if there is a certificate */ | 1476 | /* We must check if there is a certificate */ |
1460 | #ifndef OPENSSL_NO_RSA | 1477 | #ifndef OPENSSL_NO_RSA |
1461 | if (alg_a & SSL_aRSA) | 1478 | if (alg_a & SSL_aRSA) |
@@ -2249,6 +2266,13 @@ int ssl3_send_client_key_exchange(SSL *s) | |||
2249 | RSA *rsa; | 2266 | RSA *rsa; |
2250 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; | 2267 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; |
2251 | 2268 | ||
2269 | if (s->session->sess_cert == NULL) | ||
2270 | { | ||
2271 | /* We should always have a server certificate with SSL_kRSA. */ | ||
2272 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); | ||
2273 | goto err; | ||
2274 | } | ||
2275 | |||
2252 | if (s->session->sess_cert->peer_rsa_tmp != NULL) | 2276 | if (s->session->sess_cert->peer_rsa_tmp != NULL) |
2253 | rsa=s->session->sess_cert->peer_rsa_tmp; | 2277 | rsa=s->session->sess_cert->peer_rsa_tmp; |
2254 | else | 2278 | else |
diff --git a/src/lib/libssl/src/ssl/s3_enc.c b/src/lib/libssl/src/ssl/s3_enc.c index e3cd4f062c..996267725e 100644 --- a/src/lib/libssl/src/ssl/s3_enc.c +++ b/src/lib/libssl/src/ssl/s3_enc.c | |||
@@ -642,10 +642,18 @@ int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p) | |||
642 | int ssl3_final_finish_mac(SSL *s, | 642 | int ssl3_final_finish_mac(SSL *s, |
643 | const char *sender, int len, unsigned char *p) | 643 | const char *sender, int len, unsigned char *p) |
644 | { | 644 | { |
645 | int ret; | 645 | int ret, sha1len; |
646 | ret=ssl3_handshake_mac(s,NID_md5,sender,len,p); | 646 | ret=ssl3_handshake_mac(s,NID_md5,sender,len,p); |
647 | if(ret == 0) | ||
648 | return 0; | ||
649 | |||
647 | p+=ret; | 650 | p+=ret; |
648 | ret+=ssl3_handshake_mac(s,NID_sha1,sender,len,p); | 651 | |
652 | sha1len=ssl3_handshake_mac(s,NID_sha1,sender,len,p); | ||
653 | if(sha1len == 0) | ||
654 | return 0; | ||
655 | |||
656 | ret+=sha1len; | ||
649 | return(ret); | 657 | return(ret); |
650 | } | 658 | } |
651 | static int ssl3_handshake_mac(SSL *s, int md_nid, | 659 | static int ssl3_handshake_mac(SSL *s, int md_nid, |
diff --git a/src/lib/libssl/src/ssl/s3_pkt.c b/src/lib/libssl/src/ssl/s3_pkt.c index 9da0c2ca81..2cb7049c3d 100644 --- a/src/lib/libssl/src/ssl/s3_pkt.c +++ b/src/lib/libssl/src/ssl/s3_pkt.c | |||
@@ -952,7 +952,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
952 | if (!ssl3_setup_read_buffer(s)) | 952 | if (!ssl3_setup_read_buffer(s)) |
953 | return(-1); | 953 | return(-1); |
954 | 954 | ||
955 | if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE) && type) || | 955 | if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE)) || |
956 | (peek && (type != SSL3_RT_APPLICATION_DATA))) | 956 | (peek && (type != SSL3_RT_APPLICATION_DATA))) |
957 | { | 957 | { |
958 | SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); | 958 | SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); |
diff --git a/src/lib/libssl/src/ssl/s3_srvr.c b/src/lib/libssl/src/ssl/s3_srvr.c index 673ced236e..7401e0b24a 100644 --- a/src/lib/libssl/src/ssl/s3_srvr.c +++ b/src/lib/libssl/src/ssl/s3_srvr.c | |||
@@ -2781,6 +2781,13 @@ int ssl3_get_client_key_exchange(SSL *s) | |||
2781 | SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB); | 2781 | SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB); |
2782 | goto err; | 2782 | goto err; |
2783 | } | 2783 | } |
2784 | if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0 | ||
2785 | || BN_is_zero(s->srp_ctx.A)) | ||
2786 | { | ||
2787 | al=SSL_AD_ILLEGAL_PARAMETER; | ||
2788 | SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_WRONG_CIPHER_RETURNED); | ||
2789 | goto f_err; | ||
2790 | } | ||
2784 | if (s->session->srp_username != NULL) | 2791 | if (s->session->srp_username != NULL) |
2785 | OPENSSL_free(s->session->srp_username); | 2792 | OPENSSL_free(s->session->srp_username); |
2786 | s->session->srp_username = BUF_strdup(s->srp_ctx.login); | 2793 | s->session->srp_username = BUF_strdup(s->srp_ctx.login); |
diff --git a/src/lib/libssl/src/ssl/ssl_lib.c b/src/lib/libssl/src/ssl/ssl_lib.c index c91f0018e4..ab9cdd1ac2 100644 --- a/src/lib/libssl/src/ssl/ssl_lib.c +++ b/src/lib/libssl/src/ssl/ssl_lib.c | |||
@@ -1397,6 +1397,11 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, | |||
1397 | s->psk_client_callback == NULL) | 1397 | s->psk_client_callback == NULL) |
1398 | continue; | 1398 | continue; |
1399 | #endif /* OPENSSL_NO_PSK */ | 1399 | #endif /* OPENSSL_NO_PSK */ |
1400 | #ifndef OPENSSL_NO_SRP | ||
1401 | if (((c->algorithm_mkey & SSL_kSRP) || (c->algorithm_auth & SSL_aSRP)) && | ||
1402 | !(s->srp_ctx.srp_Mask & SSL_kSRP)) | ||
1403 | continue; | ||
1404 | #endif /* OPENSSL_NO_SRP */ | ||
1400 | j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p); | 1405 | j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p); |
1401 | p+=j; | 1406 | p+=j; |
1402 | } | 1407 | } |
diff --git a/src/lib/libssl/src/ssl/t1_lib.c b/src/lib/libssl/src/ssl/t1_lib.c index a649dafba9..1cf17cce0d 100644 --- a/src/lib/libssl/src/ssl/t1_lib.c +++ b/src/lib/libssl/src/ssl/t1_lib.c | |||
@@ -360,15 +360,16 @@ int tls12_get_req_sig_algs(SSL *s, unsigned char *p) | |||
360 | return (int)slen; | 360 | return (int)slen; |
361 | } | 361 | } |
362 | 362 | ||
363 | unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | 363 | unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit) |
364 | { | 364 | { |
365 | int extdatalen=0; | 365 | int extdatalen=0; |
366 | unsigned char *ret = p; | 366 | unsigned char *orig = buf; |
367 | unsigned char *ret = buf; | ||
367 | 368 | ||
368 | /* don't add extensions for SSLv3 unless doing secure renegotiation */ | 369 | /* don't add extensions for SSLv3 unless doing secure renegotiation */ |
369 | if (s->client_version == SSL3_VERSION | 370 | if (s->client_version == SSL3_VERSION |
370 | && !s->s3->send_connection_binding) | 371 | && !s->s3->send_connection_binding) |
371 | return p; | 372 | return orig; |
372 | 373 | ||
373 | ret+=2; | 374 | ret+=2; |
374 | 375 | ||
@@ -417,7 +418,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
417 | return NULL; | 418 | return NULL; |
418 | } | 419 | } |
419 | 420 | ||
420 | if((limit - p - 4 - el) < 0) return NULL; | 421 | if((limit - ret - 4 - el) < 0) return NULL; |
421 | 422 | ||
422 | s2n(TLSEXT_TYPE_renegotiate,ret); | 423 | s2n(TLSEXT_TYPE_renegotiate,ret); |
423 | s2n(el,ret); | 424 | s2n(el,ret); |
@@ -460,8 +461,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
460 | #endif | 461 | #endif |
461 | 462 | ||
462 | #ifndef OPENSSL_NO_EC | 463 | #ifndef OPENSSL_NO_EC |
463 | if (s->tlsext_ecpointformatlist != NULL && | 464 | if (s->tlsext_ecpointformatlist != NULL) |
464 | s->version != DTLS1_VERSION) | ||
465 | { | 465 | { |
466 | /* Add TLS extension ECPointFormats to the ClientHello message */ | 466 | /* Add TLS extension ECPointFormats to the ClientHello message */ |
467 | long lenmax; | 467 | long lenmax; |
@@ -480,8 +480,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
480 | memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length); | 480 | memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length); |
481 | ret+=s->tlsext_ecpointformatlist_length; | 481 | ret+=s->tlsext_ecpointformatlist_length; |
482 | } | 482 | } |
483 | if (s->tlsext_ellipticcurvelist != NULL && | 483 | if (s->tlsext_ellipticcurvelist != NULL) |
484 | s->version != DTLS1_VERSION) | ||
485 | { | 484 | { |
486 | /* Add TLS extension EllipticCurves to the ClientHello message */ | 485 | /* Add TLS extension EllipticCurves to the ClientHello message */ |
487 | long lenmax; | 486 | long lenmax; |
@@ -655,7 +654,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
655 | 654 | ||
656 | ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0); | 655 | ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0); |
657 | 656 | ||
658 | if((limit - p - 4 - el) < 0) return NULL; | 657 | if((limit - ret - 4 - el) < 0) return NULL; |
659 | 658 | ||
660 | s2n(TLSEXT_TYPE_use_srtp,ret); | 659 | s2n(TLSEXT_TYPE_use_srtp,ret); |
661 | s2n(el,ret); | 660 | s2n(el,ret); |
@@ -668,24 +667,25 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
668 | ret += el; | 667 | ret += el; |
669 | } | 668 | } |
670 | 669 | ||
671 | if ((extdatalen = ret-p-2)== 0) | 670 | if ((extdatalen = ret-orig-2)== 0) |
672 | return p; | 671 | return orig; |
673 | 672 | ||
674 | s2n(extdatalen,p); | 673 | s2n(extdatalen, orig); |
675 | return ret; | 674 | return ret; |
676 | } | 675 | } |
677 | 676 | ||
678 | unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | 677 | unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit) |
679 | { | 678 | { |
680 | int extdatalen=0; | 679 | int extdatalen=0; |
681 | unsigned char *ret = p; | 680 | unsigned char *orig = buf; |
681 | unsigned char *ret = buf; | ||
682 | #ifndef OPENSSL_NO_NEXTPROTONEG | 682 | #ifndef OPENSSL_NO_NEXTPROTONEG |
683 | int next_proto_neg_seen; | 683 | int next_proto_neg_seen; |
684 | #endif | 684 | #endif |
685 | 685 | ||
686 | /* don't add extensions for SSLv3, unless doing secure renegotiation */ | 686 | /* don't add extensions for SSLv3, unless doing secure renegotiation */ |
687 | if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) | 687 | if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) |
688 | return p; | 688 | return orig; |
689 | 689 | ||
690 | ret+=2; | 690 | ret+=2; |
691 | if (ret>=limit) return NULL; /* this really never occurs, but ... */ | 691 | if (ret>=limit) return NULL; /* this really never occurs, but ... */ |
@@ -708,7 +708,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
708 | return NULL; | 708 | return NULL; |
709 | } | 709 | } |
710 | 710 | ||
711 | if((limit - p - 4 - el) < 0) return NULL; | 711 | if((limit - ret - 4 - el) < 0) return NULL; |
712 | 712 | ||
713 | s2n(TLSEXT_TYPE_renegotiate,ret); | 713 | s2n(TLSEXT_TYPE_renegotiate,ret); |
714 | s2n(el,ret); | 714 | s2n(el,ret); |
@@ -723,8 +723,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
723 | } | 723 | } |
724 | 724 | ||
725 | #ifndef OPENSSL_NO_EC | 725 | #ifndef OPENSSL_NO_EC |
726 | if (s->tlsext_ecpointformatlist != NULL && | 726 | if (s->tlsext_ecpointformatlist != NULL) |
727 | s->version != DTLS1_VERSION) | ||
728 | { | 727 | { |
729 | /* Add TLS extension ECPointFormats to the ServerHello message */ | 728 | /* Add TLS extension ECPointFormats to the ServerHello message */ |
730 | long lenmax; | 729 | long lenmax; |
@@ -787,7 +786,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
787 | 786 | ||
788 | ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0); | 787 | ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0); |
789 | 788 | ||
790 | if((limit - p - 4 - el) < 0) return NULL; | 789 | if((limit - ret - 4 - el) < 0) return NULL; |
791 | 790 | ||
792 | s2n(TLSEXT_TYPE_use_srtp,ret); | 791 | s2n(TLSEXT_TYPE_use_srtp,ret); |
793 | s2n(el,ret); | 792 | s2n(el,ret); |
@@ -855,10 +854,10 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
855 | } | 854 | } |
856 | #endif | 855 | #endif |
857 | 856 | ||
858 | if ((extdatalen = ret-p-2)== 0) | 857 | if ((extdatalen = ret-orig-2)== 0) |
859 | return p; | 858 | return orig; |
860 | 859 | ||
861 | s2n(extdatalen,p); | 860 | s2n(extdatalen, orig); |
862 | return ret; | 861 | return ret; |
863 | } | 862 | } |
864 | 863 | ||
@@ -1035,8 +1034,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in | |||
1035 | #endif | 1034 | #endif |
1036 | 1035 | ||
1037 | #ifndef OPENSSL_NO_EC | 1036 | #ifndef OPENSSL_NO_EC |
1038 | else if (type == TLSEXT_TYPE_ec_point_formats && | 1037 | else if (type == TLSEXT_TYPE_ec_point_formats) |
1039 | s->version != DTLS1_VERSION) | ||
1040 | { | 1038 | { |
1041 | unsigned char *sdata = data; | 1039 | unsigned char *sdata = data; |
1042 | int ecpointformatlist_length = *(sdata++); | 1040 | int ecpointformatlist_length = *(sdata++); |
@@ -1070,8 +1068,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in | |||
1070 | fprintf(stderr,"\n"); | 1068 | fprintf(stderr,"\n"); |
1071 | #endif | 1069 | #endif |
1072 | } | 1070 | } |
1073 | else if (type == TLSEXT_TYPE_elliptic_curves && | 1071 | else if (type == TLSEXT_TYPE_elliptic_curves) |
1074 | s->version != DTLS1_VERSION) | ||
1075 | { | 1072 | { |
1076 | unsigned char *sdata = data; | 1073 | unsigned char *sdata = data; |
1077 | int ellipticcurvelist_length = (*(sdata++) << 8); | 1074 | int ellipticcurvelist_length = (*(sdata++) << 8); |
@@ -1427,8 +1424,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in | |||
1427 | } | 1424 | } |
1428 | 1425 | ||
1429 | #ifndef OPENSSL_NO_EC | 1426 | #ifndef OPENSSL_NO_EC |
1430 | else if (type == TLSEXT_TYPE_ec_point_formats && | 1427 | else if (type == TLSEXT_TYPE_ec_point_formats) |
1431 | s->version != DTLS1_VERSION) | ||
1432 | { | 1428 | { |
1433 | unsigned char *sdata = data; | 1429 | unsigned char *sdata = data; |
1434 | int ecpointformatlist_length = *(sdata++); | 1430 | int ecpointformatlist_length = *(sdata++); |
@@ -1438,15 +1434,18 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in | |||
1438 | *al = TLS1_AD_DECODE_ERROR; | 1434 | *al = TLS1_AD_DECODE_ERROR; |
1439 | return 0; | 1435 | return 0; |
1440 | } | 1436 | } |
1441 | s->session->tlsext_ecpointformatlist_length = 0; | 1437 | if (!s->hit) |
1442 | if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist); | ||
1443 | if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL) | ||
1444 | { | 1438 | { |
1445 | *al = TLS1_AD_INTERNAL_ERROR; | 1439 | s->session->tlsext_ecpointformatlist_length = 0; |
1446 | return 0; | 1440 | if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist); |
1441 | if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL) | ||
1442 | { | ||
1443 | *al = TLS1_AD_INTERNAL_ERROR; | ||
1444 | return 0; | ||
1445 | } | ||
1446 | s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; | ||
1447 | memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); | ||
1447 | } | 1448 | } |
1448 | s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; | ||
1449 | memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); | ||
1450 | #if 0 | 1449 | #if 0 |
1451 | fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist "); | 1450 | fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist "); |
1452 | sdata = s->session->tlsext_ecpointformatlist; | 1451 | sdata = s->session->tlsext_ecpointformatlist; |