summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2012-03-06 13:20:20 +0000
committerDr. Stephen Henson <steve@openssl.org>2012-03-06 13:20:20 +0000
commit4e7f6d380ded86f19dea9465ac296b1be4e2d180 (patch)
treeda796308e6c99ef514e5dc4c51b6cfec041a6406 /crypto
parentf0be325f885201430206559831f5e1c936be5df3 (diff)
PR: 2748
Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de> Fix possible DTLS timer deadlock.
Diffstat (limited to 'crypto')
-rw-r--r--crypto/engine/eng_cryptodev.c23
-rw-r--r--crypto/x509v3/v3_asid.c47
2 files changed, 57 insertions, 13 deletions
diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c
index eef1e2d814..09ef3292b5 100644
--- a/crypto/engine/eng_cryptodev.c
+++ b/crypto/engine/eng_cryptodev.c
@@ -186,6 +186,7 @@ get_dev_crypto(void)
if ((fd = open_dev_crypto()) == -1)
return (-1);
+#ifndef CRIOGET_NOT_NEEDED
if (ioctl(fd, CRIOGET, &retfd) == -1)
return (-1);
@@ -194,9 +195,19 @@ get_dev_crypto(void)
close(retfd);
return (-1);
}
+#else
+ retfd = fd;
+#endif
return (retfd);
}
+static void put_dev_crypto(int fd)
+{
+#ifndef CRIOGET_NOT_NEEDED
+ close(fd);
+#endif
+}
+
/* Caching version for asym operations */
static int
get_asym_dev_crypto(void)
@@ -282,7 +293,7 @@ get_cryptodev_ciphers(const int **cnids)
ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
nids[count++] = ciphers[i].nid;
}
- close(fd);
+ put_dev_crypto(fd);
if (count > 0)
*cnids = nids;
@@ -319,7 +330,7 @@ get_cryptodev_digests(const int **cnids)
ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
nids[count++] = digests[i].nid;
}
- close(fd);
+ put_dev_crypto(fd);
if (count > 0)
*cnids = nids;
@@ -457,7 +468,7 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
sess->cipher = cipher;
if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
- close(state->d_fd);
+ put_dev_crypto(state->d_fd);
state->d_fd = -1;
return (0);
}
@@ -494,7 +505,7 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
} else {
ret = 1;
}
- close(state->d_fd);
+ put_dev_crypto(state->d_fd);
state->d_fd = -1;
return (ret);
@@ -1084,11 +1095,11 @@ ENGINE_load_cryptodev(void)
* find out what asymmetric crypto algorithms we support
*/
if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
- close(fd);
+ put_dev_crypto(fd);
ENGINE_free(engine);
return;
}
- close(fd);
+ put_dev_crypto(fd);
if (!ENGINE_set_id(engine, "cryptodev") ||
!ENGINE_set_name(engine, "BSD cryptodev engine") ||
diff --git a/crypto/x509v3/v3_asid.c b/crypto/x509v3/v3_asid.c
index cff04a3558..d2011f18f9 100644
--- a/crypto/x509v3/v3_asid.c
+++ b/crypto/x509v3/v3_asid.c
@@ -358,6 +358,20 @@ static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
goto done;
}
+ /*
+ * Check for inverted range.
+ */
+ i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
+ {
+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+ ASN1_INTEGER *a_min, *a_max;
+ if (a != NULL && a->type == ASIdOrRange_range) {
+ extract_min_max(a, &a_min, &a_max);
+ if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
+ goto done;
+ }
+ }
+
ret = 1;
done:
@@ -392,9 +406,18 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
return 1;
/*
- * We have a list. Sort it.
+ * If not a list, or if empty list, it's broken.
+ */
+ if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
+ sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) {
+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+ X509V3_R_EXTENSION_VALUE_ERROR);
+ return 0;
+ }
+
+ /*
+ * We have a non-empty list. Sort it.
*/
- OPENSSL_assert(choice->type == ASIdentifierChoice_asIdsOrRanges);
sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
/*
@@ -415,6 +438,13 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
/*
+ * Punt inverted ranges.
+ */
+ if (ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
+ ASN1_INTEGER_cmp(b_min, b_max) > 0)
+ goto done;
+
+ /*
* Check for overlaps.
*/
if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
@@ -498,6 +528,7 @@ static void *v2i_ASIdentifiers(struct v3_ext_method *method,
struct v3_ext_ctx *ctx,
STACK_OF(CONF_VALUE) *values)
{
+ ASN1_INTEGER *min = NULL, *max = NULL;
ASIdentifiers *asid = NULL;
int i;
@@ -508,7 +539,6 @@ static void *v2i_ASIdentifiers(struct v3_ext_method *method,
for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
- ASN1_INTEGER *min = NULL, *max = NULL;
int i1, i2, i3, is_range, which;
/*
@@ -578,18 +608,19 @@ static void *v2i_ASIdentifiers(struct v3_ext_method *method,
max = s2i_ASN1_INTEGER(NULL, s + i2);
OPENSSL_free(s);
if (min == NULL || max == NULL) {
- ASN1_INTEGER_free(min);
- ASN1_INTEGER_free(max);
X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
goto err;
}
+ if (ASN1_INTEGER_cmp(min, max) > 0) {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_VALUE_ERROR);
+ goto err;
+ }
}
if (!v3_asid_add_id_or_range(asid, which, min, max)) {
- ASN1_INTEGER_free(min);
- ASN1_INTEGER_free(max);
X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
goto err;
}
+ min = max = NULL;
}
/*
@@ -601,6 +632,8 @@ static void *v2i_ASIdentifiers(struct v3_ext_method *method,
err:
ASIdentifiers_free(asid);
+ ASN1_INTEGER_free(min);
+ ASN1_INTEGER_free(max);
return NULL;
}