summaryrefslogtreecommitdiff
path: root/Cryptlib/OpenSSL/crypto/asn1
diff options
context:
space:
mode:
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/asn1')
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_bitstr.c26
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_digest.c6
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_dup.c2
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_gentm.c65
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_hdr.c118
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_int.c20
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_meth.c86
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_object.c26
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_octet.c5
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_set.c44
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_sign.c128
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_strex.c1
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_strnid.c21
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_time.c68
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_type.c7
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_utctm.c124
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/a_verify.c68
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c484
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn1_err.c26
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn1_gen.c79
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c43
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn1_locl.h135
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn1_par.c16
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn_mime.c107
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn_pack.c9
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/bio_asn1.c482
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/bio_ndef.c248
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/charmap.h24
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/d2i_pr.c97
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/d2i_pu.c9
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/i2d_pr.c34
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/n_pkey.c38
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/nsseq.c5
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/p5_pbe.c71
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/p5_pbev2.c178
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/p8_pkey.c63
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_crl.c3
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_pkey.c689
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_req.c27
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_spki.c22
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/t_x509.c120
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c22
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c11
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_fre.c8
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_new.c33
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_prn.c585
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/tasn_typ.c11
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_algor.c15
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_crl.c373
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_long.c11
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_name.c273
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_nx509.c72
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_pubkey.c289
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_req.c3
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/x_x509.c43
55 files changed, 3841 insertions, 1732 deletions
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_bitstr.c b/Cryptlib/OpenSSL/crypto/asn1/a_bitstr.c
index ef1caa4e..f906188b 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_bitstr.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_bitstr.c
@@ -234,3 +234,29 @@ int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
return (0);
return ((a->data[w] & v) != 0);
}
+
+/*
+ * Checks if the given bit string contains only bits specified by
+ * the flags vector. Returns 0 if there is at least one bit set in 'a'
+ * which is not specified in 'flags', 1 otherwise.
+ * 'len' is the length of 'flags'.
+ */
+int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
+ unsigned char *flags, int flags_len)
+{
+ int i, ok;
+ /* Check if there is one bit set at all. */
+ if (!a || !a->data)
+ return 1;
+
+ /*
+ * Check each byte of the internal representation of the bit string.
+ */
+ ok = 1;
+ for (i = 0; i < a->length && ok; ++i) {
+ unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
+ /* We are done if there is an unneeded bit set. */
+ ok = (a->data[i] & mask) == 0;
+ }
+ return ok;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_digest.c b/Cryptlib/OpenSSL/crypto/asn1/a_digest.c
index 2c0a9bad..7cbc4751 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_digest.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_digest.c
@@ -86,7 +86,8 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
p = str;
i2d(data, &p);
- EVP_Digest(str, i, md, len, type, NULL);
+ if (!EVP_Digest(str, i, md, len, type, NULL))
+ return 0;
OPENSSL_free(str);
return (1);
}
@@ -103,7 +104,8 @@ int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
if (!str)
return (0);
- EVP_Digest(str, i, md, len, type, NULL);
+ if (!EVP_Digest(str, i, md, len, type, NULL))
+ return 0;
OPENSSL_free(str);
return (1);
}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_dup.c b/Cryptlib/OpenSSL/crypto/asn1/a_dup.c
index 35e65409..349ab562 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_dup.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_dup.c
@@ -62,7 +62,7 @@
#ifndef NO_OLD_ASN1
-void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x)
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
{
unsigned char *b, *p;
const unsigned char *p2;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_gentm.c b/Cryptlib/OpenSSL/crypto/asn1/a_gentm.c
index b504f2e7..fa76dcac 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_gentm.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_gentm.c
@@ -65,6 +65,7 @@
#include "cryptlib.h"
#include "o_time.h"
#include <openssl/asn1.h>
+#include "asn1_locl.h"
#if 0
@@ -117,10 +118,10 @@ ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a,
#endif
-int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
{
- static int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
- static int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
+ static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
+ static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
char *a;
int n, i, l, o;
@@ -139,6 +140,8 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
for (i = 0; i < 7; i++) {
if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
i++;
+ if (tm)
+ tm->tm_sec = 0;
break;
}
if ((a[o] < '0') || (a[o] > '9'))
@@ -155,6 +158,31 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
if ((n < min[i]) || (n > max[i]))
goto err;
+ if (tm) {
+ switch (i) {
+ case 0:
+ tm->tm_year = n * 100 - 1900;
+ break;
+ case 1:
+ tm->tm_year += n;
+ break;
+ case 2:
+ tm->tm_mon = n - 1;
+ break;
+ case 3:
+ tm->tm_mday = n;
+ break;
+ case 4:
+ tm->tm_hour = n;
+ break;
+ case 5:
+ tm->tm_min = n;
+ break;
+ case 6:
+ tm->tm_sec = n;
+ break;
+ }
+ }
}
/*
* Optional fractional seconds: decimal point followed by one or more
@@ -174,6 +202,7 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-')) {
+ int offsign = a[o] == '-' ? -1 : 1, offset = 0;
o++;
if (o + 4 > l)
goto err;
@@ -187,14 +216,30 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
n = (n * 10) + a[o] - '0';
if ((n < min[i]) || (n > max[i]))
goto err;
+ if (tm) {
+ if (i == 7)
+ offset = n * 3600;
+ else if (i == 8)
+ offset += n * 60;
+ }
o++;
}
+ if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+ return 0;
+ } else if (a[o]) {
+ /* Missing time zone information. */
+ goto err;
}
return (o == l);
err:
return (0);
}
+int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
+{
+ return asn1_generalizedtime_to_tm(NULL, d);
+}
+
int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
{
ASN1_GENERALIZEDTIME t;
@@ -217,6 +262,13 @@ int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
time_t t)
{
+ return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
+}
+
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+ time_t t, int offset_day,
+ long offset_sec)
+{
char *p;
struct tm *ts;
struct tm data;
@@ -231,11 +283,16 @@ ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
if (ts == NULL)
return (NULL);
+ if (offset_day || offset_sec) {
+ if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+ return NULL;
+ }
+
p = (char *)s->data;
if ((p == NULL) || ((size_t)s->length < len)) {
p = OPENSSL_malloc(len);
if (p == NULL) {
- ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_SET, ERR_R_MALLOC_FAILURE);
+ ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE);
return (NULL);
}
if (s->data != NULL)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_hdr.c b/Cryptlib/OpenSSL/crypto/asn1/a_hdr.c
deleted file mode 100644
index e67afdc6..00000000
--- a/Cryptlib/OpenSSL/crypto/asn1/a_hdr.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* crypto/asn1/a_hdr.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/asn1_mac.h>
-#include <openssl/asn1.h>
-
-int i2d_ASN1_HEADER(ASN1_HEADER * a, unsigned char **pp)
-{
- M_ASN1_I2D_vars(a);
-
- M_ASN1_I2D_len(a->header, i2d_ASN1_OCTET_STRING);
- M_ASN1_I2D_len(a->data, a->meth->i2d);
-
- M_ASN1_I2D_seq_total();
-
- M_ASN1_I2D_put(a->header, i2d_ASN1_OCTET_STRING);
- M_ASN1_I2D_put(a->data, a->meth->i2d);
-
- M_ASN1_I2D_finish();
-}
-
-ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER ** a, const unsigned char **pp,
- long length)
-{
- M_ASN1_D2I_vars(a, ASN1_HEADER *, ASN1_HEADER_new);
-
- M_ASN1_D2I_Init();
- M_ASN1_D2I_start_sequence();
- M_ASN1_D2I_get_x(ASN1_OCTET_STRING, ret->header, d2i_ASN1_OCTET_STRING);
- if (ret->meth != NULL) {
- M_ASN1_D2I_get_x(void, ret->data, ret->meth->d2i);
- } else {
- if (a != NULL)
- (*a) = ret;
- return (ret);
- }
- M_ASN1_D2I_Finish(a, ASN1_HEADER_free, ASN1_F_D2I_ASN1_HEADER);
-}
-
-ASN1_HEADER *ASN1_HEADER_new(void)
-{
- ASN1_HEADER *ret = NULL;
- ASN1_CTX c;
-
- M_ASN1_New_Malloc(ret, ASN1_HEADER);
- M_ASN1_New(ret->header, M_ASN1_OCTET_STRING_new);
- ret->meth = NULL;
- ret->data = NULL;
- return (ret);
- M_ASN1_New_Error(ASN1_F_ASN1_HEADER_NEW);
-}
-
-void ASN1_HEADER_free(ASN1_HEADER * a)
-{
- if (a == NULL)
- return;
- M_ASN1_OCTET_STRING_free(a->header);
- if (a->meth != NULL)
- a->meth->destroy(a->data);
- OPENSSL_free(a);
-}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_int.c b/Cryptlib/OpenSSL/crypto/asn1/a_int.c
index b788617f..7e26704a 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_int.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_int.c
@@ -61,12 +61,12 @@
#include <openssl/asn1.h>
#include <openssl/bn.h>
-ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x)
+ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
{
return M_ASN1_INTEGER_dup(x);
}
-int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y)
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
{
int neg, ret;
/* Compare signs */
@@ -124,6 +124,8 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
else {
ret = a->length;
i = a->data[0];
+ if (ret == 1 && i == 0)
+ neg = 0;
if (!neg && (i > 127)) {
pad = 1;
pb = 0;
@@ -162,7 +164,7 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
p += a->length - 1;
i = a->length;
/* Copy zeros to destination as long as source is zero */
- while (!*n) {
+ while (!*n && i > 1) {
*(p--) = 0;
n--;
i--;
@@ -377,7 +379,7 @@ int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
return (1);
}
-long ASN1_INTEGER_get(ASN1_INTEGER *a)
+long ASN1_INTEGER_get(const ASN1_INTEGER *a)
{
int neg = 0, i;
long r = 0;
@@ -391,8 +393,8 @@ long ASN1_INTEGER_get(ASN1_INTEGER *a)
return -1;
if (a->length > (int)sizeof(long)) {
- /* hmm... a bit ugly */
- return (0xffffffffL);
+ /* hmm... a bit ugly, return all ones */
+ return -1;
}
if (a->data == NULL)
return 0;
@@ -406,7 +408,7 @@ long ASN1_INTEGER_get(ASN1_INTEGER *a)
return (r);
}
-ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai)
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
{
ASN1_INTEGER *ret;
int len, j;
@@ -419,7 +421,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai)
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR);
goto err;
}
- if (BN_is_negative(bn))
+ if (BN_is_negative(bn) && !BN_is_zero(bn))
ret->type = V_ASN1_NEG_INTEGER;
else
ret->type = V_ASN1_INTEGER;
@@ -446,7 +448,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai)
return (NULL);
}
-BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai, BIGNUM *bn)
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
{
BIGNUM *ret;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_meth.c b/Cryptlib/OpenSSL/crypto/asn1/a_meth.c
deleted file mode 100644
index 9c5efabc..00000000
--- a/Cryptlib/OpenSSL/crypto/asn1/a_meth.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* crypto/asn1/a_meth.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/buffer.h>
-#include <openssl/asn1.h>
-
-static ASN1_METHOD ia5string_meth = {
- (I2D_OF(void)) i2d_ASN1_IA5STRING,
- (D2I_OF(void)) d2i_ASN1_IA5STRING,
- (void *(*)(void))ASN1_STRING_new,
- (void (*)(void *))ASN1_STRING_free
-};
-
-static ASN1_METHOD bit_string_meth = {
- (I2D_OF(void)) i2d_ASN1_BIT_STRING,
- (D2I_OF(void)) d2i_ASN1_BIT_STRING,
- (void *(*)(void))ASN1_STRING_new,
- (void (*)(void *))ASN1_STRING_free
-};
-
-ASN1_METHOD *ASN1_IA5STRING_asn1_meth(void)
-{
- return (&ia5string_meth);
-}
-
-ASN1_METHOD *ASN1_BIT_STRING_asn1_meth(void)
-{
- return (&bit_string_meth);
-}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_object.c b/Cryptlib/OpenSSL/crypto/asn1/a_object.c
index aa1847cf..27f9c169 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_object.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_object.c
@@ -262,8 +262,6 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
return ret;
err:
ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
- if ((ret != NULL) && ((a == NULL) || (*a != ret)))
- ASN1_OBJECT_free(ret);
return (NULL);
}
@@ -272,6 +270,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
{
ASN1_OBJECT *ret = NULL;
const unsigned char *p;
+ unsigned char *data;
int i, length;
/*
@@ -305,17 +304,24 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
ret = (*a);
p = *pp;
- if ((ret->data == NULL) || (ret->length < length)) {
- if (ret->data != NULL)
- OPENSSL_free(ret->data);
- ret->data = (unsigned char *)OPENSSL_malloc(length);
- ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
- if (ret->data == NULL) {
+ /* detach data from object */
+ data = (unsigned char *)ret->data;
+ ret->data = NULL;
+ /* once detached we can change it */
+ if ((data == NULL) || (ret->length < length)) {
+ ret->length = 0;
+ if (data != NULL)
+ OPENSSL_free(data);
+ data = (unsigned char *)OPENSSL_malloc(length);
+ if (data == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
+ ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
}
- memcpy(ret->data, p, length);
+ memcpy(data, p, length);
+ /* reattach data to object, after which it remains const */
+ ret->data = data;
ret->length = length;
ret->sn = NULL;
ret->ln = NULL;
@@ -368,7 +374,7 @@ void ASN1_OBJECT_free(ASN1_OBJECT *a)
}
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
if (a->data != NULL)
- OPENSSL_free(a->data);
+ OPENSSL_free((void *)a->data);
a->data = NULL;
a->length = 0;
}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_octet.c b/Cryptlib/OpenSSL/crypto/asn1/a_octet.c
index 6ea1950a..1a6e9ca9 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_octet.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_octet.c
@@ -60,12 +60,13 @@
#include "cryptlib.h"
#include <openssl/asn1.h>
-ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *x)
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
{
return M_ASN1_OCTET_STRING_dup(x);
}
-int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b)
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
+ const ASN1_OCTET_STRING *b)
{
return M_ASN1_OCTET_STRING_cmp(a, b);
}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_set.c b/Cryptlib/OpenSSL/crypto/asn1/a_set.c
index 18bb408c..bf3f9718 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_set.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_set.c
@@ -86,8 +86,8 @@ static int SetBlobCmp(const void *elem1, const void *elem2)
/*
* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE)
*/
-int i2d_ASN1_SET(STACK * a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
- int ex_class, int is_set)
+int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
+ i2d_of_void *i2d, int ex_tag, int ex_class, int is_set)
{
int ret = 0, r;
int i;
@@ -98,8 +98,8 @@ int i2d_ASN1_SET(STACK * a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
if (a == NULL)
return (0);
- for (i = sk_num(a) - 1; i >= 0; i--)
- ret += i2d(sk_value(a, i), NULL);
+ for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--)
+ ret += i2d(sk_OPENSSL_BLOCK_value(a, i), NULL);
r = ASN1_object_size(1, ret, ex_tag);
if (pp == NULL)
return (r);
@@ -111,9 +111,9 @@ int i2d_ASN1_SET(STACK * a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
/* And then again by Ben */
/* And again by Steve */
- if (!is_set || (sk_num(a) < 2)) {
- for (i = 0; i < sk_num(a); i++)
- i2d(sk_value(a, i), &p);
+ if (!is_set || (sk_OPENSSL_BLOCK_num(a) < 2)) {
+ for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++)
+ i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
*pp = p;
return (r);
@@ -121,15 +121,15 @@ int i2d_ASN1_SET(STACK * a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
pStart = p; /* Catch the beg of Setblobs */
/* In this array we will store the SET blobs */
- rgSetBlob = (MYBLOB *) OPENSSL_malloc(sk_num(a) * sizeof(MYBLOB));
+ rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB));
if (rgSetBlob == NULL) {
ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE);
return (0);
}
- for (i = 0; i < sk_num(a); i++) {
+ for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) {
rgSetBlob[i].pbData = p; /* catch each set encode blob */
- i2d(sk_value(a, i), &p);
+ i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
* SetBlob */
}
@@ -140,7 +140,7 @@ int i2d_ASN1_SET(STACK * a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
* Now we have to sort the blobs. I am using a simple algo. *Sort ptrs
* *Copy to temp-mem *Copy from temp-mem to user-mem
*/
- qsort(rgSetBlob, sk_num(a), sizeof(MYBLOB), SetBlobCmp);
+ qsort(rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
if (!(pTempMem = OPENSSL_malloc(totSize))) {
ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE);
return (0);
@@ -148,7 +148,7 @@ int i2d_ASN1_SET(STACK * a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
/* Copy to temp mem */
p = pTempMem;
- for (i = 0; i < sk_num(a); ++i) {
+ for (i = 0; i < sk_OPENSSL_BLOCK_num(a); ++i) {
memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
p += rgSetBlob[i].cbData;
}
@@ -161,15 +161,17 @@ int i2d_ASN1_SET(STACK * a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
return (r);
}
-STACK *d2i_ASN1_SET(STACK ** a, const unsigned char **pp, long length,
- d2i_of_void *d2i, void (*free_func) (void *), int ex_tag,
- int ex_class)
+STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
+ const unsigned char **pp,
+ long length, d2i_of_void *d2i,
+ void (*free_func) (OPENSSL_BLOCK),
+ int ex_tag, int ex_class)
{
ASN1_const_CTX c;
- STACK *ret = NULL;
+ STACK_OF(OPENSSL_BLOCK) *ret = NULL;
if ((a == NULL) || ((*a) == NULL)) {
- if ((ret = sk_new_null()) == NULL) {
+ if ((ret = sk_OPENSSL_BLOCK_new_null()) == NULL) {
ASN1err(ASN1_F_D2I_ASN1_SET, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -213,10 +215,10 @@ STACK *d2i_ASN1_SET(STACK ** a, const unsigned char **pp, long length,
*/
if ((s = d2i(NULL, &c.p, c.slen)) == NULL) {
ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_ERROR_PARSING_SET_ELEMENT);
- asn1_add_error(*pp, (int)(c.q - *pp));
+ asn1_add_error(*pp, (int)(c.p - *pp));
goto err;
}
- if (!sk_push(ret, s))
+ if (!sk_OPENSSL_BLOCK_push(ret, s))
goto err;
}
if (a != NULL)
@@ -226,9 +228,9 @@ STACK *d2i_ASN1_SET(STACK ** a, const unsigned char **pp, long length,
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret))) {
if (free_func != NULL)
- sk_pop_free(ret, free_func);
+ sk_OPENSSL_BLOCK_pop_free(ret, free_func);
else
- sk_free(ret);
+ sk_OPENSSL_BLOCK_free(ret);
}
return (NULL);
}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_sign.c b/Cryptlib/OpenSSL/crypto/asn1/a_sign.c
index 92a5a6c6..51c6a0c3 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_sign.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_sign.c
@@ -123,6 +123,7 @@
#include <openssl/x509.h>
#include <openssl/objects.h>
#include <openssl/buffer.h>
+#include "asn1_locl.h"
#ifndef NO_ASN1_OLD
@@ -181,10 +182,10 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
p = buf_in;
i2d(data, &p);
- EVP_SignInit_ex(&ctx, type, NULL);
- EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl);
- if (!EVP_SignFinal(&ctx, (unsigned char *)buf_out,
- (unsigned int *)&outl, pkey)) {
+ if (!EVP_SignInit_ex(&ctx, type, NULL)
+ || !EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl)
+ || !EVP_SignFinal(&ctx, (unsigned char *)buf_out,
+ (unsigned int *)&outl, pkey)) {
outl = 0;
ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB);
goto err;
@@ -220,64 +221,89 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
EVP_PKEY *pkey, const EVP_MD *type)
{
EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+ if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) {
+ EVP_MD_CTX_cleanup(&ctx);
+ return 0;
+ }
+ return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
+}
+
+int ASN1_item_sign_ctx(const ASN1_ITEM *it,
+ X509_ALGOR *algor1, X509_ALGOR *algor2,
+ ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
+{
+ const EVP_MD *type;
+ EVP_PKEY *pkey;
unsigned char *buf_in = NULL, *buf_out = NULL;
- int i, inl = 0, outl = 0, outll = 0;
- X509_ALGOR *a;
+ size_t inl = 0, outl = 0, outll = 0;
+ int signid, paramtype;
+ int rv;
- EVP_MD_CTX_init(&ctx);
- for (i = 0; i < 2; i++) {
- if (i == 0)
- a = algor1;
- else
- a = algor2;
- if (a == NULL)
- continue;
- if (type->pkey_type == NID_dsaWithSHA1 ||
- type->pkey_type == NID_ecdsa_with_SHA1) {
- /*
- * special case: RFC 3279 tells us to omit 'parameters' with
- * id-dsa-with-sha1 and ecdsa-with-SHA1
- */
- ASN1_TYPE_free(a->parameter);
- a->parameter = NULL;
- } else if ((a->parameter == NULL) ||
- (a->parameter->type != V_ASN1_NULL)) {
- ASN1_TYPE_free(a->parameter);
- if ((a->parameter = ASN1_TYPE_new()) == NULL)
- goto err;
- a->parameter->type = V_ASN1_NULL;
- }
- ASN1_OBJECT_free(a->algorithm);
- a->algorithm = OBJ_nid2obj(type->pkey_type);
- if (a->algorithm == NULL) {
- ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE);
- goto err;
- }
- if (a->algorithm->length == 0) {
- ASN1err(ASN1_F_ASN1_ITEM_SIGN,
- ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
+ type = EVP_MD_CTX_md(ctx);
+ pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+
+ if (!type || !pkey) {
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
+ return 0;
+ }
+
+ if (pkey->ameth->item_sign) {
+ rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature);
+ if (rv == 1)
+ outl = signature->length;
+ /*-
+ * Return value meanings:
+ * <=0: error.
+ * 1: method does everything.
+ * 2: carry on as normal.
+ * 3: ASN1 method sets algorithm identifiers: just sign.
+ */
+ if (rv <= 0)
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
+ if (rv <= 1)
goto err;
- }
+ } else
+ rv = 2;
+
+ if (rv == 2) {
+ if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) {
+ if (!pkey->ameth ||
+ !OBJ_find_sigid_by_algs(&signid,
+ EVP_MD_nid(type),
+ pkey->ameth->pkey_id)) {
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
+ ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+ return 0;
+ }
+ } else
+ signid = type->pkey_type;
+
+ if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
+ paramtype = V_ASN1_NULL;
+ else
+ paramtype = V_ASN1_UNDEF;
+
+ if (algor1)
+ X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
+ if (algor2)
+ X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
+
}
+
inl = ASN1_item_i2d(asn, &buf_in, it);
outll = outl = EVP_PKEY_size(pkey);
- buf_out = (unsigned char *)OPENSSL_malloc((unsigned int)outl);
+ buf_out = OPENSSL_malloc((unsigned int)outl);
if ((buf_in == NULL) || (buf_out == NULL)) {
outl = 0;
- ASN1err(ASN1_F_ASN1_ITEM_SIGN, ERR_R_MALLOC_FAILURE);
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (!EVP_SignInit_ex(&ctx, type, NULL)) {
- outl = 0;
- ASN1err(ASN1_F_ASN1_ITEM_SIGN, ERR_R_EVP_LIB);
- goto err;
- }
- EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl);
- if (!EVP_SignFinal(&ctx, (unsigned char *)buf_out,
- (unsigned int *)&outl, pkey)) {
+ if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
+ || !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
outl = 0;
- ASN1err(ASN1_F_ASN1_ITEM_SIGN, ERR_R_EVP_LIB);
+ ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
goto err;
}
if (signature->data != NULL)
@@ -292,7 +318,7 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
err:
- EVP_MD_CTX_cleanup(&ctx);
+ EVP_MD_CTX_cleanup(ctx);
if (buf_in != NULL) {
OPENSSL_cleanse((char *)buf_in, (unsigned int)inl);
OPENSSL_free(buf_in);
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_strex.c b/Cryptlib/OpenSSL/crypto/asn1/a_strex.c
index f650708c..35fd44cd 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_strex.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_strex.c
@@ -638,6 +638,7 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
mbflag |= MBSTRING_FLAG;
stmp.data = NULL;
stmp.length = 0;
+ stmp.flags = 0;
ret =
ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
B_ASN1_UTF8STRING);
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_strnid.c b/Cryptlib/OpenSSL/crypto/asn1/a_strnid.c
index 1796fba9..52243453 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_strnid.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_strnid.c
@@ -67,7 +67,6 @@ static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
static void st_free(ASN1_STRING_TABLE *tbl);
static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
const ASN1_STRING_TABLE *const *b);
-static int table_cmp(const void *a, const void *b);
/*
* This is the global mask for the mbstring functions: this is use to mask
@@ -171,7 +170,7 @@ ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
/* This table must be kept in NID order */
-static ASN1_STRING_TABLE tbl_standard[] = {
+static const ASN1_STRING_TABLE tbl_standard[] = {
{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
@@ -202,24 +201,24 @@ static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
return (*a)->nid - (*b)->nid;
}
-static int table_cmp(const void *a, const void *b)
+DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
{
- const ASN1_STRING_TABLE *sa = a, *sb = b;
- return sa->nid - sb->nid;
+ return a->nid - b->nid;
}
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
{
int idx;
ASN1_STRING_TABLE *ttmp;
ASN1_STRING_TABLE fnd;
fnd.nid = nid;
- ttmp = (ASN1_STRING_TABLE *)OBJ_bsearch((char *)&fnd,
- (char *)tbl_standard,
- sizeof(tbl_standard) /
- sizeof(ASN1_STRING_TABLE),
- sizeof(ASN1_STRING_TABLE),
- table_cmp);
+ ttmp = OBJ_bsearch_table(&fnd, tbl_standard,
+ sizeof(tbl_standard) /
+ sizeof(ASN1_STRING_TABLE));
if (ttmp)
return ttmp;
if (!stable)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_time.c b/Cryptlib/OpenSSL/crypto/asn1/a_time.c
index 34ac7202..fcb2d565 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_time.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_time.c
@@ -66,6 +66,7 @@
#include "cryptlib.h"
#include "o_time.h"
#include <openssl/asn1t.h>
+#include "asn1_locl.h"
IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
@@ -100,17 +101,27 @@ int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
{
+ return ASN1_TIME_adj(s, t, 0, 0);
+}
+
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
+ int offset_day, long offset_sec)
+{
struct tm *ts;
struct tm data;
ts = OPENSSL_gmtime(&t, &data);
if (ts == NULL) {
- ASN1err(ASN1_F_ASN1_TIME_SET, ASN1_R_ERROR_GETTING_TIME);
+ ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
return NULL;
}
+ if (offset_day || offset_sec) {
+ if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+ return NULL;
+ }
if ((ts->tm_year >= 50) && (ts->tm_year < 150))
- return ASN1_UTCTIME_set(s, t);
- return ASN1_GENERALIZEDTIME_set(s, t);
+ return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
+ return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
}
int ASN1_TIME_check(ASN1_TIME *t)
@@ -164,3 +175,54 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
return ret;
}
+
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
+{
+ ASN1_TIME t;
+
+ t.length = strlen(str);
+ t.data = (unsigned char *)str;
+ t.flags = 0;
+
+ t.type = V_ASN1_UTCTIME;
+
+ if (!ASN1_TIME_check(&t)) {
+ t.type = V_ASN1_GENERALIZEDTIME;
+ if (!ASN1_TIME_check(&t))
+ return 0;
+ }
+
+ if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
+ return 0;
+
+ return 1;
+}
+
+static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t)
+{
+ if (t == NULL) {
+ time_t now_t;
+ time(&now_t);
+ if (OPENSSL_gmtime(&now_t, tm))
+ return 1;
+ return 0;
+ }
+
+ if (t->type == V_ASN1_UTCTIME)
+ return asn1_utctime_to_tm(tm, t);
+ else if (t->type == V_ASN1_GENERALIZEDTIME)
+ return asn1_generalizedtime_to_tm(tm, t);
+
+ return 0;
+}
+
+int ASN1_TIME_diff(int *pday, int *psec,
+ const ASN1_TIME *from, const ASN1_TIME *to)
+{
+ struct tm tm_from, tm_to;
+ if (!asn1_time_to_tm(&tm_from, from))
+ return 0;
+ if (!asn1_time_to_tm(&tm_to, to))
+ return 0;
+ return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_type.c b/Cryptlib/OpenSSL/crypto/asn1/a_type.c
index 69a5cf6f..af795306 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_type.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_type.c
@@ -76,7 +76,10 @@ void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
}
a->type = type;
- a->value.ptr = value;
+ if (type == V_ASN1_BOOLEAN)
+ a->value.boolean = value ? 0xff : 0;
+ else
+ a->value.ptr = value;
}
int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
@@ -92,7 +95,7 @@ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
ASN1_TYPE_set(a, type, odup);
} else {
ASN1_STRING *sdup;
- sdup = ASN1_STRING_dup((ASN1_STRING *)value);
+ sdup = ASN1_STRING_dup(value);
if (!sdup)
return 0;
ASN1_TYPE_set(a, type, sdup);
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_utctm.c b/Cryptlib/OpenSSL/crypto/asn1/a_utctm.c
index 2aabc675..724a10be 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_utctm.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_utctm.c
@@ -61,6 +61,7 @@
#include "cryptlib.h"
#include "o_time.h"
#include <openssl/asn1.h>
+#include "asn1_locl.h"
#if 0
int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
@@ -109,10 +110,10 @@ ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
#endif
-int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
{
- static int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
- static int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
+ static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
+ static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
char *a;
int n, i, l, o;
@@ -127,6 +128,8 @@ int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
for (i = 0; i < 6; i++) {
if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
i++;
+ if (tm)
+ tm->tm_sec = 0;
break;
}
if ((a[o] < '0') || (a[o] > '9'))
@@ -143,10 +146,33 @@ int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
if ((n < min[i]) || (n > max[i]))
goto err;
+ if (tm) {
+ switch (i) {
+ case 0:
+ tm->tm_year = n < 50 ? n + 100 : n;
+ break;
+ case 1:
+ tm->tm_mon = n - 1;
+ break;
+ case 2:
+ tm->tm_mday = n;
+ break;
+ case 3:
+ tm->tm_hour = n;
+ break;
+ case 4:
+ tm->tm_min = n;
+ break;
+ case 5:
+ tm->tm_sec = n;
+ break;
+ }
+ }
}
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-')) {
+ int offsign = a[o] == '-' ? -1 : 1, offset = 0;
o++;
if (o + 4 > l)
goto err;
@@ -160,12 +186,25 @@ int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
n = (n * 10) + a[o] - '0';
if ((n < min[i]) || (n > max[i]))
goto err;
+ if (tm) {
+ if (i == 6)
+ offset = n * 3600;
+ else if (i == 7)
+ offset += n * 60;
+ }
o++;
}
+ if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+ return 0;
}
- return (o == l);
+ return o == l;
err:
- return (0);
+ return 0;
+}
+
+int ASN1_UTCTIME_check(const ASN1_UTCTIME *d)
+{
+ return asn1_utctime_to_tm(NULL, d);
}
int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
@@ -189,26 +228,43 @@ int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
{
+ return ASN1_UTCTIME_adj(s, t, 0, 0);
+}
+
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+ int offset_day, long offset_sec)
+{
char *p;
struct tm *ts;
struct tm data;
size_t len = 20;
+ int free_s = 0;
- if (s == NULL)
+ if (s == NULL) {
+ free_s = 1;
s = M_ASN1_UTCTIME_new();
+ }
if (s == NULL)
- return (NULL);
+ goto err;
ts = OPENSSL_gmtime(&t, &data);
if (ts == NULL)
- return (NULL);
+ goto err;
+
+ if (offset_day || offset_sec) {
+ if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+ goto err;
+ }
+
+ if ((ts->tm_year < 50) || (ts->tm_year >= 150))
+ goto err;
p = (char *)s->data;
if ((p == NULL) || ((size_t)s->length < len)) {
p = OPENSSL_malloc(len);
if (p == NULL) {
- ASN1err(ASN1_F_ASN1_UTCTIME_SET, ERR_R_MALLOC_FAILURE);
- return (NULL);
+ ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE);
+ goto err;
}
if (s->data != NULL)
OPENSSL_free(s->data);
@@ -224,42 +280,34 @@ ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
ebcdic2ascii(s->data, s->data, s->length);
#endif
return (s);
+ err:
+ if (free_s && s)
+ M_ASN1_UTCTIME_free(s);
+ return NULL;
}
int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
{
- struct tm *tm;
- struct tm data;
- int offset;
- int year;
-
-#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
-
- if (s->data[12] == 'Z')
- offset = 0;
- else {
- offset = g2(s->data + 13) * 60 + g2(s->data + 15);
- if (s->data[12] == '-')
- offset = -offset;
- }
+ struct tm stm, ttm;
+ int day, sec;
- t -= offset * 60; /* FIXME: may overflow in extreme cases */
+ if (!asn1_utctime_to_tm(&stm, s))
+ return -2;
- tm = OPENSSL_gmtime(&t, &data);
+ if (!OPENSSL_gmtime(&t, &ttm))
+ return -2;
-#define return_cmp(a,b) if ((a)<(b)) return -1; else if ((a)>(b)) return 1
- year = g2(s->data);
- if (year < 50)
- year += 100;
- return_cmp(year, tm->tm_year);
- return_cmp(g2(s->data + 2) - 1, tm->tm_mon);
- return_cmp(g2(s->data + 4), tm->tm_mday);
- return_cmp(g2(s->data + 6), tm->tm_hour);
- return_cmp(g2(s->data + 8), tm->tm_min);
- return_cmp(g2(s->data + 10), tm->tm_sec);
-#undef g2
-#undef return_cmp
+ if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
+ return -2;
+ if (day > 0)
+ return 1;
+ if (day < 0)
+ return -1;
+ if (sec > 0)
+ return 1;
+ if (sec < 0)
+ return -1;
return 0;
}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_verify.c b/Cryptlib/OpenSSL/crypto/asn1/a_verify.c
index afbfa021..3ffd934c 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_verify.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_verify.c
@@ -60,6 +60,7 @@
#include <time.h>
#include "cryptlib.h"
+#include "asn1_locl.h"
#ifndef NO_SYS_TYPES_H
# include <sys/types.h>
@@ -103,12 +104,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
p = buf_in;
i2d(data, &p);
- if (!EVP_VerifyInit_ex(&ctx, type, NULL)) {
+ if (!EVP_VerifyInit_ex(&ctx, type, NULL)
+ || !EVP_VerifyUpdate(&ctx, (unsigned char *)buf_in, inl)) {
ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
ret = 0;
goto err;
}
- EVP_VerifyUpdate(&ctx, (unsigned char *)buf_in, inl);
OPENSSL_cleanse(buf_in, (unsigned int)inl);
OPENSSL_free(buf_in);
@@ -136,9 +137,10 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
{
EVP_MD_CTX ctx;
- const EVP_MD *type;
unsigned char *buf_in = NULL;
- int ret = -1, i, inl;
+ int ret = -1, inl;
+
+ int mdnid, pknid;
if (!pkey) {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
@@ -151,18 +153,48 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
}
EVP_MD_CTX_init(&ctx);
- i = OBJ_obj2nid(a->algorithm);
- type = EVP_get_digestbyname(OBJ_nid2sn(i));
- if (type == NULL) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
- ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+
+ /* Convert signature OID into digest and public key OIDs */
+ if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
goto err;
}
+ if (mdnid == NID_undef) {
+ if (!pkey->ameth || !pkey->ameth->item_verify) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
+ ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ goto err;
+ }
+ ret = pkey->ameth->item_verify(&ctx, it, asn, a, signature, pkey);
+ /*
+ * Return value of 2 means carry on, anything else means we exit
+ * straight away: either a fatal error of the underlying verification
+ * routine handles all verification.
+ */
+ if (ret != 2)
+ goto err;
+ ret = -1;
+ } else {
+ const EVP_MD *type;
+ type = EVP_get_digestbynid(mdnid);
+ if (type == NULL) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
+ ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ goto err;
+ }
+
+ /* Check public key OID matches public key type */
+ if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
+ goto err;
+ }
+
+ if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+ ret = 0;
+ goto err;
+ }
- if (!EVP_VerifyInit_ex(&ctx, type, NULL)) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
- ret = 0;
- goto err;
}
inl = ASN1_item_i2d(asn, &buf_in, it);
@@ -172,13 +204,17 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
goto err;
}
- EVP_VerifyUpdate(&ctx, (unsigned char *)buf_in, inl);
+ if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+ ret = 0;
+ goto err;
+ }
OPENSSL_cleanse(buf_in, (unsigned int)inl);
OPENSSL_free(buf_in);
- if (EVP_VerifyFinal(&ctx, (unsigned char *)signature->data,
- (unsigned int)signature->length, pkey) <= 0) {
+ if (EVP_DigestVerifyFinal(&ctx, signature->data,
+ (size_t)signature->length) <= 0) {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
ret = 0;
goto err;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c b/Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c
new file mode 100644
index 00000000..5389c043
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c
@@ -0,0 +1,484 @@
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#include "asn1_locl.h"
+
+extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
+
+/* Keep this sorted in type order !! */
+static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
+#ifndef OPENSSL_NO_RSA
+ &rsa_asn1_meths[0],
+ &rsa_asn1_meths[1],
+#endif
+#ifndef OPENSSL_NO_DH
+ &dh_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+ &dsa_asn1_meths[0],
+ &dsa_asn1_meths[1],
+ &dsa_asn1_meths[2],
+ &dsa_asn1_meths[3],
+ &dsa_asn1_meths[4],
+#endif
+#ifndef OPENSSL_NO_EC
+ &eckey_asn1_meth,
+#endif
+ &hmac_asn1_meth,
+ &cmac_asn1_meth,
+#ifndef OPENSSL_NO_DH
+ &dhx_asn1_meth
+#endif
+};
+
+typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
+DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
+static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
+
+#ifdef TEST
+void main()
+{
+ int i;
+ for (i = 0;
+ i < sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); i++)
+ fprintf(stderr, "Number %d id=%d (%s)\n", i,
+ standard_methods[i]->pkey_id,
+ OBJ_nid2sn(standard_methods[i]->pkey_id));
+}
+#endif
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+ const EVP_PKEY_ASN1_METHOD *, ameth);
+
+static int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a,
+ const EVP_PKEY_ASN1_METHOD *const *b)
+{
+ return ((*a)->pkey_id - (*b)->pkey_id);
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+ const EVP_PKEY_ASN1_METHOD *, ameth);
+
+int EVP_PKEY_asn1_get_count(void)
+{
+ int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *);
+ if (app_methods)
+ num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
+ return num;
+}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
+{
+ int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *);
+ if (idx < 0)
+ return NULL;
+ if (idx < num)
+ return standard_methods[idx];
+ idx -= num;
+ return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+}
+
+static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
+{
+ EVP_PKEY_ASN1_METHOD tmp;
+ const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
+ tmp.pkey_id = type;
+ if (app_methods) {
+ int idx;
+ idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
+ if (idx >= 0)
+ return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+ }
+ ret = OBJ_bsearch_ameth(&t, standard_methods, sizeof(standard_methods)
+ / sizeof(EVP_PKEY_ASN1_METHOD *));
+ if (!ret || !*ret)
+ return NULL;
+ return *ret;
+}
+
+/*
+ * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also
+ * search through engines and set *pe to a functional reference to the engine
+ * implementing 'type' or NULL if no engine implements it.
+ */
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
+{
+ const EVP_PKEY_ASN1_METHOD *t;
+
+ for (;;) {
+ t = pkey_asn1_find(type);
+ if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
+ break;
+ type = t->pkey_base_id;
+ }
+ if (pe) {
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE *e;
+ /* type will contain the final unaliased type */
+ e = ENGINE_get_pkey_asn1_meth_engine(type);
+ if (e) {
+ *pe = e;
+ return ENGINE_get_pkey_asn1_meth(e, type);
+ }
+#endif
+ *pe = NULL;
+ }
+ return t;
+}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+ const char *str, int len)
+{
+ int i;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ if (len == -1)
+ len = strlen(str);
+ if (pe) {
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE *e;
+ ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
+ if (ameth) {
+ /*
+ * Convert structural into functional reference
+ */
+ if (!ENGINE_init(e))
+ ameth = NULL;
+ ENGINE_free(e);
+ *pe = e;
+ return ameth;
+ }
+#endif
+ *pe = NULL;
+ }
+ for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
+ ameth = EVP_PKEY_asn1_get0(i);
+ if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
+ continue;
+ if (((int)strlen(ameth->pem_str) == len) &&
+ !strncasecmp(ameth->pem_str, str, len))
+ return ameth;
+ }
+ return NULL;
+}
+
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
+{
+ if (app_methods == NULL) {
+ app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
+ if (!app_methods)
+ return 0;
+ }
+ if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
+ return 0;
+ sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
+ return 1;
+}
+
+int EVP_PKEY_asn1_add_alias(int to, int from)
+{
+ EVP_PKEY_ASN1_METHOD *ameth;
+ ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
+ if (!ameth)
+ return 0;
+ ameth->pkey_base_id = to;
+ if (!EVP_PKEY_asn1_add0(ameth)) {
+ EVP_PKEY_asn1_free(ameth);
+ return 0;
+ }
+ return 1;
+}
+
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id,
+ int *ppkey_flags, const char **pinfo,
+ const char **ppem_str,
+ const EVP_PKEY_ASN1_METHOD *ameth)
+{
+ if (!ameth)
+ return 0;
+ if (ppkey_id)
+ *ppkey_id = ameth->pkey_id;
+ if (ppkey_base_id)
+ *ppkey_base_id = ameth->pkey_base_id;
+ if (ppkey_flags)
+ *ppkey_flags = ameth->pkey_flags;
+ if (pinfo)
+ *pinfo = ameth->info;
+ if (ppem_str)
+ *ppem_str = ameth->pem_str;
+ return 1;
+}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
+{
+ return pkey->ameth;
+}
+
+EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
+ const char *pem_str, const char *info)
+{
+ EVP_PKEY_ASN1_METHOD *ameth;
+ ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
+ if (!ameth)
+ return NULL;
+
+ memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD));
+
+ ameth->pkey_id = id;
+ ameth->pkey_base_id = id;
+ ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
+
+ if (info) {
+ ameth->info = BUF_strdup(info);
+ if (!ameth->info)
+ goto err;
+ } else
+ ameth->info = NULL;
+
+ if (pem_str) {
+ ameth->pem_str = BUF_strdup(pem_str);
+ if (!ameth->pem_str)
+ goto err;
+ } else
+ ameth->pem_str = NULL;
+
+ ameth->pub_decode = 0;
+ ameth->pub_encode = 0;
+ ameth->pub_cmp = 0;
+ ameth->pub_print = 0;
+
+ ameth->priv_decode = 0;
+ ameth->priv_encode = 0;
+ ameth->priv_print = 0;
+
+ ameth->old_priv_encode = 0;
+ ameth->old_priv_decode = 0;
+
+ ameth->item_verify = 0;
+ ameth->item_sign = 0;
+
+ ameth->pkey_size = 0;
+ ameth->pkey_bits = 0;
+
+ ameth->param_decode = 0;
+ ameth->param_encode = 0;
+ ameth->param_missing = 0;
+ ameth->param_copy = 0;
+ ameth->param_cmp = 0;
+ ameth->param_print = 0;
+
+ ameth->pkey_free = 0;
+ ameth->pkey_ctrl = 0;
+
+ return ameth;
+
+ err:
+
+ EVP_PKEY_asn1_free(ameth);
+ return NULL;
+
+}
+
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
+ const EVP_PKEY_ASN1_METHOD *src)
+{
+
+ dst->pub_decode = src->pub_decode;
+ dst->pub_encode = src->pub_encode;
+ dst->pub_cmp = src->pub_cmp;
+ dst->pub_print = src->pub_print;
+
+ dst->priv_decode = src->priv_decode;
+ dst->priv_encode = src->priv_encode;
+ dst->priv_print = src->priv_print;
+
+ dst->old_priv_encode = src->old_priv_encode;
+ dst->old_priv_decode = src->old_priv_decode;
+
+ dst->pkey_size = src->pkey_size;
+ dst->pkey_bits = src->pkey_bits;
+
+ dst->param_decode = src->param_decode;
+ dst->param_encode = src->param_encode;
+ dst->param_missing = src->param_missing;
+ dst->param_copy = src->param_copy;
+ dst->param_cmp = src->param_cmp;
+ dst->param_print = src->param_print;
+
+ dst->pkey_free = src->pkey_free;
+ dst->pkey_ctrl = src->pkey_ctrl;
+
+ dst->item_sign = src->item_sign;
+ dst->item_verify = src->item_verify;
+
+}
+
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
+{
+ if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) {
+ if (ameth->pem_str)
+ OPENSSL_free(ameth->pem_str);
+ if (ameth->info)
+ OPENSSL_free(ameth->info);
+ OPENSSL_free(ameth);
+ }
+}
+
+void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*pub_decode) (EVP_PKEY *pk,
+ X509_PUBKEY *pub),
+ int (*pub_encode) (X509_PUBKEY *pub,
+ const EVP_PKEY *pk),
+ int (*pub_cmp) (const EVP_PKEY *a,
+ const EVP_PKEY *b),
+ int (*pub_print) (BIO *out,
+ const EVP_PKEY *pkey,
+ int indent, ASN1_PCTX *pctx),
+ int (*pkey_size) (const EVP_PKEY *pk),
+ int (*pkey_bits) (const EVP_PKEY *pk))
+{
+ ameth->pub_decode = pub_decode;
+ ameth->pub_encode = pub_encode;
+ ameth->pub_cmp = pub_cmp;
+ ameth->pub_print = pub_print;
+ ameth->pkey_size = pkey_size;
+ ameth->pkey_bits = pkey_bits;
+}
+
+void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*priv_decode) (EVP_PKEY *pk,
+ PKCS8_PRIV_KEY_INFO
+ *p8inf),
+ int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
+ const EVP_PKEY *pk),
+ int (*priv_print) (BIO *out,
+ const EVP_PKEY *pkey,
+ int indent,
+ ASN1_PCTX *pctx))
+{
+ ameth->priv_decode = priv_decode;
+ ameth->priv_encode = priv_encode;
+ ameth->priv_print = priv_print;
+}
+
+void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*param_decode) (EVP_PKEY *pkey,
+ const unsigned char **pder,
+ int derlen),
+ int (*param_encode) (const EVP_PKEY *pkey,
+ unsigned char **pder),
+ int (*param_missing) (const EVP_PKEY *pk),
+ int (*param_copy) (EVP_PKEY *to,
+ const EVP_PKEY *from),
+ int (*param_cmp) (const EVP_PKEY *a,
+ const EVP_PKEY *b),
+ int (*param_print) (BIO *out,
+ const EVP_PKEY *pkey,
+ int indent, ASN1_PCTX *pctx))
+{
+ ameth->param_decode = param_decode;
+ ameth->param_encode = param_encode;
+ ameth->param_missing = param_missing;
+ ameth->param_copy = param_copy;
+ ameth->param_cmp = param_cmp;
+ ameth->param_print = param_print;
+}
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+ void (*pkey_free) (EVP_PKEY *pkey))
+{
+ ameth->pkey_free = pkey_free;
+}
+
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
+ long arg1, void *arg2))
+{
+ ameth->pkey_ctrl = pkey_ctrl;
+}
+
+void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*item_verify) (EVP_MD_CTX *ctx,
+ const ASN1_ITEM *it,
+ void *asn,
+ X509_ALGOR *a,
+ ASN1_BIT_STRING *sig,
+ EVP_PKEY *pkey),
+ int (*item_sign) (EVP_MD_CTX *ctx,
+ const ASN1_ITEM *it,
+ void *asn,
+ X509_ALGOR *alg1,
+ X509_ALGOR *alg2,
+ ASN1_BIT_STRING *sig))
+{
+ ameth->item_sign = item_sign;
+ ameth->item_verify = item_verify;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c b/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c
index 43e4c195..fd4ac8d9 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c
@@ -90,10 +90,11 @@ static ERR_STRING_DATA ASN1_str_functs[] = {
{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"},
{ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"},
{ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"},
+ {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"},
{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"},
{ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"},
{ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"},
- {ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_new"},
+ {ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_NEW"},
{ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"},
{ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"},
{ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"},
@@ -106,13 +107,14 @@ static ERR_STRING_DATA ASN1_str_functs[] = {
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
{ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"},
{ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"},
{ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"},
- {ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_NEW"},
+ {ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"},
{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"},
{ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"},
{ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"},
@@ -124,15 +126,18 @@ static ERR_STRING_DATA ASN1_str_functs[] = {
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"},
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"},
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"},
+ {ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"},
{ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"},
{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING),
"ASN1_TYPE_get_int_octetstring"},
{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"},
{ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"},
+ {ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"},
{ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"},
{ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"},
{ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"},
{ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"},
+ {ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"},
{ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"},
{ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"},
{ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"},
@@ -144,13 +149,14 @@ static ERR_STRING_DATA ASN1_str_functs[] = {
{ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"},
{ERR_FUNC(ASN1_F_D2I_ASN1_BYTES), "d2i_ASN1_bytes"},
{ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME), "D2I_ASN1_GENERALIZEDTIME"},
- {ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "d2i_ASN1_HEADER"},
+ {ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "D2I_ASN1_HEADER"},
{ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER), "D2I_ASN1_INTEGER"},
{ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"},
{ERR_FUNC(ASN1_F_D2I_ASN1_SET), "d2i_ASN1_SET"},
{ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES), "d2i_ASN1_type_bytes"},
{ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"},
{ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME), "D2I_ASN1_UTCTIME"},
+ {ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"},
{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA), "d2i_Netscape_RSA"},
{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"},
{ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"},
@@ -160,6 +166,7 @@ static ERR_STRING_DATA ASN1_str_functs[] = {
{ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"},
{ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"},
{ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"},
+ {ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"},
{ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"},
{ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"},
{ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"},
@@ -171,8 +178,10 @@ static ERR_STRING_DATA ASN1_str_functs[] = {
{ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"},
{ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"},
{ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"},
- {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET), "PKCS5_pbe2_set"},
+ {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"},
{ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"},
+ {ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"},
+ {ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"},
{ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"},
{ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"},
{ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"},
@@ -202,10 +211,13 @@ static ERR_STRING_DATA ASN1_str_reasons[] = {
{ERR_REASON(ASN1_R_BUFFER_TOO_SMALL), "buffer too small"},
{ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),
"cipher has no object identifier"},
+ {ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED), "context not initialised"},
{ERR_REASON(ASN1_R_DATA_IS_WRONG), "data is wrong"},
{ERR_REASON(ASN1_R_DECODE_ERROR), "decode error"},
{ERR_REASON(ASN1_R_DECODING_ERROR), "decoding error"},
{ERR_REASON(ASN1_R_DEPTH_EXCEEDED), "depth exceeded"},
+ {ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),
+ "digest and key type not supported"},
{ERR_REASON(ASN1_R_ENCODE_ERROR), "encode error"},
{ERR_REASON(ASN1_R_ERROR_GETTING_TIME), "error getting time"},
{ERR_REASON(ASN1_R_ERROR_LOADING_SECTION), "error loading section"},
@@ -271,6 +283,7 @@ static ERR_STRING_DATA ASN1_str_reasons[] = {
{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT), "not ascii format"},
{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA), "not enough data"},
{ERR_REASON(ASN1_R_NO_CONTENT_TYPE), "no content type"},
+ {ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST), "no default digest"},
{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE), "no matching choice type"},
{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),
"no multipart body failure"},
@@ -309,8 +322,10 @@ static ERR_STRING_DATA ASN1_str_reasons[] = {
"unknown message digest algorithm"},
{ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE), "unknown object type"},
{ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE), "unknown public key type"},
+ {ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),
+ "unknown signature algorithm"},
{ERR_REASON(ASN1_R_UNKNOWN_TAG), "unknown tag"},
- {ERR_REASON(ASN1_R_UNKOWN_FORMAT), "unkown format"},
+ {ERR_REASON(ASN1_R_UNKOWN_FORMAT), "unknown format"},
{ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),
"unsupported any defined by type"},
{ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
@@ -319,6 +334,7 @@ static ERR_STRING_DATA ASN1_str_reasons[] = {
{ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),
"unsupported public key type"},
{ERR_REASON(ASN1_R_UNSUPPORTED_TYPE), "unsupported type"},
+ {ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"},
{ERR_REASON(ASN1_R_WRONG_TAG), "wrong tag"},
{ERR_REASON(ASN1_R_WRONG_TYPE), "wrong type"},
{0, NULL}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_gen.c b/Cryptlib/OpenSSL/crypto/asn1/asn1_gen.c
index 596b6564..65749239 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/asn1_gen.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_gen.c
@@ -74,6 +74,8 @@
#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val}
#define ASN1_FLAG_EXP_MAX 20
+/* Maximum number of nested sequences */
+#define ASN1_GEN_SEQ_MAX_DEPTH 50
/* Input formats */
@@ -110,13 +112,16 @@ typedef struct {
int exp_count;
} tag_exp_arg;
+static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth,
+ int *perr);
static int bitstr_cb(const char *elem, int len, void *bitstr);
static int asn1_cb(const char *elem, int len, void *bitstr);
static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
int exp_constructed, int exp_pad, int imp_ok);
static int parse_tagging(const char *vstart, int vlen, int *ptag,
int *pclass);
-static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
+ int depth, int *perr);
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
static int asn1_str2tag(const char *tagstr, int len);
@@ -133,6 +138,16 @@ ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
{
+ int err = 0;
+ ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err);
+ if (err)
+ ASN1err(ASN1_F_ASN1_GENERATE_V3, err);
+ return ret;
+}
+
+static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth,
+ int *perr)
+{
ASN1_TYPE *ret;
tag_exp_arg asn1_tags;
tag_exp_type *etmp;
@@ -152,17 +167,22 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
asn1_tags.imp_class = -1;
asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
asn1_tags.exp_count = 0;
- if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
+ if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) {
+ *perr = ASN1_R_UNKNOWN_TAG;
return NULL;
+ }
if ((asn1_tags.utype == V_ASN1_SEQUENCE)
|| (asn1_tags.utype == V_ASN1_SET)) {
if (!cnf) {
- ASN1err(ASN1_F_ASN1_GENERATE_V3,
- ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
+ *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG;
+ return NULL;
+ }
+ if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) {
+ *perr = ASN1_R_ILLEGAL_NESTED_TAGGING;
return NULL;
}
- ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
+ ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr);
} else
ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
@@ -242,9 +262,14 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
/* If IMPLICIT, output tag */
- if (asn1_tags.imp_tag != -1)
+ if (asn1_tags.imp_tag != -1) {
+ if (asn1_tags.imp_class == V_ASN1_UNIVERSAL
+ && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
+ || asn1_tags.imp_tag == V_ASN1_SET))
+ hdr_constructed = V_ASN1_CONSTRUCTED;
ASN1_put_object(&p, hdr_constructed, hdr_len,
asn1_tags.imp_tag, asn1_tags.imp_class);
+ }
/* Copy across original encoding */
memcpy(p, cpy_start, cpy_len);
@@ -274,6 +299,9 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
int tmp_tag, tmp_class;
+ if (elem == NULL)
+ return -1;
+
for (i = 0, p = elem; i < len; p++, i++) {
/* Look for the ':' in name value pairs */
if (*p == ':') {
@@ -345,13 +373,17 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
break;
case ASN1_GEN_FLAG_FORMAT:
+ if (!vstart) {
+ ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
+ return -1;
+ }
if (!strncmp(vstart, "ASCII", 5))
arg->format = ASN1_GEN_FORMAT_ASCII;
else if (!strncmp(vstart, "UTF8", 4))
arg->format = ASN1_GEN_FORMAT_UTF8;
else if (!strncmp(vstart, "HEX", 3))
arg->format = ASN1_GEN_FORMAT_HEX;
- else if (!strncmp(vstart, "BITLIST", 3))
+ else if (!strncmp(vstart, "BITLIST", 7))
arg->format = ASN1_GEN_FORMAT_BITLIST;
else {
ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT);
@@ -423,14 +455,15 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
/* Handle multiple types: SET and SEQUENCE */
-static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
+ int depth, int *perr)
{
- ASN1_TYPE *ret = NULL, *typ = NULL;
+ ASN1_TYPE *ret = NULL;
STACK_OF(ASN1_TYPE) *sk = NULL;
STACK_OF(CONF_VALUE) *sect = NULL;
- unsigned char *der = NULL, *p;
+ unsigned char *der = NULL;
int derlen;
- int i, is_set;
+ int i;
sk = sk_ASN1_TYPE_new_null();
if (!sk)
goto bad;
@@ -441,12 +474,13 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
if (!sect)
goto bad;
for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
- typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
+ ASN1_TYPE *typ =
+ generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf,
+ depth + 1, perr);
if (!typ)
goto bad;
if (!sk_ASN1_TYPE_push(sk, typ))
goto bad;
- typ = NULL;
}
}
@@ -455,18 +489,12 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
*/
if (utype == V_ASN1_SET)
- is_set = 1;
+ derlen = i2d_ASN1_SET_ANY(sk, &der);
else
- is_set = 0;
+ derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
- derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype,
- V_ASN1_UNIVERSAL, is_set);
- der = OPENSSL_malloc(derlen);
- if (!der)
+ if (derlen < 0)
goto bad;
- p = der;
- i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype,
- V_ASN1_UNIVERSAL, is_set);
if (!(ret = ASN1_TYPE_new()))
goto bad;
@@ -488,8 +516,6 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
if (sk)
sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
- if (typ)
- ASN1_TYPE_free(typ);
if (sect)
X509V3_section_free(cnf, sect);
@@ -535,7 +561,7 @@ static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
static int asn1_str2tag(const char *tagstr, int len)
{
unsigned int i;
- static struct tag_name_st *tntmp, tnst[] = {
+ static const struct tag_name_st *tntmp, tnst[] = {
ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
ASN1_GEN_STR("NULL", V_ASN1_NULL),
@@ -570,6 +596,8 @@ static int asn1_str2tag(const char *tagstr, int len)
ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
+ ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
+ ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
/* Special cases */
ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
@@ -701,6 +729,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
case V_ASN1_VISIBLESTRING:
case V_ASN1_UNIVERSALSTRING:
case V_ASN1_GENERALSTRING:
+ case V_ASN1_NUMERICSTRING:
if (format == ASN1_GEN_FORMAT_ASCII)
format = MBSTRING_ASC;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c b/Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c
index dd667f2d..0b61fc93 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c
@@ -333,20 +333,30 @@ int asn1_GetSequence(ASN1_const_CTX *c, long *length)
return (1);
}
-ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *str)
+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
{
- ASN1_STRING *ret;
-
if (str == NULL)
- return (NULL);
- if ((ret = ASN1_STRING_type_new(str->type)) == NULL)
- return (NULL);
- if (!ASN1_STRING_set(ret, str->data, str->length)) {
+ return 0;
+ dst->type = str->type;
+ if (!ASN1_STRING_set(dst, str->data, str->length))
+ return 0;
+ dst->flags = str->flags;
+ return 1;
+}
+
+ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
+{
+ ASN1_STRING *ret;
+ if (!str)
+ return NULL;
+ ret = ASN1_STRING_new();
+ if (!ret)
+ return NULL;
+ if (!ASN1_STRING_copy(ret, str)) {
ASN1_STRING_free(ret);
- return (NULL);
+ return NULL;
}
- ret->flags = str->flags;
- return (ret);
+ return ret;
}
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
@@ -415,12 +425,19 @@ void ASN1_STRING_free(ASN1_STRING *a)
{
if (a == NULL)
return;
- if (a->data != NULL)
+ if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
OPENSSL_free(a->data);
OPENSSL_free(a);
}
-int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b)
+void ASN1_STRING_clear_free(ASN1_STRING *a)
+{
+ if (a && a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
+ OPENSSL_cleanse(a->data, a->length);
+ ASN1_STRING_free(a);
+}
+
+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
{
int i;
@@ -444,7 +461,7 @@ void asn1_add_error(const unsigned char *address, int offset)
ERR_add_error_data(4, "address=", buf1, " offset=", buf2);
}
-int ASN1_STRING_length(ASN1_STRING *x)
+int ASN1_STRING_length(const ASN1_STRING *x)
{
return M_ASN1_STRING_length(x);
}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_locl.h b/Cryptlib/OpenSSL/crypto/asn1/asn1_locl.h
new file mode 100644
index 00000000..4c004fab
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_locl.h
@@ -0,0 +1,135 @@
+/* asn1t.h */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Internal ASN1 structures and functions: not for application use */
+
+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d);
+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
+
+/* ASN1 print context structure */
+
+struct asn1_pctx_st {
+ unsigned long flags;
+ unsigned long nm_flags;
+ unsigned long cert_flags;
+ unsigned long oid_flags;
+ unsigned long str_flags;
+} /* ASN1_PCTX */ ;
+
+/* ASN1 public key method structure */
+
+struct evp_pkey_asn1_method_st {
+ int pkey_id;
+ int pkey_base_id;
+ unsigned long pkey_flags;
+ char *pem_str;
+ char *info;
+ int (*pub_decode) (EVP_PKEY *pk, X509_PUBKEY *pub);
+ int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk);
+ int (*pub_cmp) (const EVP_PKEY *a, const EVP_PKEY *b);
+ int (*pub_print) (BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx);
+ int (*priv_decode) (EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
+ int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
+ int (*priv_print) (BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx);
+ int (*pkey_size) (const EVP_PKEY *pk);
+ int (*pkey_bits) (const EVP_PKEY *pk);
+ int (*param_decode) (EVP_PKEY *pkey,
+ const unsigned char **pder, int derlen);
+ int (*param_encode) (const EVP_PKEY *pkey, unsigned char **pder);
+ int (*param_missing) (const EVP_PKEY *pk);
+ int (*param_copy) (EVP_PKEY *to, const EVP_PKEY *from);
+ int (*param_cmp) (const EVP_PKEY *a, const EVP_PKEY *b);
+ int (*param_print) (BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx);
+ int (*sig_print) (BIO *out,
+ const X509_ALGOR *sigalg, const ASN1_STRING *sig,
+ int indent, ASN1_PCTX *pctx);
+ void (*pkey_free) (EVP_PKEY *pkey);
+ int (*pkey_ctrl) (EVP_PKEY *pkey, int op, long arg1, void *arg2);
+ /* Legacy functions for old PEM */
+ int (*old_priv_decode) (EVP_PKEY *pkey,
+ const unsigned char **pder, int derlen);
+ int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder);
+ /* Custom ASN1 signature verification */
+ int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey);
+ int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *alg1, X509_ALGOR *alg2,
+ ASN1_BIT_STRING *sig);
+} /* EVP_PKEY_ASN1_METHOD */ ;
+
+/*
+ * Method to handle CRL access. In general a CRL could be very large (several
+ * Mb) and can consume large amounts of resources if stored in memory by
+ * multiple processes. This method allows general CRL operations to be
+ * redirected to more efficient callbacks: for example a CRL entry database.
+ */
+
+#define X509_CRL_METHOD_DYNAMIC 1
+
+struct x509_crl_method_st {
+ int flags;
+ int (*crl_init) (X509_CRL *crl);
+ int (*crl_free) (X509_CRL *crl);
+ int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret,
+ ASN1_INTEGER *ser, X509_NAME *issuer);
+ int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk);
+};
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_par.c b/Cryptlib/OpenSSL/crypto/asn1/asn1_par.c
index e15e341a..a5d2da10 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/asn1_par.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_par.c
@@ -70,9 +70,8 @@ static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
int indent)
{
static const char fmt[] = "%-18s";
- static const char fmt2[] = "%2d %-15s";
char str[128];
- const char *p, *p2 = NULL;
+ const char *p;
if (constructed & V_ASN1_CONSTRUCTED)
p = "cons: ";
@@ -94,13 +93,8 @@ static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
else
p = ASN1_tag2str(tag);
- if (p2 != NULL) {
- if (BIO_printf(bp, fmt2, tag, p2) <= 0)
- goto err;
- } else {
- if (BIO_printf(bp, fmt, p) <= 0)
- goto err;
- }
+ if (BIO_printf(bp, fmt, p) <= 0)
+ goto err;
return (1);
err:
return (0);
@@ -343,7 +337,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
goto end;
}
} else {
- if (BIO_write(bp, "BAD ENUMERATED", 11) <= 0)
+ if (BIO_write(bp, "BAD ENUMERATED", 14) <= 0)
goto end;
}
M_ASN1_ENUMERATED_free(bs);
@@ -383,7 +377,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
const char *ASN1_tag2str(int tag)
{
- static const char *tag2str[] = {
+ static const char *const tag2str[] = {
/* 0-4 */
"EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
/* 5-9 */
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c b/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c
index e7c5696b..96110c54 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c
@@ -60,6 +60,7 @@
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
+#include "asn1_locl.h"
/*
* Generalised MIME like utilities for streaming ASN1. Although many have a
@@ -88,6 +89,8 @@ typedef struct {
DECLARE_STACK_OF(MIME_HEADER)
IMPLEMENT_STACK_OF(MIME_HEADER)
+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+ const ASN1_ITEM *it);
static char *strip_ends(char *name);
static char *strip_start(char *name);
static char *strip_end(char *name);
@@ -109,6 +112,37 @@ static void mime_hdr_free(MIME_HEADER *hdr);
#define MAX_SMLEN 1024
#define mime_debug(x) /* x */
+/* Output an ASN1 structure in BER format streaming if necessary */
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+ const ASN1_ITEM *it)
+{
+ /* If streaming create stream BIO and copy all content through it */
+ if (flags & SMIME_STREAM) {
+ BIO *bio, *tbio;
+ bio = BIO_new_NDEF(out, val, it);
+ if (!bio) {
+ ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ SMIME_crlf_copy(in, bio, flags);
+ (void)BIO_flush(bio);
+ /* Free up successive BIOs until we hit the old output BIO */
+ do {
+ tbio = BIO_pop(bio);
+ BIO_free(bio);
+ bio = tbio;
+ } while (bio != out);
+ }
+ /*
+ * else just write out ASN1 structure which will have all content stored
+ * internally
+ */
+ else
+ ASN1_item_i2d_bio(it, out, val);
+ return 1;
+}
+
/* Base 64 read and write of ASN1 structure */
static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
@@ -125,13 +159,25 @@ static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
* prepend the b64 BIO so all data is base64 encoded.
*/
out = BIO_push(b64, out);
- r = ASN1_item_i2d_bio(it, out, val);
+ r = i2d_ASN1_bio_stream(out, val, in, flags, it);
(void)BIO_flush(out);
BIO_pop(out);
BIO_free(b64);
return r;
}
+/* Streaming ASN1 PEM write */
+
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+ const char *hdr, const ASN1_ITEM *it)
+{
+ int r;
+ BIO_printf(out, "-----BEGIN %s-----\n", hdr);
+ r = B64_write_ASN1(out, val, in, flags, it);
+ BIO_printf(out, "-----END %s-----\n", hdr);
+ return r;
+}
+
static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
{
BIO *b64;
@@ -154,7 +200,8 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
{
- int i, have_unknown = 0, write_comma, md_nid;
+ const EVP_MD *md;
+ int i, have_unknown = 0, write_comma, ret = 0, md_nid;
have_unknown = 0;
write_comma = 0;
for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) {
@@ -162,6 +209,19 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
BIO_write(out, ",", 1);
write_comma = 1;
md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
+ md = EVP_get_digestbynid(md_nid);
+ if (md && md->md_ctrl) {
+ int rv;
+ char *micstr;
+ rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
+ if (rv > 0) {
+ BIO_puts(out, micstr);
+ OPENSSL_free(micstr);
+ continue;
+ }
+ if (rv != -2)
+ goto err;
+ }
switch (md_nid) {
case NID_sha1:
BIO_puts(out, "sha1");
@@ -183,6 +243,11 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
BIO_puts(out, "sha-512");
break;
+ case NID_id_GostR3411_94:
+ BIO_puts(out, "gostr3411-94");
+ goto err;
+ break;
+
default:
if (have_unknown)
write_comma = 0;
@@ -195,16 +260,18 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
}
}
- return 1;
+ ret = 1;
+ err:
+
+ return ret;
}
/* SMIME sender */
-int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
- int ctype_nid, int econt_nid,
- STACK_OF(X509_ALGOR) *mdalgs,
- asn1_output_data_fn * data_fn, const ASN1_ITEM *it)
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+ int ctype_nid, int econt_nid,
+ STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it)
{
char bound[33], c;
int i;
@@ -222,7 +289,8 @@ int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
if ((flags & SMIME_DETACHED) && data) {
/* We want multipart/signed */
/* Generate a random boundary */
- RAND_pseudo_bytes((unsigned char *)bound, 32);
+ if (RAND_pseudo_bytes((unsigned char *)bound, 32) < 0)
+ return 0;
for (i = 0; i < 32; i++) {
c = bound[i] & 0xf;
if (c < 10)
@@ -243,7 +311,7 @@ int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
mime_eol, mime_eol);
/* Now write out the first part */
BIO_printf(bio, "------%s%s", bound, mime_eol);
- if (!data_fn(bio, data, val, flags, it))
+ if (!asn1_output_data(bio, data, val, flags, it))
return 0;
BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
@@ -291,8 +359,6 @@ int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
return 1;
}
-#if 0
-
/* Handle output of ASN1 data */
static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
@@ -301,8 +367,13 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
BIO *tmpbio;
const ASN1_AUX *aux = it->funcs;
ASN1_STREAM_ARG sarg;
+ int rv = 1;
- if (!(flags & SMIME_DETACHED)) {
+ /*
+ * If data is not deteched or resigning then the output BIO is already
+ * set up to finalise when it is written through.
+ */
+ if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) {
SMIME_crlf_copy(data, out, flags);
return 1;
}
@@ -326,7 +397,7 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
/* Finalize structure */
if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
- return 0;
+ rv = 0;
/* Now remove any digests prepended to the BIO */
@@ -336,12 +407,10 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
sarg.ndef_bio = tmpbio;
}
- return 1;
+ return rv;
}
-#endif
-
/*
* SMIME reader: handle multipart/signed and opaque signing. in multipart
* case the content is placed in a memory BIO pointed to by "bcont". In
@@ -737,7 +806,7 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
if (!(tmpname = BUF_strdup(name)))
return NULL;
for (p = tmpname; *p; p++) {
- c = *p;
+ c = (unsigned char)*p;
if (isupper(c)) {
c = tolower(c);
*p = c;
@@ -749,7 +818,7 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
if (!(tmpval = BUF_strdup(value)))
return NULL;
for (p = tmpval; *p; p++) {
- c = *p;
+ c = (unsigned char)*p;
if (isupper(c)) {
c = tolower(c);
*p = c;
@@ -777,7 +846,7 @@ static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
if (!tmpname)
return 0;
for (p = tmpname; *p; p++) {
- c = *p;
+ c = (unsigned char)*p;
if (isupper(c)) {
c = tolower(c);
*p = c;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn_pack.c b/Cryptlib/OpenSSL/crypto/asn1/asn_pack.c
index 0f460d0a..366caf01 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/asn_pack.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn_pack.c
@@ -67,10 +67,11 @@
/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */
-STACK *ASN1_seq_unpack(const unsigned char *buf, int len,
- d2i_of_void *d2i, void (*free_func) (void *))
+STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
+ d2i_of_void *d2i,
+ void (*free_func) (OPENSSL_BLOCK))
{
- STACK *sk;
+ STACK_OF(OPENSSL_BLOCK) *sk;
const unsigned char *pbuf;
pbuf = buf;
if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func,
@@ -84,7 +85,7 @@ STACK *ASN1_seq_unpack(const unsigned char *buf, int len,
* OPENSSL_malloc'ed buffer
*/
-unsigned char *ASN1_seq_pack(STACK * safes, i2d_of_void *i2d,
+unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
unsigned char **buf, int *len)
{
int safelen;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/bio_asn1.c b/Cryptlib/OpenSSL/crypto/asn1/bio_asn1.c
new file mode 100644
index 00000000..60189b3b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/bio_asn1.c
@@ -0,0 +1,482 @@
+/* bio_asn1.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+ * Experimental ASN1 BIO. When written through the data is converted to an
+ * ASN1 string type: default is OCTET STRING. Additional functions can be
+ * provided to add prefix and suffix data.
+ */
+
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+
+/* Must be large enough for biggest tag+length */
+#define DEFAULT_ASN1_BUF_SIZE 20
+
+typedef enum {
+ ASN1_STATE_START,
+ ASN1_STATE_PRE_COPY,
+ ASN1_STATE_HEADER,
+ ASN1_STATE_HEADER_COPY,
+ ASN1_STATE_DATA_COPY,
+ ASN1_STATE_POST_COPY,
+ ASN1_STATE_DONE
+} asn1_bio_state_t;
+
+typedef struct BIO_ASN1_EX_FUNCS_st {
+ asn1_ps_func *ex_func;
+ asn1_ps_func *ex_free_func;
+} BIO_ASN1_EX_FUNCS;
+
+typedef struct BIO_ASN1_BUF_CTX_t {
+ /* Internal state */
+ asn1_bio_state_t state;
+ /* Internal buffer */
+ unsigned char *buf;
+ /* Size of buffer */
+ int bufsize;
+ /* Current position in buffer */
+ int bufpos;
+ /* Current buffer length */
+ int buflen;
+ /* Amount of data to copy */
+ int copylen;
+ /* Class and tag to use */
+ int asn1_class, asn1_tag;
+ asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
+ /* Extra buffer for prefix and suffix data */
+ unsigned char *ex_buf;
+ int ex_len;
+ int ex_pos;
+ void *ex_arg;
+} BIO_ASN1_BUF_CTX;
+
+static int asn1_bio_write(BIO *h, const char *buf, int num);
+static int asn1_bio_read(BIO *h, char *buf, int size);
+static int asn1_bio_puts(BIO *h, const char *str);
+static int asn1_bio_gets(BIO *h, char *str, int size);
+static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int asn1_bio_new(BIO *h);
+static int asn1_bio_free(BIO *data);
+static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+ asn1_ps_func *cleanup, asn1_bio_state_t next);
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+ asn1_ps_func *setup,
+ asn1_bio_state_t ex_state,
+ asn1_bio_state_t other_state);
+
+static BIO_METHOD methods_asn1 = {
+ BIO_TYPE_ASN1,
+ "asn1",
+ asn1_bio_write,
+ asn1_bio_read,
+ asn1_bio_puts,
+ asn1_bio_gets,
+ asn1_bio_ctrl,
+ asn1_bio_new,
+ asn1_bio_free,
+ asn1_bio_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_asn1(void)
+{
+ return (&methods_asn1);
+}
+
+static int asn1_bio_new(BIO *b)
+{
+ BIO_ASN1_BUF_CTX *ctx;
+ ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
+ if (!ctx)
+ return 0;
+ if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
+ OPENSSL_free(ctx);
+ return 0;
+ }
+ b->init = 1;
+ b->ptr = (char *)ctx;
+ b->flags = 0;
+ return 1;
+}
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
+{
+ ctx->buf = OPENSSL_malloc(size);
+ if (!ctx->buf)
+ return 0;
+ ctx->bufsize = size;
+ ctx->bufpos = 0;
+ ctx->buflen = 0;
+ ctx->copylen = 0;
+ ctx->asn1_class = V_ASN1_UNIVERSAL;
+ ctx->asn1_tag = V_ASN1_OCTET_STRING;
+ ctx->ex_buf = 0;
+ ctx->ex_pos = 0;
+ ctx->ex_len = 0;
+ ctx->state = ASN1_STATE_START;
+ return 1;
+}
+
+static int asn1_bio_free(BIO *b)
+{
+ BIO_ASN1_BUF_CTX *ctx;
+ ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+ if (ctx == NULL)
+ return 0;
+ if (ctx->buf)
+ OPENSSL_free(ctx->buf);
+ OPENSSL_free(ctx);
+ b->init = 0;
+ b->ptr = NULL;
+ b->flags = 0;
+ return 1;
+}
+
+static int asn1_bio_write(BIO *b, const char *in, int inl)
+{
+ BIO_ASN1_BUF_CTX *ctx;
+ int wrmax, wrlen, ret;
+ unsigned char *p;
+ if (!in || (inl < 0) || (b->next_bio == NULL))
+ return 0;
+ ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+ if (ctx == NULL)
+ return 0;
+
+ wrlen = 0;
+ ret = -1;
+
+ for (;;) {
+ switch (ctx->state) {
+
+ /* Setup prefix data, call it */
+ case ASN1_STATE_START:
+ if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
+ ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
+ return 0;
+ break;
+
+ /* Copy any pre data first */
+ case ASN1_STATE_PRE_COPY:
+
+ ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
+ ASN1_STATE_HEADER);
+
+ if (ret <= 0)
+ goto done;
+
+ break;
+
+ case ASN1_STATE_HEADER:
+ ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
+ OPENSSL_assert(ctx->buflen <= ctx->bufsize);
+ p = ctx->buf;
+ ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
+ ctx->copylen = inl;
+ ctx->state = ASN1_STATE_HEADER_COPY;
+
+ break;
+
+ case ASN1_STATE_HEADER_COPY:
+ ret = BIO_write(b->next_bio, ctx->buf + ctx->bufpos, ctx->buflen);
+ if (ret <= 0)
+ goto done;
+
+ ctx->buflen -= ret;
+ if (ctx->buflen)
+ ctx->bufpos += ret;
+ else {
+ ctx->bufpos = 0;
+ ctx->state = ASN1_STATE_DATA_COPY;
+ }
+
+ break;
+
+ case ASN1_STATE_DATA_COPY:
+
+ if (inl > ctx->copylen)
+ wrmax = ctx->copylen;
+ else
+ wrmax = inl;
+ ret = BIO_write(b->next_bio, in, wrmax);
+ if (ret <= 0)
+ break;
+ wrlen += ret;
+ ctx->copylen -= ret;
+ in += ret;
+ inl -= ret;
+
+ if (ctx->copylen == 0)
+ ctx->state = ASN1_STATE_HEADER;
+
+ if (inl == 0)
+ goto done;
+
+ break;
+
+ default:
+ BIO_clear_retry_flags(b);
+ return 0;
+
+ }
+
+ }
+
+ done:
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+
+ return (wrlen > 0) ? wrlen : ret;
+
+}
+
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+ asn1_ps_func *cleanup, asn1_bio_state_t next)
+{
+ int ret;
+ if (ctx->ex_len <= 0)
+ return 1;
+ for (;;) {
+ ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos, ctx->ex_len);
+ if (ret <= 0)
+ break;
+ ctx->ex_len -= ret;
+ if (ctx->ex_len > 0)
+ ctx->ex_pos += ret;
+ else {
+ if (cleanup)
+ cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
+ ctx->state = next;
+ ctx->ex_pos = 0;
+ break;
+ }
+ }
+ return ret;
+}
+
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+ asn1_ps_func *setup,
+ asn1_bio_state_t ex_state,
+ asn1_bio_state_t other_state)
+{
+ if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ if (ctx->ex_len > 0)
+ ctx->state = ex_state;
+ else
+ ctx->state = other_state;
+ return 1;
+}
+
+static int asn1_bio_read(BIO *b, char *in, int inl)
+{
+ if (!b->next_bio)
+ return 0;
+ return BIO_read(b->next_bio, in, inl);
+}
+
+static int asn1_bio_puts(BIO *b, const char *str)
+{
+ return asn1_bio_write(b, str, strlen(str));
+}
+
+static int asn1_bio_gets(BIO *b, char *str, int size)
+{
+ if (!b->next_bio)
+ return 0;
+ return BIO_gets(b->next_bio, str, size);
+}
+
+static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ if (b->next_bio == NULL)
+ return (0);
+ return BIO_callback_ctrl(b->next_bio, cmd, fp);
+}
+
+static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
+{
+ BIO_ASN1_BUF_CTX *ctx;
+ BIO_ASN1_EX_FUNCS *ex_func;
+ long ret = 1;
+ ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+ if (ctx == NULL)
+ return 0;
+ switch (cmd) {
+
+ case BIO_C_SET_PREFIX:
+ ex_func = arg2;
+ ctx->prefix = ex_func->ex_func;
+ ctx->prefix_free = ex_func->ex_free_func;
+ break;
+
+ case BIO_C_GET_PREFIX:
+ ex_func = arg2;
+ ex_func->ex_func = ctx->prefix;
+ ex_func->ex_free_func = ctx->prefix_free;
+ break;
+
+ case BIO_C_SET_SUFFIX:
+ ex_func = arg2;
+ ctx->suffix = ex_func->ex_func;
+ ctx->suffix_free = ex_func->ex_free_func;
+ break;
+
+ case BIO_C_GET_SUFFIX:
+ ex_func = arg2;
+ ex_func->ex_func = ctx->suffix;
+ ex_func->ex_free_func = ctx->suffix_free;
+ break;
+
+ case BIO_C_SET_EX_ARG:
+ ctx->ex_arg = arg2;
+ break;
+
+ case BIO_C_GET_EX_ARG:
+ *(void **)arg2 = ctx->ex_arg;
+ break;
+
+ case BIO_CTRL_FLUSH:
+ if (!b->next_bio)
+ return 0;
+
+ /* Call post function if possible */
+ if (ctx->state == ASN1_STATE_HEADER) {
+ if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
+ ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
+ return 0;
+ }
+
+ if (ctx->state == ASN1_STATE_POST_COPY) {
+ ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
+ ASN1_STATE_DONE);
+ if (ret <= 0)
+ return ret;
+ }
+
+ if (ctx->state == ASN1_STATE_DONE)
+ return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+ else {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ break;
+
+ default:
+ if (!b->next_bio)
+ return 0;
+ return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+
+ }
+
+ return ret;
+}
+
+static int asn1_bio_set_ex(BIO *b, int cmd,
+ asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
+{
+ BIO_ASN1_EX_FUNCS extmp;
+ extmp.ex_func = ex_func;
+ extmp.ex_free_func = ex_free_func;
+ return BIO_ctrl(b, cmd, 0, &extmp);
+}
+
+static int asn1_bio_get_ex(BIO *b, int cmd,
+ asn1_ps_func **ex_func,
+ asn1_ps_func **ex_free_func)
+{
+ BIO_ASN1_EX_FUNCS extmp;
+ int ret;
+ ret = BIO_ctrl(b, cmd, 0, &extmp);
+ if (ret > 0) {
+ *ex_func = extmp.ex_func;
+ *ex_free_func = extmp.ex_free_func;
+ }
+ return ret;
+}
+
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+ asn1_ps_func *prefix_free)
+{
+ return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
+}
+
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+ asn1_ps_func **pprefix_free)
+{
+ return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
+}
+
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+ asn1_ps_func *suffix_free)
+{
+ return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
+}
+
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+ asn1_ps_func **psuffix_free)
+{
+ return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/bio_ndef.c b/Cryptlib/OpenSSL/crypto/asn1/bio_ndef.c
new file mode 100644
index 00000000..31949b87
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/bio_ndef.c
@@ -0,0 +1,248 @@
+/* bio_ndef.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+#include <stdio.h>
+
+/* Experimental NDEF ASN1 BIO support routines */
+
+/*
+ * The usage is quite simple, initialize an ASN1 structure, get a BIO from it
+ * then any data written through the BIO will end up translated to
+ * approptiate format on the fly. The data is streamed out and does *not*
+ * need to be all held in memory at once. When the BIO is flushed the output
+ * is finalized and any signatures etc written out. The BIO is a 'proper'
+ * BIO and can handle non blocking I/O correctly. The usage is simple. The
+ * implementation is *not*...
+ */
+
+/* BIO support data stored in the ASN1 BIO ex_arg */
+
+typedef struct ndef_aux_st {
+ /* ASN1 structure this BIO refers to */
+ ASN1_VALUE *val;
+ const ASN1_ITEM *it;
+ /* Top of the BIO chain */
+ BIO *ndef_bio;
+ /* Output BIO */
+ BIO *out;
+ /* Boundary where content is inserted */
+ unsigned char **boundary;
+ /* DER buffer start */
+ unsigned char *derbuf;
+} NDEF_SUPPORT;
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+ void *parg);
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+ void *parg);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
+{
+ NDEF_SUPPORT *ndef_aux = NULL;
+ BIO *asn_bio = NULL;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_STREAM_ARG sarg;
+
+ if (!aux || !aux->asn1_cb) {
+ ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
+ return NULL;
+ }
+ ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
+ asn_bio = BIO_new(BIO_f_asn1());
+
+ /* ASN1 bio needs to be next to output BIO */
+
+ out = BIO_push(asn_bio, out);
+
+ if (!ndef_aux || !asn_bio || !out)
+ goto err;
+
+ BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
+ BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
+
+ /*
+ * Now let callback prepend any digest, cipher etc BIOs ASN1 structure
+ * needs.
+ */
+
+ sarg.out = out;
+ sarg.ndef_bio = NULL;
+ sarg.boundary = NULL;
+
+ if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
+ goto err;
+
+ ndef_aux->val = val;
+ ndef_aux->it = it;
+ ndef_aux->ndef_bio = sarg.ndef_bio;
+ ndef_aux->boundary = sarg.boundary;
+ ndef_aux->out = out;
+
+ BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
+
+ return sarg.ndef_bio;
+
+ err:
+ if (asn_bio)
+ BIO_free(asn_bio);
+ if (ndef_aux)
+ OPENSSL_free(ndef_aux);
+ return NULL;
+}
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+ NDEF_SUPPORT *ndef_aux;
+ unsigned char *p;
+ int derlen;
+
+ if (!parg)
+ return 0;
+
+ ndef_aux = *(NDEF_SUPPORT **)parg;
+
+ derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+ p = OPENSSL_malloc(derlen);
+ if (!p)
+ return 0;
+
+ ndef_aux->derbuf = p;
+ *pbuf = p;
+ derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+ if (!*ndef_aux->boundary)
+ return 0;
+
+ *plen = *ndef_aux->boundary - *pbuf;
+
+ return 1;
+}
+
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+ void *parg)
+{
+ NDEF_SUPPORT *ndef_aux;
+
+ if (!parg)
+ return 0;
+
+ ndef_aux = *(NDEF_SUPPORT **)parg;
+
+ if (ndef_aux->derbuf)
+ OPENSSL_free(ndef_aux->derbuf);
+
+ ndef_aux->derbuf = NULL;
+ *pbuf = NULL;
+ *plen = 0;
+ return 1;
+}
+
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+ void *parg)
+{
+ NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
+ if (!ndef_prefix_free(b, pbuf, plen, parg))
+ return 0;
+ OPENSSL_free(*pndef_aux);
+ *pndef_aux = NULL;
+ return 1;
+}
+
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+ NDEF_SUPPORT *ndef_aux;
+ unsigned char *p;
+ int derlen;
+ const ASN1_AUX *aux;
+ ASN1_STREAM_ARG sarg;
+
+ if (!parg)
+ return 0;
+
+ ndef_aux = *(NDEF_SUPPORT **)parg;
+
+ aux = ndef_aux->it->funcs;
+
+ /* Finalize structures */
+ sarg.ndef_bio = ndef_aux->ndef_bio;
+ sarg.out = ndef_aux->out;
+ sarg.boundary = ndef_aux->boundary;
+ if (aux->asn1_cb(ASN1_OP_STREAM_POST,
+ &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
+ return 0;
+
+ derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+ p = OPENSSL_malloc(derlen);
+ if (!p)
+ return 0;
+
+ ndef_aux->derbuf = p;
+ *pbuf = p;
+ derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+ if (!*ndef_aux->boundary)
+ return 0;
+ *pbuf = *ndef_aux->boundary;
+ *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
+
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/charmap.h b/Cryptlib/OpenSSL/crypto/asn1/charmap.h
index bd020a95..3305ad14 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/charmap.h
+++ b/Cryptlib/OpenSSL/crypto/asn1/charmap.h
@@ -1,15 +1,15 @@
-/* Auto generated with chartype.pl script.
- * Mask of various character properties
+/*
+ * Auto generated with chartype.pl script. Mask of various character
+ * properties
*/
-static unsigned char char_type[] = {
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16,
-16,16,16,16,16,16,16,16,16,16,16, 9, 9,16, 9,16,
- 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-16,16,16,16,16,16,16,16,16,16,16, 0, 1, 0, 0, 0,
- 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-16,16,16,16,16,16,16,16,16,16,16, 0, 0, 0, 0, 2
+static const unsigned char char_type[] = {
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 120, 0, 1, 40, 0, 0, 0, 16, 16, 16, 0, 25, 25, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16,
+ 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0,
+ 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2
};
-
diff --git a/Cryptlib/OpenSSL/crypto/asn1/d2i_pr.c b/Cryptlib/OpenSSL/crypto/asn1/d2i_pr.c
index 3218862f..c96da091 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/d2i_pr.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/d2i_pr.c
@@ -61,16 +61,12 @@
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
-#include <openssl/asn1.h>
-#ifndef OPENSSL_NO_RSA
-# include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-# include <openssl/dsa.h>
-#endif
-#ifndef OPENSSL_NO_EC
-# include <openssl/ec.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
#endif
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include "asn1_locl.h"
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
long length)
@@ -82,48 +78,36 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
return (NULL);
}
- } else
+ } else {
ret = *a;
-
- ret->save_type = type;
- ret->type = EVP_PKEY_type(type);
- switch (ret->type) {
-#ifndef OPENSSL_NO_RSA
- case EVP_PKEY_RSA:
- /* TMP UGLY CAST */
- if ((ret->pkey.rsa = d2i_RSAPrivateKey(NULL,
- (const unsigned char **)pp,
- length)) == NULL) {
- ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
- goto err;
- }
- break;
-#endif
-#ifndef OPENSSL_NO_DSA
- case EVP_PKEY_DSA:
- /* TMP UGLY CAST */
- if ((ret->pkey.dsa = d2i_DSAPrivateKey(NULL,
- (const unsigned char **)pp,
- length)) == NULL) {
- ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
- goto err;
+#ifndef OPENSSL_NO_ENGINE
+ if (ret->engine) {
+ ENGINE_finish(ret->engine);
+ ret->engine = NULL;
}
- break;
#endif
-#ifndef OPENSSL_NO_EC
- case EVP_PKEY_EC:
- if ((ret->pkey.ec = d2i_ECPrivateKey(NULL,
- (const unsigned char **)pp,
- length)) == NULL) {
+ }
+
+ if (!EVP_PKEY_set_type(ret, type)) {
+ ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
+ goto err;
+ }
+
+ if (!ret->ameth->old_priv_decode ||
+ !ret->ameth->old_priv_decode(ret, pp, length)) {
+ if (ret->ameth->priv_decode) {
+ PKCS8_PRIV_KEY_INFO *p8 = NULL;
+ p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, pp, length);
+ if (!p8)
+ goto err;
+ EVP_PKEY_free(ret);
+ ret = EVP_PKCS82PKEY(p8);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+
+ } else {
ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
goto err;
}
- break;
-#endif
- default:
- ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
- goto err;
- /* break; */
}
if (a != NULL)
(*a) = ret;
@@ -151,9 +135,7 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
* analyzing it we can determine the passed structure: this assumes the
* input is surrounded by an ASN1 SEQUENCE.
*/
- inkey = d2i_ASN1_SET_OF_ASN1_TYPE(NULL, &p, length, d2i_ASN1_TYPE,
- ASN1_TYPE_free, V_ASN1_SEQUENCE,
- V_ASN1_UNIVERSAL);
+ inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
/*
* Since we only need to discern "traditional format" RSA and DSA keys we
* can just count the elements.
@@ -162,7 +144,24 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
keytype = EVP_PKEY_DSA;
else if (sk_ASN1_TYPE_num(inkey) == 4)
keytype = EVP_PKEY_EC;
- else
+ else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not
+ * traditional format */
+ PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, pp, length);
+ EVP_PKEY *ret;
+
+ sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
+ if (!p8) {
+ ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,
+ ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+ return NULL;
+ }
+ ret = EVP_PKCS82PKEY(p8);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ if (a) {
+ *a = ret;
+ }
+ return ret;
+ } else
keytype = EVP_PKEY_RSA;
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
return d2i_PrivateKey(keytype, a, pp, length);
diff --git a/Cryptlib/OpenSSL/crypto/asn1/d2i_pu.c b/Cryptlib/OpenSSL/crypto/asn1/d2i_pu.c
index 1f05fee2..33542dd1 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/d2i_pu.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/d2i_pu.c
@@ -85,9 +85,12 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
} else
ret = *a;
- ret->save_type = type;
- ret->type = EVP_PKEY_type(type);
- switch (ret->type) {
+ if (!EVP_PKEY_set_type(ret, type)) {
+ ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
+ goto err;
+ }
+
+ switch (EVP_PKEY_id(ret)) {
#ifndef OPENSSL_NO_RSA
case EVP_PKEY_RSA:
/* TMP UGLY CAST */
diff --git a/Cryptlib/OpenSSL/crypto/asn1/i2d_pr.c b/Cryptlib/OpenSSL/crypto/asn1/i2d_pr.c
index 2919e48d..4d338ac5 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/i2d_pr.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/i2d_pr.c
@@ -58,37 +58,21 @@
#include <stdio.h>
#include "cryptlib.h"
-#include <openssl/bn.h>
#include <openssl/evp.h>
-#include <openssl/objects.h>
-#ifndef OPENSSL_NO_RSA
-# include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-# include <openssl/dsa.h>
-#endif
-#ifndef OPENSSL_NO_EC
-# include <openssl/ec.h>
-#endif
+#include <openssl/x509.h>
+#include "asn1_locl.h"
int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
{
-#ifndef OPENSSL_NO_RSA
- if (a->type == EVP_PKEY_RSA) {
- return (i2d_RSAPrivateKey(a->pkey.rsa, pp));
- } else
-#endif
-#ifndef OPENSSL_NO_DSA
- if (a->type == EVP_PKEY_DSA) {
- return (i2d_DSAPrivateKey(a->pkey.dsa, pp));
+ if (a->ameth && a->ameth->old_priv_encode) {
+ return a->ameth->old_priv_encode(a, pp);
}
-#endif
-#ifndef OPENSSL_NO_EC
- if (a->type == EVP_PKEY_EC) {
- return (i2d_ECPrivateKey(a->pkey.ec, pp));
+ if (a->ameth && a->ameth->priv_encode) {
+ PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
+ int ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ return ret;
}
-#endif
-
ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return (-1);
}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/n_pkey.c b/Cryptlib/OpenSSL/crypto/asn1/n_pkey.c
index f7b874eb..d5a55146 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/n_pkey.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/n_pkey.c
@@ -125,6 +125,7 @@ int i2d_RSA_NET(const RSA *a, unsigned char **pp,
unsigned char buf[256], *zz;
unsigned char key[EVP_MAX_KEY_LENGTH];
EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
if (a == NULL)
return (0);
@@ -201,24 +202,28 @@ int i2d_RSA_NET(const RSA *a, unsigned char **pp,
i = strlen((char *)buf);
/* If the key is used for SGC the algorithm is modified a little. */
if (sgckey) {
- EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL);
+ if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
+ goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
}
- EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL);
+ if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL))
+ goto err;
OPENSSL_cleanse(buf, 256);
/* Encrypt private key in place */
zz = enckey->enckey->digest->data;
- EVP_CIPHER_CTX_init(&ctx);
- EVP_EncryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL);
- EVP_EncryptUpdate(&ctx, zz, &i, zz, pkeylen);
- EVP_EncryptFinal_ex(&ctx, zz + i, &j);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ if (!EVP_EncryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
+ goto err;
+ if (!EVP_EncryptUpdate(&ctx, zz, &i, zz, pkeylen))
+ goto err;
+ if (!EVP_EncryptFinal_ex(&ctx, zz + i, &j))
+ goto err;
ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
NETSCAPE_PKEY_free(pkey);
return (ret);
@@ -282,6 +287,7 @@ static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
const unsigned char *zz;
unsigned char key[EVP_MAX_KEY_LENGTH];
EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
i = cb((char *)buf, 256, "Enter Private Key password:", 0);
if (i != 0) {
@@ -291,19 +297,22 @@ static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
i = strlen((char *)buf);
if (sgckey) {
- EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL);
+ if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
+ goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
}
- EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL);
+ if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL))
+ goto err;
OPENSSL_cleanse(buf, 256);
- EVP_CIPHER_CTX_init(&ctx);
- EVP_DecryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL);
- EVP_DecryptUpdate(&ctx, os->data, &i, os->data, os->length);
- EVP_DecryptFinal_ex(&ctx, &(os->data[i]), &j);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ if (!EVP_DecryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
+ goto err;
+ if (!EVP_DecryptUpdate(&ctx, os->data, &i, os->data, os->length))
+ goto err;
+ if (!EVP_DecryptFinal_ex(&ctx, &(os->data[i]), &j))
+ goto err;
os->length = i + j;
zz = os->data;
@@ -320,6 +329,7 @@ static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
goto err;
}
err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
NETSCAPE_PKEY_free(pkey);
return (ret);
}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/nsseq.c b/Cryptlib/OpenSSL/crypto/asn1/nsseq.c
index 186e8b0b..f2f7cba4 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/nsseq.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/nsseq.c
@@ -4,7 +4,7 @@
* 1999.
*/
/* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -63,7 +63,8 @@
#include <openssl/x509.h>
#include <openssl/objects.h>
-static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
{
if (operation == ASN1_OP_NEW_POST) {
NETSCAPE_CERT_SEQUENCE *nsseq;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/p5_pbe.c b/Cryptlib/OpenSSL/crypto/asn1/p5_pbe.c
index 096ccdd3..bdbfdcd6 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/p5_pbe.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/p5_pbe.c
@@ -72,65 +72,72 @@ ASN1_SEQUENCE(PBEPARAM) = {
IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
-/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
+/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
-X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen)
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+ const unsigned char *salt, int saltlen)
{
PBEPARAM *pbe = NULL;
- ASN1_OBJECT *al;
- X509_ALGOR *algor;
- ASN1_TYPE *astype = NULL;
+ ASN1_STRING *pbe_str = NULL;
+ unsigned char *sstr;
- if (!(pbe = PBEPARAM_new())) {
- ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
+ pbe = PBEPARAM_new();
+ if (!pbe) {
+ ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
goto err;
}
if (iter <= 0)
iter = PKCS5_DEFAULT_ITER;
if (!ASN1_INTEGER_set(pbe->iter, iter)) {
- ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
+ ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!saltlen)
saltlen = PKCS5_SALT_LEN;
- if (!(pbe->salt->data = OPENSSL_malloc(saltlen))) {
- ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
+ if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) {
+ ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
goto err;
}
- pbe->salt->length = saltlen;
+ sstr = ASN1_STRING_data(pbe->salt);
if (salt)
- memcpy(pbe->salt->data, salt, saltlen);
- else if (RAND_pseudo_bytes(pbe->salt->data, saltlen) < 0)
+ memcpy(sstr, salt, saltlen);
+ else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
goto err;
- if (!(astype = ASN1_TYPE_new())) {
- ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
+ if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) {
+ ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
goto err;
}
- astype->type = V_ASN1_SEQUENCE;
- if (!ASN1_pack_string_of(PBEPARAM, pbe, i2d_PBEPARAM,
- &astype->value.sequence)) {
- ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
PBEPARAM_free(pbe);
pbe = NULL;
- al = OBJ_nid2obj(alg); /* never need to free al */
- if (!(algor = X509_ALGOR_new())) {
- ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- ASN1_OBJECT_free(algor->algorithm);
- algor->algorithm = al;
- algor->parameter = astype;
+ if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
+ return 1;
- return (algor);
err:
if (pbe != NULL)
PBEPARAM_free(pbe);
- if (astype != NULL)
- ASN1_TYPE_free(astype);
+ if (pbe_str != NULL)
+ ASN1_STRING_free(pbe_str);
+ return 0;
+}
+
+/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+ const unsigned char *salt, int saltlen)
+{
+ X509_ALGOR *ret;
+ ret = X509_ALGOR_new();
+ if (!ret) {
+ ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
+ return ret;
+
+ X509_ALGOR_free(ret);
return NULL;
}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/p5_pbev2.c b/Cryptlib/OpenSSL/crypto/asn1/p5_pbev2.c
index 5054f0c4..73ba4a3d 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/p5_pbev2.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/p5_pbev2.c
@@ -83,24 +83,24 @@ IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
/*
* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know
- * this is horrible!
+ * this is horrible! Extended version to allow application supplied PRF NID
+ * and IV.
*/
-X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
- unsigned char *salt, int saltlen)
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+ unsigned char *salt, int saltlen,
+ unsigned char *aiv, int prf_nid)
{
X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
- int alg_nid;
+ int alg_nid, keylen;
EVP_CIPHER_CTX ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
- PBKDF2PARAM *kdf = NULL;
PBE2PARAM *pbe2 = NULL;
- ASN1_OCTET_STRING *osalt = NULL;
ASN1_OBJECT *obj;
alg_nid = EVP_CIPHER_type(cipher);
if (alg_nid == NID_undef) {
- ASN1err(ASN1_F_PKCS5_PBE2_SET,
+ ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
goto err;
}
@@ -117,31 +117,112 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
goto merr;
/* Create random IV */
- if (EVP_CIPHER_iv_length(cipher) &&
- RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
- goto err;
+ if (EVP_CIPHER_iv_length(cipher)) {
+ if (aiv)
+ memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
+ else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
+ goto err;
+ }
EVP_CIPHER_CTX_init(&ctx);
- /* Dummy cipherinit to just setup the IV */
- EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
+ /* Dummy cipherinit to just setup the IV, and PRF */
+ if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
+ goto err;
if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
- ASN1err(ASN1_F_PKCS5_PBE2_SET, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
+ ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
EVP_CIPHER_CTX_cleanup(&ctx);
goto err;
}
+ /*
+ * If prf NID unspecified see if cipher has a preference. An error is OK
+ * here: just means use default PRF.
+ */
+ if ((prf_nid == -1) &&
+ EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
+ ERR_clear_error();
+ prf_nid = NID_hmacWithSHA1;
+ }
EVP_CIPHER_CTX_cleanup(&ctx);
+ /* If its RC2 then we'd better setup the key length */
+
+ if (alg_nid == NID_rc2_cbc)
+ keylen = EVP_CIPHER_key_length(cipher);
+ else
+ keylen = -1;
+
+ /* Setup keyfunc */
+
+ X509_ALGOR_free(pbe2->keyfunc);
+
+ pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
+
+ if (!pbe2->keyfunc)
+ goto merr;
+
+ /* Now set up top level AlgorithmIdentifier */
+
+ if (!(ret = X509_ALGOR_new()))
+ goto merr;
+ if (!(ret->parameter = ASN1_TYPE_new()))
+ goto merr;
+
+ ret->algorithm = OBJ_nid2obj(NID_pbes2);
+
+ /* Encode PBE2PARAM into parameter */
+
+ if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
+ &ret->parameter->value.sequence))
+ goto merr;
+ ret->parameter->type = V_ASN1_SEQUENCE;
+
+ PBE2PARAM_free(pbe2);
+ pbe2 = NULL;
+
+ return ret;
+
+ merr:
+ ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);
+
+ err:
+ PBE2PARAM_free(pbe2);
+ /* Note 'scheme' is freed as part of pbe2 */
+ X509_ALGOR_free(kalg);
+ X509_ALGOR_free(ret);
+
+ return NULL;
+
+}
+
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+ unsigned char *salt, int saltlen)
+{
+ return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
+}
+
+X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
+ int prf_nid, int keylen)
+{
+ X509_ALGOR *keyfunc = NULL;
+ PBKDF2PARAM *kdf = NULL;
+ ASN1_OCTET_STRING *osalt = NULL;
+
if (!(kdf = PBKDF2PARAM_new()))
goto merr;
if (!(osalt = M_ASN1_OCTET_STRING_new()))
goto merr;
+ kdf->salt->value.octet_string = osalt;
+ kdf->salt->type = V_ASN1_OCTET_STRING;
+
if (!saltlen)
saltlen = PKCS5_SALT_LEN;
if (!(osalt->data = OPENSSL_malloc(saltlen)))
goto merr;
+
osalt->length = saltlen;
+
if (salt)
memcpy(osalt->data, salt, saltlen);
else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0)
@@ -149,74 +230,51 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
if (iter <= 0)
iter = PKCS5_DEFAULT_ITER;
+
if (!ASN1_INTEGER_set(kdf->iter, iter))
goto merr;
- /* Now include salt in kdf structure */
- kdf->salt->value.octet_string = osalt;
- kdf->salt->type = V_ASN1_OCTET_STRING;
- osalt = NULL;
-
- /* If its RC2 then we'd better setup the key length */
+ /* If have a key len set it up */
- if (alg_nid == NID_rc2_cbc) {
+ if (keylen > 0) {
if (!(kdf->keylength = M_ASN1_INTEGER_new()))
goto merr;
- if (!ASN1_INTEGER_set(kdf->keylength, EVP_CIPHER_key_length(cipher)))
+ if (!ASN1_INTEGER_set(kdf->keylength, keylen))
goto merr;
}
- /* prf can stay NULL because we are using hmacWithSHA1 */
-
- /* Now setup the PBE2PARAM keyfunc structure */
-
- pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
+ /* prf can stay NULL if we are using hmacWithSHA1 */
+ if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
+ kdf->prf = X509_ALGOR_new();
+ if (!kdf->prf)
+ goto merr;
+ X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL);
+ }
- /* Encode PBKDF2PARAM into parameter of pbe2 */
+ /* Finally setup the keyfunc structure */
- if (!(pbe2->keyfunc->parameter = ASN1_TYPE_new()))
+ keyfunc = X509_ALGOR_new();
+ if (!keyfunc)
goto merr;
- if (!ASN1_pack_string_of(PBKDF2PARAM, kdf, i2d_PBKDF2PARAM,
- &pbe2->keyfunc->parameter->value.sequence))
- goto merr;
- pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;
-
- PBKDF2PARAM_free(kdf);
- kdf = NULL;
+ keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
- /* Now set up top level AlgorithmIdentifier */
+ /* Encode PBKDF2PARAM into parameter of pbe2 */
- if (!(ret = X509_ALGOR_new()))
- goto merr;
- if (!(ret->parameter = ASN1_TYPE_new()))
+ if (!(keyfunc->parameter = ASN1_TYPE_new()))
goto merr;
- ret->algorithm = OBJ_nid2obj(NID_pbes2);
-
- /* Encode PBE2PARAM into parameter */
-
- if (!ASN1_pack_string_of(PBE2PARAM, pbe2, i2d_PBE2PARAM,
- &ret->parameter->value.sequence))
+ if (!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
+ &keyfunc->parameter->value.sequence))
goto merr;
- ret->parameter->type = V_ASN1_SEQUENCE;
-
- PBE2PARAM_free(pbe2);
- pbe2 = NULL;
+ keyfunc->parameter->type = V_ASN1_SEQUENCE;
- return ret;
+ PBKDF2PARAM_free(kdf);
+ return keyfunc;
merr:
- ASN1err(ASN1_F_PKCS5_PBE2_SET, ERR_R_MALLOC_FAILURE);
-
- err:
- PBE2PARAM_free(pbe2);
- /* Note 'scheme' is freed as part of pbe2 */
- M_ASN1_OCTET_STRING_free(osalt);
+ ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
PBKDF2PARAM_free(kdf);
- X509_ALGOR_free(kalg);
- X509_ALGOR_free(ret);
-
+ X509_ALGOR_free(keyfunc);
return NULL;
-
}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/p8_pkey.c b/Cryptlib/OpenSSL/crypto/asn1/p8_pkey.c
index 6cd36ce8..0a425cd2 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/p8_pkey.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/p8_pkey.c
@@ -4,7 +4,7 @@
* 1999.
*/
/* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -63,7 +63,8 @@
#include <openssl/x509.h>
/* Minor tweak to operation: zero private key data */
-static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
{
/* Since the structure must still be valid use ASN1_OP_FREE_PRE */
if (operation == ASN1_OP_FREE_PRE) {
@@ -84,3 +85,61 @@ ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+ int version,
+ int ptype, void *pval, unsigned char *penc, int penclen)
+{
+ unsigned char **ppenc = NULL;
+ if (version >= 0) {
+ if (!ASN1_INTEGER_set(priv->version, version))
+ return 0;
+ }
+ if (penc) {
+ int pmtype;
+ ASN1_OCTET_STRING *oct;
+ oct = ASN1_OCTET_STRING_new();
+ if (!oct)
+ return 0;
+ oct->data = penc;
+ ppenc = &oct->data;
+ oct->length = penclen;
+ if (priv->broken == PKCS8_NO_OCTET)
+ pmtype = V_ASN1_SEQUENCE;
+ else
+ pmtype = V_ASN1_OCTET_STRING;
+ ASN1_TYPE_set(priv->pkey, pmtype, oct);
+ }
+ if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) {
+ /* If call fails do not swallow 'enc' */
+ if (ppenc)
+ *ppenc = NULL;
+ return 0;
+ }
+ return 1;
+}
+
+int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+ const unsigned char **pk, int *ppklen,
+ X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8)
+{
+ if (ppkalg)
+ *ppkalg = p8->pkeyalg->algorithm;
+ if (p8->pkey->type == V_ASN1_OCTET_STRING) {
+ p8->broken = PKCS8_OK;
+ if (pk) {
+ *pk = p8->pkey->value.octet_string->data;
+ *ppklen = p8->pkey->value.octet_string->length;
+ }
+ } else if (p8->pkey->type == V_ASN1_SEQUENCE) {
+ p8->broken = PKCS8_NO_OCTET;
+ if (pk) {
+ *pk = p8->pkey->value.sequence->data;
+ *ppklen = p8->pkey->value.sequence->length;
+ }
+ } else
+ return 0;
+ if (pa)
+ *pa = p8->pkeyalg;
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/t_crl.c b/Cryptlib/OpenSSL/crypto/asn1/t_crl.c
index 75a753b8..0dfaf0ba 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/t_crl.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_crl.c
@@ -94,8 +94,7 @@ int X509_CRL_print(BIO *out, X509_CRL *x)
l = X509_CRL_get_version(x);
BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l);
i = OBJ_obj2nid(x->sig_alg->algorithm);
- BIO_printf(out, "%8sSignature Algorithm: %s\n", "",
- (i == NID_undef) ? "NONE" : OBJ_nid2ln(i));
+ X509_signature_print(out, x->sig_alg, NULL);
p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0);
BIO_printf(out, "%8sIssuer: %s\n", "", p);
OPENSSL_free(p);
diff --git a/Cryptlib/OpenSSL/crypto/asn1/t_pkey.c b/Cryptlib/OpenSSL/crypto/asn1/t_pkey.c
index 4821821b..735c3426 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/t_pkey.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_pkey.c
@@ -55,487 +55,15 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- * Binary polynomial ECC support in OpenSSL originally developed by
- * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
- */
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/bn.h>
-#ifndef OPENSSL_NO_RSA
-# include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DH
-# include <openssl/dh.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-# include <openssl/dsa.h>
-#endif
-#ifndef OPENSSL_NO_EC
-# include <openssl/ec.h>
-#endif
-
-static int print(BIO *fp, const char *str, const BIGNUM *num,
- unsigned char *buf, int off);
-#ifndef OPENSSL_NO_EC
-static int print_bin(BIO *fp, const char *str, const unsigned char *num,
- size_t len, int off);
-#endif
-#ifndef OPENSSL_NO_RSA
-# ifndef OPENSSL_NO_FP_API
-int RSA_print_fp(FILE *fp, const RSA *x, int off)
-{
- BIO *b;
- int ret;
-
- if ((b = BIO_new(BIO_s_file())) == NULL) {
- RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB);
- return (0);
- }
- BIO_set_fp(b, fp, BIO_NOCLOSE);
- ret = RSA_print(b, x, off);
- BIO_free(b);
- return (ret);
-}
-# endif
-
-int RSA_print(BIO *bp, const RSA *x, int off)
-{
- char str[128];
- const char *s;
- unsigned char *m = NULL;
- int ret = 0, mod_len = 0;
- size_t buf_len = 0, i;
-
- if (x->n)
- buf_len = (size_t)BN_num_bytes(x->n);
- if (x->e)
- if (buf_len < (i = (size_t)BN_num_bytes(x->e)))
- buf_len = i;
- if (x->d)
- if (buf_len < (i = (size_t)BN_num_bytes(x->d)))
- buf_len = i;
- if (x->p)
- if (buf_len < (i = (size_t)BN_num_bytes(x->p)))
- buf_len = i;
- if (x->q)
- if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
- buf_len = i;
- if (x->dmp1)
- if (buf_len < (i = (size_t)BN_num_bytes(x->dmp1)))
- buf_len = i;
- if (x->dmq1)
- if (buf_len < (i = (size_t)BN_num_bytes(x->dmq1)))
- buf_len = i;
- if (x->iqmp)
- if (buf_len < (i = (size_t)BN_num_bytes(x->iqmp)))
- buf_len = i;
-
- m = (unsigned char *)OPENSSL_malloc(buf_len + 10);
- if (m == NULL) {
- RSAerr(RSA_F_RSA_PRINT, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (x->n != NULL)
- mod_len = BN_num_bits(x->n);
-
- if (x->d != NULL) {
- if (!BIO_indent(bp, off, 128))
- goto err;
- if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len)
- <= 0)
- goto err;
- }
-
- if (x->d == NULL)
- BIO_snprintf(str, sizeof str, "Modulus (%d bit):", mod_len);
- else
- BUF_strlcpy(str, "modulus:", sizeof str);
- if (!print(bp, str, x->n, m, off))
- goto err;
- s = (x->d == NULL) ? "Exponent:" : "publicExponent:";
- if ((x->e != NULL) && !print(bp, s, x->e, m, off))
- goto err;
- if ((x->d != NULL) && !print(bp, "privateExponent:", x->d, m, off))
- goto err;
- if ((x->p != NULL) && !print(bp, "prime1:", x->p, m, off))
- goto err;
- if ((x->q != NULL) && !print(bp, "prime2:", x->q, m, off))
- goto err;
- if ((x->dmp1 != NULL) && !print(bp, "exponent1:", x->dmp1, m, off))
- goto err;
- if ((x->dmq1 != NULL) && !print(bp, "exponent2:", x->dmq1, m, off))
- goto err;
- if ((x->iqmp != NULL) && !print(bp, "coefficient:", x->iqmp, m, off))
- goto err;
- ret = 1;
- err:
- if (m != NULL)
- OPENSSL_free(m);
- return (ret);
-}
-#endif /* OPENSSL_NO_RSA */
-
-#ifndef OPENSSL_NO_DSA
-# ifndef OPENSSL_NO_FP_API
-int DSA_print_fp(FILE *fp, const DSA *x, int off)
-{
- BIO *b;
- int ret;
-
- if ((b = BIO_new(BIO_s_file())) == NULL) {
- DSAerr(DSA_F_DSA_PRINT_FP, ERR_R_BUF_LIB);
- return (0);
- }
- BIO_set_fp(b, fp, BIO_NOCLOSE);
- ret = DSA_print(b, x, off);
- BIO_free(b);
- return (ret);
-}
-# endif
-
-int DSA_print(BIO *bp, const DSA *x, int off)
-{
- unsigned char *m = NULL;
- int ret = 0;
- size_t buf_len = 0, i;
-
- if (x->p)
- buf_len = (size_t)BN_num_bytes(x->p);
- if (x->q)
- if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
- buf_len = i;
- if (x->g)
- if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
- buf_len = i;
- if (x->priv_key)
- if (buf_len < (i = (size_t)BN_num_bytes(x->priv_key)))
- buf_len = i;
- if (x->pub_key)
- if (buf_len < (i = (size_t)BN_num_bytes(x->pub_key)))
- buf_len = i;
-
- m = (unsigned char *)OPENSSL_malloc(buf_len + 10);
- if (m == NULL) {
- DSAerr(DSA_F_DSA_PRINT, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (x->priv_key != NULL) {
- if (!BIO_indent(bp, off, 128))
- goto err;
- if (BIO_printf(bp, "Private-Key: (%d bit)\n", BN_num_bits(x->p))
- <= 0)
- goto err;
- }
-
- if ((x->priv_key != NULL) && !print(bp, "priv:", x->priv_key, m, off))
- goto err;
- if ((x->pub_key != NULL) && !print(bp, "pub: ", x->pub_key, m, off))
- goto err;
- if ((x->p != NULL) && !print(bp, "P: ", x->p, m, off))
- goto err;
- if ((x->q != NULL) && !print(bp, "Q: ", x->q, m, off))
- goto err;
- if ((x->g != NULL) && !print(bp, "G: ", x->g, m, off))
- goto err;
- ret = 1;
- err:
- if (m != NULL)
- OPENSSL_free(m);
- return (ret);
-}
-#endif /* !OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_EC
-# ifndef OPENSSL_NO_FP_API
-int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
-{
- BIO *b;
- int ret;
-
- if ((b = BIO_new(BIO_s_file())) == NULL) {
- ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB);
- return (0);
- }
- BIO_set_fp(b, fp, BIO_NOCLOSE);
- ret = ECPKParameters_print(b, x, off);
- BIO_free(b);
- return (ret);
-}
-
-int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
-{
- BIO *b;
- int ret;
-
- if ((b = BIO_new(BIO_s_file())) == NULL) {
- ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
- return (0);
- }
- BIO_set_fp(b, fp, BIO_NOCLOSE);
- ret = EC_KEY_print(b, x, off);
- BIO_free(b);
- return (ret);
-}
-# endif
-
-int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
-{
- unsigned char *buffer = NULL;
- size_t buf_len = 0, i;
- int ret = 0, reason = ERR_R_BIO_LIB;
- BN_CTX *ctx = NULL;
- const EC_POINT *point = NULL;
- BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL,
- *order = NULL, *cofactor = NULL;
- const unsigned char *seed;
- size_t seed_len = 0;
-
- static const char *gen_compressed = "Generator (compressed):";
- static const char *gen_uncompressed = "Generator (uncompressed):";
- static const char *gen_hybrid = "Generator (hybrid):";
-
- if (!x) {
- reason = ERR_R_PASSED_NULL_PARAMETER;
- goto err;
- }
-
- if (EC_GROUP_get_asn1_flag(x)) {
- /* the curve parameter are given by an asn1 OID */
- int nid;
-
- if (!BIO_indent(bp, off, 128))
- goto err;
-
- nid = EC_GROUP_get_curve_name(x);
- if (nid == 0)
- goto err;
-
- if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
- goto err;
- if (BIO_printf(bp, "\n") <= 0)
- goto err;
- } else {
- /* explicit parameters */
- int is_char_two = 0;
- point_conversion_form_t form;
- int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
-
- if (tmp_nid == NID_X9_62_characteristic_two_field)
- is_char_two = 1;
-
- if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
- (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
- (cofactor = BN_new()) == NULL) {
- reason = ERR_R_MALLOC_FAILURE;
- goto err;
- }
-
- if (is_char_two) {
- if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) {
- reason = ERR_R_EC_LIB;
- goto err;
- }
- } else { /* prime field */
-
- if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) {
- reason = ERR_R_EC_LIB;
- goto err;
- }
- }
-
- if ((point = EC_GROUP_get0_generator(x)) == NULL) {
- reason = ERR_R_EC_LIB;
- goto err;
- }
- if (!EC_GROUP_get_order(x, order, NULL) ||
- !EC_GROUP_get_cofactor(x, cofactor, NULL)) {
- reason = ERR_R_EC_LIB;
- goto err;
- }
-
- form = EC_GROUP_get_point_conversion_form(x);
-
- if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) {
- reason = ERR_R_EC_LIB;
- goto err;
- }
-
- buf_len = (size_t)BN_num_bytes(p);
- if (buf_len < (i = (size_t)BN_num_bytes(a)))
- buf_len = i;
- if (buf_len < (i = (size_t)BN_num_bytes(b)))
- buf_len = i;
- if (buf_len < (i = (size_t)BN_num_bytes(gen)))
- buf_len = i;
- if (buf_len < (i = (size_t)BN_num_bytes(order)))
- buf_len = i;
- if (buf_len < (i = (size_t)BN_num_bytes(cofactor)))
- buf_len = i;
-
- if ((seed = EC_GROUP_get0_seed(x)) != NULL)
- seed_len = EC_GROUP_get_seed_len(x);
-
- buf_len += 10;
- if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
- reason = ERR_R_MALLOC_FAILURE;
- goto err;
- }
-
- if (!BIO_indent(bp, off, 128))
- goto err;
-
- /* print the 'short name' of the field type */
- if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
- <= 0)
- goto err;
-
- if (is_char_two) {
- /* print the 'short name' of the base type OID */
- int basis_type = EC_GROUP_get_basis_type(x);
- if (basis_type == 0)
- goto err;
-
- if (!BIO_indent(bp, off, 128))
- goto err;
-
- if (BIO_printf(bp, "Basis Type: %s\n",
- OBJ_nid2sn(basis_type)) <= 0)
- goto err;
-
- /* print the polynomial */
- if ((p != NULL) && !print(bp, "Polynomial:", p, buffer, off))
- goto err;
- } else {
- if ((p != NULL) && !print(bp, "Prime:", p, buffer, off))
- goto err;
- }
- if ((a != NULL) && !print(bp, "A: ", a, buffer, off))
- goto err;
- if ((b != NULL) && !print(bp, "B: ", b, buffer, off))
- goto err;
- if (form == POINT_CONVERSION_COMPRESSED) {
- if ((gen != NULL) && !print(bp, gen_compressed, gen, buffer, off))
- goto err;
- } else if (form == POINT_CONVERSION_UNCOMPRESSED) {
- if ((gen != NULL) && !print(bp, gen_uncompressed, gen,
- buffer, off))
- goto err;
- } else { /* form == POINT_CONVERSION_HYBRID */
-
- if ((gen != NULL) && !print(bp, gen_hybrid, gen, buffer, off))
- goto err;
- }
- if ((order != NULL) && !print(bp, "Order: ", order, buffer, off))
- goto err;
- if ((cofactor != NULL) && !print(bp, "Cofactor: ", cofactor,
- buffer, off))
- goto err;
- if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
- goto err;
- }
- ret = 1;
- err:
- if (!ret)
- ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
- if (p)
- BN_free(p);
- if (a)
- BN_free(a);
- if (b)
- BN_free(b);
- if (gen)
- BN_free(gen);
- if (order)
- BN_free(order);
- if (cofactor)
- BN_free(cofactor);
- if (ctx)
- BN_CTX_free(ctx);
- if (buffer != NULL)
- OPENSSL_free(buffer);
- return (ret);
-}
-
-int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
-{
- unsigned char *buffer = NULL;
- size_t buf_len = 0, i;
- int ret = 0, reason = ERR_R_BIO_LIB;
- BIGNUM *pub_key = NULL, *order = NULL;
- BN_CTX *ctx = NULL;
- const EC_GROUP *group;
- const EC_POINT *public_key;
- const BIGNUM *priv_key;
-
- if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
- reason = ERR_R_PASSED_NULL_PARAMETER;
- goto err;
- }
-
- public_key = EC_KEY_get0_public_key(x);
- if ((pub_key = EC_POINT_point2bn(group, public_key,
- EC_KEY_get_conv_form(x), NULL,
- ctx)) == NULL) {
- reason = ERR_R_EC_LIB;
- goto err;
- }
-
- buf_len = (size_t)BN_num_bytes(pub_key);
- priv_key = EC_KEY_get0_private_key(x);
- if (priv_key != NULL) {
- if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len)
- buf_len = i;
- }
-
- buf_len += 10;
- if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
- reason = ERR_R_MALLOC_FAILURE;
- goto err;
- }
- if (priv_key != NULL) {
- if (!BIO_indent(bp, off, 128))
- goto err;
- if ((order = BN_new()) == NULL)
- goto err;
- if (!EC_GROUP_get_order(group, order, NULL))
- goto err;
- if (BIO_printf(bp, "Private-Key: (%d bit)\n",
- BN_num_bits(order)) <= 0)
- goto err;
- }
-
- if ((priv_key != NULL) && !print(bp, "priv:", priv_key, buffer, off))
- goto err;
- if ((pub_key != NULL) && !print(bp, "pub: ", pub_key, buffer, off))
- goto err;
- if (!ECPKParameters_print(bp, group, off))
- goto err;
- ret = 1;
- err:
- if (!ret)
- ECerr(EC_F_EC_KEY_PRINT, reason);
- if (pub_key)
- BN_free(pub_key);
- if (order)
- BN_free(order);
- if (ctx)
- BN_CTX_free(ctx);
- if (buffer != NULL)
- OPENSSL_free(buffer);
- return (ret);
-}
-#endif /* OPENSSL_NO_EC */
-
-static int print(BIO *bp, const char *number, const BIGNUM *num,
- unsigned char *buf, int off)
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+ unsigned char *buf, int off)
{
int n, i;
const char *neg;
@@ -583,216 +111,3 @@ static int print(BIO *bp, const char *number, const BIGNUM *num,
}
return (1);
}
-
-#ifndef OPENSSL_NO_EC
-static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
- size_t len, int off)
-{
- size_t i;
- char str[128];
-
- if (buf == NULL)
- return 1;
- if (off) {
- if (off > 128)
- off = 128;
- memset(str, ' ', off);
- if (BIO_write(fp, str, off) <= 0)
- return 0;
- }
-
- if (BIO_printf(fp, "%s", name) <= 0)
- return 0;
-
- for (i = 0; i < len; i++) {
- if ((i % 15) == 0) {
- str[0] = '\n';
- memset(&(str[1]), ' ', off + 4);
- if (BIO_write(fp, str, off + 1 + 4) <= 0)
- return 0;
- }
- if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <=
- 0)
- return 0;
- }
- if (BIO_write(fp, "\n", 1) <= 0)
- return 0;
-
- return 1;
-}
-#endif
-
-#ifndef OPENSSL_NO_DH
-# ifndef OPENSSL_NO_FP_API
-int DHparams_print_fp(FILE *fp, const DH *x)
-{
- BIO *b;
- int ret;
-
- if ((b = BIO_new(BIO_s_file())) == NULL) {
- DHerr(DH_F_DHPARAMS_PRINT_FP, ERR_R_BUF_LIB);
- return (0);
- }
- BIO_set_fp(b, fp, BIO_NOCLOSE);
- ret = DHparams_print(b, x);
- BIO_free(b);
- return (ret);
-}
-# endif
-
-int DHparams_print(BIO *bp, const DH *x)
-{
- unsigned char *m = NULL;
- int reason = ERR_R_BUF_LIB, ret = 0;
- size_t buf_len = 0, i;
-
- if (x->p)
- buf_len = (size_t)BN_num_bytes(x->p);
- else {
- reason = ERR_R_PASSED_NULL_PARAMETER;
- goto err;
- }
- if (x->g)
- if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
- buf_len = i;
- m = (unsigned char *)OPENSSL_malloc(buf_len + 10);
- if (m == NULL) {
- reason = ERR_R_MALLOC_FAILURE;
- goto err;
- }
-
- if (BIO_printf(bp, "Diffie-Hellman-Parameters: (%d bit)\n",
- BN_num_bits(x->p)) <= 0)
- goto err;
- if (!print(bp, "prime:", x->p, m, 4))
- goto err;
- if (!print(bp, "generator:", x->g, m, 4))
- goto err;
- if (x->length != 0) {
- if (BIO_printf(bp, " recommended-private-length: %d bits\n",
- (int)x->length) <= 0)
- goto err;
- }
- ret = 1;
- if (0) {
- err:
- DHerr(DH_F_DHPARAMS_PRINT, reason);
- }
- if (m != NULL)
- OPENSSL_free(m);
- return (ret);
-}
-#endif
-
-#ifndef OPENSSL_NO_DSA
-# ifndef OPENSSL_NO_FP_API
-int DSAparams_print_fp(FILE *fp, const DSA *x)
-{
- BIO *b;
- int ret;
-
- if ((b = BIO_new(BIO_s_file())) == NULL) {
- DSAerr(DSA_F_DSAPARAMS_PRINT_FP, ERR_R_BUF_LIB);
- return (0);
- }
- BIO_set_fp(b, fp, BIO_NOCLOSE);
- ret = DSAparams_print(b, x);
- BIO_free(b);
- return (ret);
-}
-# endif
-
-int DSAparams_print(BIO *bp, const DSA *x)
-{
- unsigned char *m = NULL;
- int ret = 0;
- size_t buf_len = 0, i;
-
- if (x->p)
- buf_len = (size_t)BN_num_bytes(x->p);
- else {
- DSAerr(DSA_F_DSAPARAMS_PRINT, DSA_R_MISSING_PARAMETERS);
- goto err;
- }
- if (x->q)
- if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
- buf_len = i;
- if (x->g)
- if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
- buf_len = i;
- m = (unsigned char *)OPENSSL_malloc(buf_len + 10);
- if (m == NULL) {
- DSAerr(DSA_F_DSAPARAMS_PRINT, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (BIO_printf(bp, "DSA-Parameters: (%d bit)\n", BN_num_bits(x->p)) <= 0)
- goto err;
- if (!print(bp, "p:", x->p, m, 4))
- goto err;
- if ((x->q != NULL) && !print(bp, "q:", x->q, m, 4))
- goto err;
- if ((x->g != NULL) && !print(bp, "g:", x->g, m, 4))
- goto err;
- ret = 1;
- err:
- if (m != NULL)
- OPENSSL_free(m);
- return (ret);
-}
-
-#endif /* !OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_EC
-# ifndef OPENSSL_NO_FP_API
-int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
-{
- BIO *b;
- int ret;
-
- if ((b = BIO_new(BIO_s_file())) == NULL) {
- ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
- return (0);
- }
- BIO_set_fp(b, fp, BIO_NOCLOSE);
- ret = ECParameters_print(b, x);
- BIO_free(b);
- return (ret);
-}
-# endif
-
-int ECParameters_print(BIO *bp, const EC_KEY *x)
-{
- int reason = ERR_R_EC_LIB, ret = 0;
- BIGNUM *order = NULL;
- const EC_GROUP *group;
-
- if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
- reason = ERR_R_PASSED_NULL_PARAMETER;;
- goto err;
- }
-
- if ((order = BN_new()) == NULL) {
- reason = ERR_R_MALLOC_FAILURE;
- goto err;
- }
-
- if (!EC_GROUP_get_order(group, order, NULL)) {
- reason = ERR_R_EC_LIB;
- goto err;
- }
-
- if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n",
- BN_num_bits(order)) <= 0)
- goto err;
- if (!ECPKParameters_print(bp, group, 4))
- goto err;
- ret = 1;
- err:
- if (order)
- BN_free(order);
- ECerr(EC_F_ECPARAMETERS_PRINT, reason);
- return (ret);
-}
-
-#endif
diff --git a/Cryptlib/OpenSSL/crypto/asn1/t_req.c b/Cryptlib/OpenSSL/crypto/asn1/t_req.c
index b578b685..024553ab 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/t_req.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_req.c
@@ -148,29 +148,10 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
if (pkey == NULL) {
BIO_printf(bp, "%12sUnable to load Public Key\n", "");
ERR_print_errors(bp);
- } else
-#ifndef OPENSSL_NO_RSA
- if (pkey->type == EVP_PKEY_RSA) {
- BIO_printf(bp, "%12sRSA Public Key: (%d bit)\n", "",
- BN_num_bits(pkey->pkey.rsa->n));
- RSA_print(bp, pkey->pkey.rsa, 16);
- } else
-#endif
-#ifndef OPENSSL_NO_DSA
- if (pkey->type == EVP_PKEY_DSA) {
- BIO_printf(bp, "%12sDSA Public Key:\n", "");
- DSA_print(bp, pkey->pkey.dsa, 16);
- } else
-#endif
-#ifndef OPENSSL_NO_EC
- if (pkey->type == EVP_PKEY_EC) {
- BIO_printf(bp, "%12sEC Public Key: \n", "");
- EC_KEY_print(bp, pkey->pkey.ec, 16);
- } else
-#endif
- BIO_printf(bp, "%12sUnknown Public Key:\n", "");
-
- EVP_PKEY_free(pkey);
+ } else {
+ EVP_PKEY_print_public(bp, pkey, 16, NULL);
+ EVP_PKEY_free(pkey);
+ }
}
if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
diff --git a/Cryptlib/OpenSSL/crypto/asn1/t_spki.c b/Cryptlib/OpenSSL/crypto/asn1/t_spki.c
index b0ce0891..3bf48db5 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/t_spki.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_spki.c
@@ -85,27 +85,7 @@ int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
if (!pkey)
BIO_printf(out, " Unable to load public key\n");
else {
-#ifndef OPENSSL_NO_RSA
- if (pkey->type == EVP_PKEY_RSA) {
- BIO_printf(out, " RSA Public Key: (%d bit)\n",
- BN_num_bits(pkey->pkey.rsa->n));
- RSA_print(out, pkey->pkey.rsa, 2);
- } else
-#endif
-#ifndef OPENSSL_NO_DSA
- if (pkey->type == EVP_PKEY_DSA) {
- BIO_printf(out, " DSA Public Key:\n");
- DSA_print(out, pkey->pkey.dsa, 2);
- } else
-#endif
-#ifndef OPENSSL_NO_EC
- if (pkey->type == EVP_PKEY_EC) {
- BIO_printf(out, " EC Public Key:\n");
- EC_KEY_print(out, pkey->pkey.ec, 2);
- } else
-#endif
-
- BIO_printf(out, " Unknown Public Key:\n");
+ EVP_PKEY_print_public(out, pkey, 4, NULL);
EVP_PKEY_free(pkey);
}
chal = spki->spkac->challenge;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/t_x509.c b/Cryptlib/OpenSSL/crypto/asn1/t_x509.c
index 53f631d1..8aab5513 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/t_x509.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_x509.c
@@ -72,6 +72,7 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
+#include "asn1_locl.h"
#ifndef OPENSSL_NO_FP_API
int X509_print_fp(FILE *fp, X509 *x)
@@ -112,7 +113,6 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
ASN1_INTEGER *bs;
EVP_PKEY *pkey = NULL;
const char *neg;
- ASN1_STRING *str = NULL;
if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
mlch = '\n';
@@ -140,9 +140,9 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
goto err;
bs = X509_get_serialNumber(x);
- if (bs->length <= 4) {
+ if (bs->length <= (int)sizeof(long)) {
l = ASN1_INTEGER_get(bs);
- if (l < 0) {
+ if (bs->type == V_ASN1_NEG_INTEGER) {
l = -l;
neg = "-";
} else
@@ -164,12 +164,16 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
}
if (!(cflag & X509_FLAG_NO_SIGNAME)) {
+ if (X509_signature_print(bp, ci->signature, NULL) <= 0)
+ goto err;
+#if 0
if (BIO_printf(bp, "%8sSignature Algorithm: ", "") <= 0)
goto err;
if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
goto err;
if (BIO_puts(bp, "\n") <= 0)
goto err;
+#endif
}
if (!(cflag & X509_FLAG_NO_ISSUER)) {
@@ -218,29 +222,25 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
if (pkey == NULL) {
BIO_printf(bp, "%12sUnable to load Public Key\n", "");
ERR_print_errors(bp);
- } else
-#ifndef OPENSSL_NO_RSA
- if (pkey->type == EVP_PKEY_RSA) {
- BIO_printf(bp, "%12sRSA Public Key: (%d bit)\n", "",
- BN_num_bits(pkey->pkey.rsa->n));
- RSA_print(bp, pkey->pkey.rsa, 16);
- } else
-#endif
-#ifndef OPENSSL_NO_DSA
- if (pkey->type == EVP_PKEY_DSA) {
- BIO_printf(bp, "%12sDSA Public Key:\n", "");
- DSA_print(bp, pkey->pkey.dsa, 16);
- } else
-#endif
-#ifndef OPENSSL_NO_EC
- if (pkey->type == EVP_PKEY_EC) {
- BIO_printf(bp, "%12sEC Public Key:\n", "");
- EC_KEY_print(bp, pkey->pkey.ec, 16);
- } else
-#endif
- BIO_printf(bp, "%12sUnknown Public Key:\n", "");
+ } else {
+ EVP_PKEY_print_public(bp, pkey, 16, NULL);
+ EVP_PKEY_free(pkey);
+ }
+ }
- EVP_PKEY_free(pkey);
+ if (!(cflag & X509_FLAG_NO_IDS)) {
+ if (ci->issuerUID) {
+ if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0)
+ goto err;
+ if (!X509_signature_dump(bp, ci->issuerUID, 12))
+ goto err;
+ }
+ if (ci->subjectUID) {
+ if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0)
+ goto err;
+ if (!X509_signature_dump(bp, ci->subjectUID, 12))
+ goto err;
+ }
}
if (!(cflag & X509_FLAG_NO_EXTENSIONS))
@@ -257,8 +257,6 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
}
ret = 1;
err:
- if (str != NULL)
- ASN1_STRING_free(str);
if (m != NULL)
OPENSSL_free(m);
return (ret);
@@ -282,7 +280,8 @@ int X509_ocspid_print(BIO *bp, X509 *x)
goto err;
i2d_X509_NAME(x->cert_info->subject, &dertmp);
- EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL);
+ if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
+ goto err;
for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
goto err;
@@ -296,9 +295,10 @@ int X509_ocspid_print(BIO *bp, X509 *x)
if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0)
goto err;
- EVP_Digest(x->cert_info->key->public_key->data,
- x->cert_info->key->public_key->length, SHA1md, NULL,
- EVP_sha1(), NULL);
+ if (!EVP_Digest(x->cert_info->key->public_key->data,
+ x->cert_info->key->public_key->length,
+ SHA1md, NULL, EVP_sha1(), NULL))
+ goto err;
for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
goto err;
@@ -312,38 +312,64 @@ int X509_ocspid_print(BIO *bp, X509 *x)
return (0);
}
-int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
{
- unsigned char *s;
+ const unsigned char *s;
int i, n;
- if (BIO_puts(bp, " Signature Algorithm: ") <= 0)
- return 0;
- if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
- return 0;
n = sig->length;
s = sig->data;
for (i = 0; i < n; i++) {
- if ((i % 18) == 0)
- if (BIO_write(bp, "\n ", 9) <= 0)
+ if ((i % 18) == 0) {
+ if (BIO_write(bp, "\n", 1) <= 0)
return 0;
+ if (BIO_indent(bp, indent, indent) <= 0)
+ return 0;
+ }
if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0)
return 0;
}
if (BIO_write(bp, "\n", 1) != 1)
return 0;
+
return 1;
}
-int ASN1_STRING_print(BIO *bp, ASN1_STRING *v)
+int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
+{
+ int sig_nid;
+ if (BIO_puts(bp, " Signature Algorithm: ") <= 0)
+ return 0;
+ if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
+ return 0;
+
+ sig_nid = OBJ_obj2nid(sigalg->algorithm);
+ if (sig_nid != NID_undef) {
+ int pkey_nid, dig_nid;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) {
+ ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
+ if (ameth && ameth->sig_print)
+ return ameth->sig_print(bp, sigalg, sig, 9, 0);
+ }
+ }
+ if (sig)
+ return X509_signature_dump(bp, sig, 9);
+ else if (BIO_puts(bp, "\n") <= 0)
+ return 0;
+ return 1;
+}
+
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
{
int i, n;
- char buf[80], *p;
+ char buf[80];
+ const char *p;
if (v == NULL)
return (0);
n = 0;
- p = (char *)v->data;
+ p = (const char *)v->data;
for (i = 0; i < v->length; i++) {
if ((p[i] > '~') || ((p[i] < ' ') &&
(p[i] != '\n') && (p[i] != '\r')))
@@ -363,7 +389,7 @@ int ASN1_STRING_print(BIO *bp, ASN1_STRING *v)
return (1);
}
-int ASN1_TIME_print(BIO *bp, ASN1_TIME *tm)
+int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
{
if (tm->type == V_ASN1_UTCTIME)
return ASN1_UTCTIME_print(bp, tm);
@@ -378,7 +404,7 @@ static const char *mon[12] = {
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
-int ASN1_GENERALIZEDTIME_print(BIO *bp, ASN1_GENERALIZEDTIME *tm)
+int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
{
char *v;
int gmt = 0;
@@ -430,15 +456,15 @@ int ASN1_GENERALIZEDTIME_print(BIO *bp, ASN1_GENERALIZEDTIME *tm)
return (0);
}
-int ASN1_UTCTIME_print(BIO *bp, ASN1_UTCTIME *tm)
+int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
{
- char *v;
+ const char *v;
int gmt = 0;
int i;
int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
i = tm->length;
- v = (char *)tm->data;
+ v = (const char *)tm->data;
if (i < 10)
goto err;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c
index 6e4a3252..7fd336a4 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c
@@ -124,6 +124,8 @@ unsigned long ASN1_tag2bit(int tag)
/* Macro to initialize and invalidate the cache */
#define asn1_tlc_clear(c) if (c) (c)->valid = 0
+/* Version to avoid compiler warning about 'c' always non-NULL */
+#define asn1_tlc_clear_nc(c) (c)->valid = 0
/*
* Decode an ASN1 item, this currently behaves just like a standard 'd2i'
@@ -140,7 +142,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
ASN1_VALUE *ptmpval = NULL;
if (!pval)
pval = &ptmpval;
- c.valid = 0;
+ asn1_tlc_clear_nc(&c);
if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
return *pval;
return NULL;
@@ -151,7 +153,7 @@ int ASN1_template_d2i(ASN1_VALUE **pval,
const ASN1_TEMPLATE *tt)
{
ASN1_TLC c;
- c.valid = 0;
+ asn1_tlc_clear_nc(&c);
return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
}
@@ -300,7 +302,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
goto err;
case ASN1_ITYPE_CHOICE:
- if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
+ if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
goto auxerr;
if (*pval) {
/* Free up and zero CHOICE value if initialised */
@@ -349,7 +351,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
asn1_set_choice_selector(pval, i, it);
*in = p;
- if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it))
+ if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
goto auxerr;
return 1;
@@ -388,7 +390,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
goto err;
}
- if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
+ if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
goto auxerr;
/* Free up and zero any ADB found */
@@ -488,7 +490,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
if (!asn1_enc_save(pval, *in, p - *in, it))
goto auxerr;
*in = p;
- if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it))
+ if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
goto auxerr;
return 1;
@@ -629,10 +631,10 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
/*
* We've got a valid STACK: free up any items present
*/
- STACK *sktmp = (STACK *) * val;
+ STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val;
ASN1_VALUE *vtmp;
- while (sk_num(sktmp) > 0) {
- vtmp = (ASN1_VALUE *)sk_pop(sktmp);
+ while (sk_ASN1_VALUE_num(sktmp) > 0) {
+ vtmp = sk_ASN1_VALUE_pop(sktmp);
ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
}
}
@@ -665,7 +667,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
goto err;
}
len -= p - q;
- if (!sk_push((STACK *) * val, (char *)skfield)) {
+ if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
goto err;
}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c
index b93f3f69..f04a6892 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c
@@ -153,7 +153,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
case ASN1_ITYPE_CHOICE:
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))
+ if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
return 0;
i = asn1_get_choice_selector(pval, it);
if ((i >= 0) && (i < it->tcount)) {
@@ -164,7 +164,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass);
}
/* Fixme: error condition if selector out of range */
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it))
+ if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
return 0;
break;
@@ -210,7 +210,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
| V_ASN1_UNIVERSAL;
}
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))
+ if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
return 0;
/* First work out sequence content length */
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
@@ -242,7 +242,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
}
if (ndef == 2)
ASN1_put_eoc(out);
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it))
+ if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
return 0;
return seqlen;
@@ -545,7 +545,8 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
ASN1_STRING *strtmp;
ASN1_OBJECT *otmp;
int utype;
- unsigned char *cont, c;
+ const unsigned char *cont;
+ unsigned char c;
int len;
const ASN1_PRIMITIVE_FUNCS *pf;
pf = it->funcs;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_fre.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_fre.c
index a56d89b6..aeea4eff 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/tasn_fre.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_fre.c
@@ -110,7 +110,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
case ASN1_ITYPE_CHOICE:
if (asn1_cb) {
- i = asn1_cb(ASN1_OP_FREE_PRE, pval, it);
+ i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
}
@@ -122,7 +122,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
ASN1_template_free(pchval, tt);
}
if (asn1_cb)
- asn1_cb(ASN1_OP_FREE_POST, pval, it);
+ asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine) {
OPENSSL_free(*pval);
*pval = NULL;
@@ -146,7 +146,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
if (asn1_do_lock(pval, -1, it) > 0)
return;
if (asn1_cb) {
- i = asn1_cb(ASN1_OP_FREE_PRE, pval, it);
+ i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
}
@@ -166,7 +166,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
ASN1_template_free(pseqval, seqtt);
}
if (asn1_cb)
- asn1_cb(ASN1_OP_FREE_POST, pval, it);
+ asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine) {
OPENSSL_free(*pval);
*pval = NULL;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_new.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_new.c
index 8c540cc7..b0c73bee 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/tasn_new.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_new.c
@@ -68,7 +68,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine);
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
-void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
{
@@ -100,9 +100,6 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
else
asn1_cb = 0;
- if (!combine)
- *pval = NULL;
-
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_push_info(it->sname);
@@ -142,7 +139,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
case ASN1_ITYPE_CHOICE:
if (asn1_cb) {
- i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);
+ i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i == 2) {
@@ -160,14 +157,14 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
memset(*pval, 0, it->size);
}
asn1_set_choice_selector(pval, -1, it);
- if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it))
+ if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
break;
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if (asn1_cb) {
- i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);
+ i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i == 2) {
@@ -191,7 +188,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
if (!ASN1_template_new(pseqval, tt))
goto memerr;
}
- if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it))
+ if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
break;
}
@@ -312,15 +309,19 @@ static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
ASN1_TYPE *typ;
+ ASN1_STRING *str;
int utype;
- if (it && it->funcs) {
+ if (!it)
+ return 0;
+
+ if (it->funcs) {
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_new)
return pf->prim_new(pval, it);
}
- if (!it || (it->itype == ASN1_ITYPE_MSTRING))
+ if (it->itype == ASN1_ITYPE_MSTRING)
utype = -1;
else
utype = it->utype;
@@ -330,10 +331,7 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
return 1;
case V_ASN1_BOOLEAN:
- if (it)
- *(ASN1_BOOLEAN *)pval = it->size;
- else
- *(ASN1_BOOLEAN *)pval = -1;
+ *(ASN1_BOOLEAN *)pval = it->size;
return 1;
case V_ASN1_NULL:
@@ -350,7 +348,10 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
break;
default:
- *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype);
+ str = ASN1_STRING_type_new(utype);
+ if (it->itype == ASN1_ITYPE_MSTRING && str)
+ str->flags |= ASN1_STRING_FLAG_MSTRING;
+ *pval = (ASN1_VALUE *)str;
break;
}
if (*pval)
@@ -358,7 +359,7 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
return 0;
}
-void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
int utype;
if (it && it->funcs) {
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_prn.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_prn.c
new file mode 100644
index 00000000..5e7d53e9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_prn.c
@@ -0,0 +1,585 @@
+/* tasn_prn.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stddef.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include "asn1_locl.h"
+
+/*
+ * Print routines.
+ */
+
+/* ASN1_PCTX routines */
+
+ASN1_PCTX default_pctx = {
+ ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
+ 0, /* nm_flags */
+ 0, /* cert_flags */
+ 0, /* oid_flags */
+ 0 /* str_flags */
+};
+
+ASN1_PCTX *ASN1_PCTX_new(void)
+{
+ ASN1_PCTX *ret;
+ ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
+ if (ret == NULL) {
+ ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ ret->flags = 0;
+ ret->nm_flags = 0;
+ ret->cert_flags = 0;
+ ret->oid_flags = 0;
+ ret->str_flags = 0;
+ return ret;
+}
+
+void ASN1_PCTX_free(ASN1_PCTX *p)
+{
+ OPENSSL_free(p);
+}
+
+unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
+{
+ return p->flags;
+}
+
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
+{
+ p->flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
+{
+ return p->nm_flags;
+}
+
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
+{
+ p->nm_flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
+{
+ return p->cert_flags;
+}
+
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
+{
+ p->cert_flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
+{
+ return p->oid_flags;
+}
+
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
+{
+ p->oid_flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
+{
+ return p->str_flags;
+}
+
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
+{
+ p->str_flags = flags;
+}
+
+/* Main print routines */
+
+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+ const ASN1_ITEM *it,
+ const char *fname, const char *sname,
+ int nohdr, const ASN1_PCTX *pctx);
+
+int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+ const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
+
+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+ const ASN1_ITEM *it, int indent,
+ const char *fname, const char *sname,
+ const ASN1_PCTX *pctx);
+
+static int asn1_print_fsname(BIO *out, int indent,
+ const char *fname, const char *sname,
+ const ASN1_PCTX *pctx);
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+ const ASN1_ITEM *it, const ASN1_PCTX *pctx)
+{
+ const char *sname;
+ if (pctx == NULL)
+ pctx = &default_pctx;
+ if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+ sname = NULL;
+ else
+ sname = it->sname;
+ return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
+}
+
+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+ const ASN1_ITEM *it,
+ const char *fname, const char *sname,
+ int nohdr, const ASN1_PCTX *pctx)
+{
+ const ASN1_TEMPLATE *tt;
+ const ASN1_EXTERN_FUNCS *ef;
+ ASN1_VALUE **tmpfld;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_aux_cb *asn1_cb;
+ ASN1_PRINT_ARG parg;
+ int i;
+ if (aux && aux->asn1_cb) {
+ parg.out = out;
+ parg.indent = indent;
+ parg.pctx = pctx;
+ asn1_cb = aux->asn1_cb;
+ } else
+ asn1_cb = 0;
+
+ if (*fld == NULL) {
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
+ if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+ return 0;
+ if (BIO_puts(out, "<ABSENT>\n") <= 0)
+ return 0;
+ }
+ return 1;
+ }
+
+ switch (it->itype) {
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates) {
+ if (!asn1_template_print_ctx(out, fld, indent,
+ it->templates, pctx))
+ return 0;
+ break;
+ }
+ /* fall thru */
+ case ASN1_ITYPE_MSTRING:
+ if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
+ return 0;
+ break;
+
+ case ASN1_ITYPE_EXTERN:
+ if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+ return 0;
+ /* Use new style print routine if possible */
+ ef = it->funcs;
+ if (ef && ef->asn1_ex_print) {
+ i = ef->asn1_ex_print(out, fld, indent, "", pctx);
+ if (!i)
+ return 0;
+ if ((i == 2) && (BIO_puts(out, "\n") <= 0))
+ return 0;
+ return 1;
+ } else if (sname &&
+ BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
+ return 0;
+ break;
+
+ case ASN1_ITYPE_CHOICE:
+#if 0
+ if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+ return 0;
+#endif
+ /* CHOICE type, get selector */
+ i = asn1_get_choice_selector(fld, it);
+ /* This should never happen... */
+ if ((i < 0) || (i >= it->tcount)) {
+ if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
+ return 0;
+ return 1;
+ }
+ tt = it->templates + i;
+ tmpfld = asn1_get_field_ptr(fld, tt);
+ if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
+ return 0;
+ break;
+
+ case ASN1_ITYPE_SEQUENCE:
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+ return 0;
+ if (fname || sname) {
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+ if (BIO_puts(out, " {\n") <= 0)
+ return 0;
+ } else {
+ if (BIO_puts(out, "\n") <= 0)
+ return 0;
+ }
+ }
+
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
+ if (i == 0)
+ return 0;
+ if (i == 2)
+ return 1;
+ }
+
+ /* Print each field entry */
+ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+ const ASN1_TEMPLATE *seqtt;
+ seqtt = asn1_do_adb(fld, tt, 1);
+ if (!seqtt)
+ return 0;
+ tmpfld = asn1_get_field_ptr(fld, seqtt);
+ if (!asn1_template_print_ctx(out, tmpfld,
+ indent + 2, seqtt, pctx))
+ return 0;
+ }
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+ if (BIO_printf(out, "%*s}\n", indent, "") < 0)
+ return 0;
+ }
+
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
+ if (i == 0)
+ return 0;
+ }
+ break;
+
+ default:
+ BIO_printf(out, "Unprocessed type %d\n", it->itype);
+ return 0;
+ }
+
+ return 1;
+}
+
+int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+ const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
+{
+ int i, flags;
+ const char *sname, *fname;
+ flags = tt->flags;
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
+ sname = ASN1_ITEM_ptr(tt->item)->sname;
+ else
+ sname = NULL;
+ if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+ fname = NULL;
+ else
+ fname = tt->field_name;
+ if (flags & ASN1_TFLG_SK_MASK) {
+ char *tname;
+ ASN1_VALUE *skitem;
+ STACK_OF(ASN1_VALUE) *stack;
+
+ /* SET OF, SEQUENCE OF */
+ if (fname) {
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
+ if (flags & ASN1_TFLG_SET_OF)
+ tname = "SET";
+ else
+ tname = "SEQUENCE";
+ if (BIO_printf(out, "%*s%s OF %s {\n",
+ indent, "", tname, tt->field_name) <= 0)
+ return 0;
+ } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
+ return 0;
+ }
+ stack = (STACK_OF(ASN1_VALUE) *)*fld;
+ for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
+ if ((i > 0) && (BIO_puts(out, "\n") <= 0))
+ return 0;
+
+ skitem = sk_ASN1_VALUE_value(stack, i);
+ if (!asn1_item_print_ctx(out, &skitem, indent + 2,
+ ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
+ pctx))
+ return 0;
+ }
+ if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
+ return 0;
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+ if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
+ return 0;
+ }
+ return 1;
+ }
+ return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
+ fname, sname, 0, pctx);
+}
+
+static int asn1_print_fsname(BIO *out, int indent,
+ const char *fname, const char *sname,
+ const ASN1_PCTX *pctx)
+{
+ static char spaces[] = " ";
+ const int nspaces = sizeof(spaces) - 1;
+
+#if 0
+ if (!sname && !fname)
+ return 1;
+#endif
+
+ while (indent > nspaces) {
+ if (BIO_write(out, spaces, nspaces) != nspaces)
+ return 0;
+ indent -= nspaces;
+ }
+ if (BIO_write(out, spaces, indent) != indent)
+ return 0;
+ if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+ sname = NULL;
+ if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+ fname = NULL;
+ if (!sname && !fname)
+ return 1;
+ if (fname) {
+ if (BIO_puts(out, fname) <= 0)
+ return 0;
+ }
+ if (sname) {
+ if (fname) {
+ if (BIO_printf(out, " (%s)", sname) <= 0)
+ return 0;
+ } else {
+ if (BIO_puts(out, sname) <= 0)
+ return 0;
+ }
+ }
+ if (BIO_write(out, ": ", 2) != 2)
+ return 0;
+ return 1;
+}
+
+static int asn1_print_boolean_ctx(BIO *out, int boolval,
+ const ASN1_PCTX *pctx)
+{
+ const char *str;
+ switch (boolval) {
+ case -1:
+ str = "BOOL ABSENT";
+ break;
+
+ case 0:
+ str = "FALSE";
+ break;
+
+ default:
+ str = "TRUE";
+ break;
+
+ }
+
+ if (BIO_puts(out, str) <= 0)
+ return 0;
+ return 1;
+
+}
+
+static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
+ const ASN1_PCTX *pctx)
+{
+ char *s;
+ int ret = 1;
+ s = i2s_ASN1_INTEGER(NULL, str);
+ if (BIO_puts(out, s) <= 0)
+ ret = 0;
+ OPENSSL_free(s);
+ return ret;
+}
+
+static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
+ const ASN1_PCTX *pctx)
+{
+ char objbuf[80];
+ const char *ln;
+ ln = OBJ_nid2ln(OBJ_obj2nid(oid));
+ if (!ln)
+ ln = "";
+ OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
+ if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
+ return 0;
+ return 1;
+}
+
+static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
+ const ASN1_PCTX *pctx)
+{
+ if (str->type == V_ASN1_BIT_STRING) {
+ if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
+ return 0;
+ } else if (BIO_puts(out, "\n") <= 0)
+ return 0;
+ if ((str->length > 0)
+ && BIO_dump_indent(out, (char *)str->data, str->length,
+ indent + 2) <= 0)
+ return 0;
+ return 1;
+}
+
+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+ const ASN1_ITEM *it, int indent,
+ const char *fname, const char *sname,
+ const ASN1_PCTX *pctx)
+{
+ long utype;
+ ASN1_STRING *str;
+ int ret = 1, needlf = 1;
+ const char *pname;
+ const ASN1_PRIMITIVE_FUNCS *pf;
+ pf = it->funcs;
+ if (!asn1_print_fsname(out, indent, fname, sname, pctx))
+ return 0;
+ if (pf && pf->prim_print)
+ return pf->prim_print(out, fld, it, indent, pctx);
+ str = (ASN1_STRING *)*fld;
+ if (it->itype == ASN1_ITYPE_MSTRING)
+ utype = str->type & ~V_ASN1_NEG;
+ else
+ utype = it->utype;
+ if (utype == V_ASN1_ANY) {
+ ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
+ utype = atype->type;
+ fld = &atype->value.asn1_value;
+ str = (ASN1_STRING *)*fld;
+ if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
+ pname = NULL;
+ else
+ pname = ASN1_tag2str(utype);
+ } else {
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
+ pname = ASN1_tag2str(utype);
+ else
+ pname = NULL;
+ }
+
+ if (utype == V_ASN1_NULL) {
+ if (BIO_puts(out, "NULL\n") <= 0)
+ return 0;
+ return 1;
+ }
+
+ if (pname) {
+ if (BIO_puts(out, pname) <= 0)
+ return 0;
+ if (BIO_puts(out, ":") <= 0)
+ return 0;
+ }
+
+ switch (utype) {
+ case V_ASN1_BOOLEAN:
+ {
+ int boolval = *(int *)fld;
+ if (boolval == -1)
+ boolval = it->size;
+ ret = asn1_print_boolean_ctx(out, boolval, pctx);
+ }
+ break;
+
+ case V_ASN1_INTEGER:
+ case V_ASN1_ENUMERATED:
+ ret = asn1_print_integer_ctx(out, str, pctx);
+ break;
+
+ case V_ASN1_UTCTIME:
+ ret = ASN1_UTCTIME_print(out, str);
+ break;
+
+ case V_ASN1_GENERALIZEDTIME:
+ ret = ASN1_GENERALIZEDTIME_print(out, str);
+ break;
+
+ case V_ASN1_OBJECT:
+ ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
+ break;
+
+ case V_ASN1_OCTET_STRING:
+ case V_ASN1_BIT_STRING:
+ ret = asn1_print_obstring_ctx(out, str, indent, pctx);
+ needlf = 0;
+ break;
+
+ case V_ASN1_SEQUENCE:
+ case V_ASN1_SET:
+ case V_ASN1_OTHER:
+ if (BIO_puts(out, "\n") <= 0)
+ return 0;
+ if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
+ ret = 0;
+ needlf = 0;
+ break;
+
+ default:
+ ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
+
+ }
+ if (!ret)
+ return 0;
+ if (needlf && BIO_puts(out, "\n") <= 0)
+ return 0;
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_typ.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_typ.c
index 4820035b..740e86d5 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/tasn_typ.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_typ.c
@@ -136,3 +136,14 @@ IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
/* Special, OCTET STRING with indefinite length constructed support */
IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
+
+ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
+ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY)
+
+ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
+ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_algor.c b/Cryptlib/OpenSSL/crypto/asn1/x_algor.c
index babc2e17..fd7d16d4 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/x_algor.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_algor.c
@@ -121,6 +121,21 @@ void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
}
}
+/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
+
+void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
+{
+ int param_type;
+
+ if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
+ param_type = V_ASN1_UNDEF;
+ else
+ param_type = V_ASN1_NULL;
+
+ X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+
+}
+
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
{
int rv;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_crl.c b/Cryptlib/OpenSSL/crypto/asn1/x_crl.c
index 099b2646..02795033 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/x_crl.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_crl.c
@@ -59,10 +59,13 @@
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
+#include "asn1_locl.h"
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
const X509_REVOKED *const *b);
+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
ASN1_SEQUENCE(X509_REVOKED) = {
ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
@@ -70,12 +73,27 @@ ASN1_SEQUENCE(X509_REVOKED) = {
ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
} ASN1_SEQUENCE_END(X509_REVOKED)
+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
+static int def_crl_lookup(X509_CRL *crl,
+ X509_REVOKED **ret, ASN1_INTEGER *serial,
+ X509_NAME *issuer);
+
+static X509_CRL_METHOD int_crl_meth = {
+ 0,
+ 0, 0,
+ def_crl_lookup,
+ def_crl_verify
+};
+
+static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
+
/*
* The X509_CRL_INFO structure needs a bit of customisation. Since we cache
* the original encoding the signature wont be affected by reordering of the
* revoked field.
*/
-static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
{
X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
@@ -104,7 +122,218 @@ ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
-ASN1_SEQUENCE_ref(X509_CRL, 0, CRYPTO_LOCK_X509_CRL) = {
+/*
+ * Set CRL entry issuer according to CRL certificate issuer extension. Check
+ * for unhandled critical CRL entry extensions.
+ */
+
+static int crl_set_issuers(X509_CRL *crl)
+{
+
+ int i, j;
+ GENERAL_NAMES *gens, *gtmp;
+ STACK_OF(X509_REVOKED) *revoked;
+
+ revoked = X509_CRL_get_REVOKED(crl);
+
+ gens = NULL;
+ for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) {
+ X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
+ STACK_OF(X509_EXTENSION) *exts;
+ ASN1_ENUMERATED *reason;
+ X509_EXTENSION *ext;
+ gtmp = X509_REVOKED_get_ext_d2i(rev,
+ NID_certificate_issuer, &j, NULL);
+ if (!gtmp && (j != -1)) {
+ crl->flags |= EXFLAG_INVALID;
+ return 1;
+ }
+
+ if (gtmp) {
+ gens = gtmp;
+ if (!crl->issuers) {
+ crl->issuers = sk_GENERAL_NAMES_new_null();
+ if (!crl->issuers)
+ return 0;
+ }
+ if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
+ return 0;
+ }
+ rev->issuer = gens;
+
+ reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL);
+ if (!reason && (j != -1)) {
+ crl->flags |= EXFLAG_INVALID;
+ return 1;
+ }
+
+ if (reason) {
+ rev->reason = ASN1_ENUMERATED_get(reason);
+ ASN1_ENUMERATED_free(reason);
+ } else
+ rev->reason = CRL_REASON_NONE;
+
+ /* Check for critical CRL entry extensions */
+
+ exts = rev->extensions;
+
+ for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) {
+ ext = sk_X509_EXTENSION_value(exts, j);
+ if (ext->critical > 0) {
+ if (OBJ_obj2nid(ext->object) == NID_certificate_issuer)
+ continue;
+ crl->flags |= EXFLAG_CRITICAL;
+ break;
+ }
+ }
+
+ }
+
+ return 1;
+
+}
+
+/*
+ * The X509_CRL structure needs a bit of customisation. Cache some extensions
+ * and hash of the whole CRL.
+ */
+static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ X509_CRL *crl = (X509_CRL *)*pval;
+ STACK_OF(X509_EXTENSION) *exts;
+ X509_EXTENSION *ext;
+ int idx;
+
+ switch (operation) {
+ case ASN1_OP_NEW_POST:
+ crl->idp = NULL;
+ crl->akid = NULL;
+ crl->flags = 0;
+ crl->idp_flags = 0;
+ crl->idp_reasons = CRLDP_ALL_REASONS;
+ crl->meth = default_crl_method;
+ crl->meth_data = NULL;
+ crl->issuers = NULL;
+ crl->crl_number = NULL;
+ crl->base_crl_number = NULL;
+ break;
+
+ case ASN1_OP_D2I_POST:
+#ifndef OPENSSL_NO_SHA
+ X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
+#endif
+ crl->idp = X509_CRL_get_ext_d2i(crl,
+ NID_issuing_distribution_point, NULL,
+ NULL);
+ if (crl->idp)
+ setup_idp(crl, crl->idp);
+
+ crl->akid = X509_CRL_get_ext_d2i(crl,
+ NID_authority_key_identifier, NULL,
+ NULL);
+
+ crl->crl_number = X509_CRL_get_ext_d2i(crl,
+ NID_crl_number, NULL, NULL);
+
+ crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
+ NID_delta_crl, NULL,
+ NULL);
+ /* Delta CRLs must have CRL number */
+ if (crl->base_crl_number && !crl->crl_number)
+ crl->flags |= EXFLAG_INVALID;
+
+ /*
+ * See if we have any unhandled critical CRL extensions and indicate
+ * this in a flag. We only currently handle IDP so anything else
+ * critical sets the flag. This code accesses the X509_CRL structure
+ * directly: applications shouldn't do this.
+ */
+
+ exts = crl->crl->extensions;
+
+ for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
+ int nid;
+ ext = sk_X509_EXTENSION_value(exts, idx);
+ nid = OBJ_obj2nid(ext->object);
+ if (nid == NID_freshest_crl)
+ crl->flags |= EXFLAG_FRESHEST;
+ if (ext->critical > 0) {
+ /* We handle IDP and deltas */
+ if ((nid == NID_issuing_distribution_point)
+ || (nid == NID_authority_key_identifier)
+ || (nid == NID_delta_crl))
+ break;;
+ crl->flags |= EXFLAG_CRITICAL;
+ break;
+ }
+ }
+
+ if (!crl_set_issuers(crl))
+ return 0;
+
+ if (crl->meth->crl_init) {
+ if (crl->meth->crl_init(crl) == 0)
+ return 0;
+ }
+ break;
+
+ case ASN1_OP_FREE_POST:
+ if (crl->meth->crl_free) {
+ if (!crl->meth->crl_free(crl))
+ return 0;
+ }
+ if (crl->akid)
+ AUTHORITY_KEYID_free(crl->akid);
+ if (crl->idp)
+ ISSUING_DIST_POINT_free(crl->idp);
+ ASN1_INTEGER_free(crl->crl_number);
+ ASN1_INTEGER_free(crl->base_crl_number);
+ sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
+ break;
+ }
+ return 1;
+}
+
+/* Convert IDP into a more convenient form */
+
+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
+{
+ int idp_only = 0;
+ /* Set various flags according to IDP */
+ crl->idp_flags |= IDP_PRESENT;
+ if (idp->onlyuser > 0) {
+ idp_only++;
+ crl->idp_flags |= IDP_ONLYUSER;
+ }
+ if (idp->onlyCA > 0) {
+ idp_only++;
+ crl->idp_flags |= IDP_ONLYCA;
+ }
+ if (idp->onlyattr > 0) {
+ idp_only++;
+ crl->idp_flags |= IDP_ONLYATTR;
+ }
+
+ if (idp_only > 1)
+ crl->idp_flags |= IDP_INVALID;
+
+ if (idp->indirectCRL > 0)
+ crl->idp_flags |= IDP_INDIRECT;
+
+ if (idp->onlysomereasons) {
+ crl->idp_flags |= IDP_REASONS;
+ if (idp->onlysomereasons->length > 0)
+ crl->idp_reasons = idp->onlysomereasons->data[0];
+ if (idp->onlysomereasons->length > 1)
+ crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8);
+ crl->idp_reasons &= CRLDP_ALL_REASONS;
+ }
+
+ DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
+}
+
+ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
@@ -112,6 +341,8 @@ ASN1_SEQUENCE_ref(X509_CRL, 0, CRYPTO_LOCK_X509_CRL) = {
IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED)
+
IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
@@ -139,6 +370,144 @@ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
return 1;
}
+int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
+{
+ if (crl->meth->crl_verify)
+ return crl->meth->crl_verify(crl, r);
+ return 0;
+}
+
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+ X509_REVOKED **ret, ASN1_INTEGER *serial)
+{
+ if (crl->meth->crl_lookup)
+ return crl->meth->crl_lookup(crl, ret, serial, NULL);
+ return 0;
+}
+
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
+{
+ if (crl->meth->crl_lookup)
+ return crl->meth->crl_lookup(crl, ret,
+ X509_get_serialNumber(x),
+ X509_get_issuer_name(x));
+ return 0;
+}
+
+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
+{
+ return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
+ crl->sig_alg, crl->signature, crl->crl, r));
+}
+
+static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
+ X509_REVOKED *rev)
+{
+ int i;
+
+ if (!rev->issuer) {
+ if (!nm)
+ return 1;
+ if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
+ return 1;
+ return 0;
+ }
+
+ if (!nm)
+ nm = X509_CRL_get_issuer(crl);
+
+ for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) {
+ GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
+ if (gen->type != GEN_DIRNAME)
+ continue;
+ if (!X509_NAME_cmp(nm, gen->d.directoryName))
+ return 1;
+ }
+ return 0;
+
+}
+
+static int def_crl_lookup(X509_CRL *crl,
+ X509_REVOKED **ret, ASN1_INTEGER *serial,
+ X509_NAME *issuer)
+{
+ X509_REVOKED rtmp, *rev;
+ int idx;
+ rtmp.serialNumber = serial;
+ /*
+ * Sort revoked into serial number order if not already sorted. Do this
+ * under a lock to avoid race condition.
+ */
+ if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) {
+ CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
+ sk_X509_REVOKED_sort(crl->crl->revoked);
+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
+ }
+ idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
+ if (idx < 0)
+ return 0;
+ /* Need to look for matching name */
+ for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) {
+ rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
+ if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
+ return 0;
+ if (crl_revoked_issuer_match(crl, issuer, rev)) {
+ if (ret)
+ *ret = rev;
+ if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+ return 2;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
+{
+ if (meth == NULL)
+ default_crl_method = &int_crl_meth;
+ else
+ default_crl_method = meth;
+}
+
+X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
+ int (*crl_free) (X509_CRL *crl),
+ int (*crl_lookup) (X509_CRL *crl,
+ X509_REVOKED **ret,
+ ASN1_INTEGER *ser,
+ X509_NAME *issuer),
+ int (*crl_verify) (X509_CRL *crl,
+ EVP_PKEY *pk))
+{
+ X509_CRL_METHOD *m;
+ m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
+ if (!m)
+ return NULL;
+ m->crl_init = crl_init;
+ m->crl_free = crl_free;
+ m->crl_lookup = crl_lookup;
+ m->crl_verify = crl_verify;
+ m->flags = X509_CRL_METHOD_DYNAMIC;
+ return m;
+}
+
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
+{
+ if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
+ return;
+ OPENSSL_free(m);
+}
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
+{
+ crl->meth_data = dat;
+}
+
+void *X509_CRL_get_meth_data(X509_CRL *crl)
+{
+ return crl->meth_data;
+}
+
IMPLEMENT_STACK_OF(X509_REVOKED)
IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_long.c b/Cryptlib/OpenSSL/crypto/asn1/x_long.c
index e0dab2be..3aed44a3 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/x_long.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_long.c
@@ -74,6 +74,8 @@ static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it);
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it);
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int indent, const ASN1_PCTX *pctx);
static ASN1_PRIMITIVE_FUNCS long_pf = {
NULL, 0,
@@ -81,7 +83,8 @@ static ASN1_PRIMITIVE_FUNCS long_pf = {
long_free,
long_free, /* Clear should set to initial value */
long_c2i,
- long_i2c
+ long_i2c,
+ long_print
};
ASN1_ITEM_start(LONG)
@@ -185,3 +188,9 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
memcpy(cp, &ltmp, sizeof(long));
return 1;
}
+
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int indent, const ASN1_PCTX *pctx)
+{
+ return BIO_printf(out, "%ld\n", *(long *)pval);
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_name.c b/Cryptlib/OpenSSL/crypto/asn1/x_name.c
index 85be1a62..737c426f 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/x_name.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_name.c
@@ -57,13 +57,19 @@
*/
#include <stdio.h>
+#include <ctype.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
+#include "asn1_locl.h"
-static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
- long len, const ASN1_ITEM *it, int tag,
- int aclass, char opt, ASN1_TLC *ctx);
+typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
+DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
+
+static int x509_name_ex_d2i(ASN1_VALUE **val,
+ const unsigned char **in, long len,
+ const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx);
static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass);
@@ -71,6 +77,14 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
static int x509_name_encode(X509_NAME *a);
+static int x509_name_canon(X509_NAME *a);
+static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
+ unsigned char **in);
+
+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+ int indent,
+ const char *fname, const ASN1_PCTX *pctx);
ASN1_SEQUENCE(X509_NAME_ENTRY) = {
ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
@@ -106,7 +120,8 @@ const ASN1_EXTERN_FUNCS x509_name_ff = {
x509_name_ex_free,
0, /* Default clear behaviour is OK */
x509_name_ex_d2i,
- x509_name_ex_i2d
+ x509_name_ex_i2d,
+ x509_name_ex_print
};
IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
@@ -125,6 +140,8 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
goto memerr;
if ((ret->bytes = BUF_MEM_new()) == NULL)
goto memerr;
+ ret->canon_enc = NULL;
+ ret->canon_enclen = 0;
ret->modified = 1;
*val = (ASN1_VALUE *)ret;
return 1;
@@ -148,28 +165,20 @@ static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
BUF_MEM_free(a->bytes);
sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
+ if (a->canon_enc)
+ OPENSSL_free(a->canon_enc);
OPENSSL_free(a);
*pval = NULL;
}
-/*
- * Used with sk_pop_free() to free up the internal representation. NB: we
- * only free the STACK and not its contents because it is already present in
- * the X509_NAME structure.
- */
-
-static void sk_internal_free(void *a)
-{
- sk_free(a);
-}
-
-static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
- long len, const ASN1_ITEM *it, int tag,
- int aclass, char opt, ASN1_TLC *ctx)
+static int x509_name_ex_d2i(ASN1_VALUE **val,
+ const unsigned char **in, long len,
+ const ASN1_ITEM *it, int tag, int aclass,
+ char opt, ASN1_TLC *ctx)
{
const unsigned char *p = *in, *q;
union {
- STACK *s;
+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
ASN1_VALUE *a;
} intname = {
NULL
@@ -203,8 +212,8 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
memcpy(nm.x->bytes->data, q, p - q);
/* Convert internal representation to X509_NAME structure */
- for (i = 0; i < sk_num(intname.s); i++) {
- entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname.s, i);
+ for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
+ entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
entry = sk_X509_NAME_ENTRY_value(entries, j);
entry->set = i;
@@ -213,7 +222,10 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
}
sk_X509_NAME_ENTRY_free(entries);
}
- sk_free(intname.s);
+ sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
+ ret = x509_name_canon(nm.x);
+ if (!ret)
+ goto err;
nm.x->modified = 0;
*val = nm.a;
*in = p;
@@ -231,7 +243,10 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
int ret;
X509_NAME *a = (X509_NAME *)*val;
if (a->modified) {
- ret = x509_name_encode((X509_NAME *)a);
+ ret = x509_name_encode(a);
+ if (ret < 0)
+ return ret;
+ ret = x509_name_canon(a);
if (ret < 0)
return ret;
}
@@ -243,10 +258,20 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
return ret;
}
+static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
+{
+ sk_X509_NAME_ENTRY_free(ne);
+}
+
+static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
+{
+ sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
+}
+
static int x509_name_encode(X509_NAME *a)
{
union {
- STACK *s;
+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
ASN1_VALUE *a;
} intname = {
NULL
@@ -256,7 +281,7 @@ static int x509_name_encode(X509_NAME *a)
STACK_OF(X509_NAME_ENTRY) *entries = NULL;
X509_NAME_ENTRY *entry;
int i, set = -1;
- intname.s = sk_new_null();
+ intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
if (!intname.s)
goto memerr;
for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
@@ -265,7 +290,7 @@ static int x509_name_encode(X509_NAME *a)
entries = sk_X509_NAME_ENTRY_new_null();
if (!entries)
goto memerr;
- if (!sk_push(intname.s, (char *)entries))
+ if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries))
goto memerr;
set = entry->set;
}
@@ -279,15 +304,207 @@ static int x509_name_encode(X509_NAME *a)
p = (unsigned char *)a->bytes->data;
ASN1_item_ex_i2d(&intname.a,
&p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
- sk_pop_free(intname.s, sk_internal_free);
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_free);
a->modified = 0;
return len;
memerr:
- sk_pop_free(intname.s, sk_internal_free);
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_free);
ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
return -1;
}
+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+ int indent,
+ const char *fname, const ASN1_PCTX *pctx)
+{
+ if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
+ indent, pctx->nm_flags) <= 0)
+ return 0;
+ return 2;
+}
+
+/*
+ * This function generates the canonical encoding of the Name structure. In
+ * it all strings are converted to UTF8, leading, trailing and multiple
+ * spaces collapsed, converted to lower case and the leading SEQUENCE header
+ * removed. In future we could also normalize the UTF8 too. By doing this
+ * comparison of Name structures can be rapidly perfomed by just using
+ * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name
+ * constraints of type dirName can also be checked with a simple memcmp().
+ */
+
+static int x509_name_canon(X509_NAME *a)
+{
+ unsigned char *p;
+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
+ STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+ X509_NAME_ENTRY *entry, *tmpentry = NULL;
+ int i, set = -1, ret = 0;
+
+ if (a->canon_enc) {
+ OPENSSL_free(a->canon_enc);
+ a->canon_enc = NULL;
+ }
+ /* Special case: empty X509_NAME => null encoding */
+ if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
+ a->canon_enclen = 0;
+ return 1;
+ }
+ intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+ if (!intname)
+ goto err;
+ for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+ entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+ if (entry->set != set) {
+ entries = sk_X509_NAME_ENTRY_new_null();
+ if (!entries)
+ goto err;
+ if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
+ goto err;
+ set = entry->set;
+ }
+ tmpentry = X509_NAME_ENTRY_new();
+ if (!tmpentry)
+ goto err;
+ tmpentry->object = OBJ_dup(entry->object);
+ if (!asn1_string_canon(tmpentry->value, entry->value))
+ goto err;
+ if (!sk_X509_NAME_ENTRY_push(entries, tmpentry))
+ goto err;
+ tmpentry = NULL;
+ }
+
+ /* Finally generate encoding */
+
+ a->canon_enclen = i2d_name_canon(intname, NULL);
+
+ p = OPENSSL_malloc(a->canon_enclen);
+
+ if (!p)
+ goto err;
+
+ a->canon_enc = p;
+
+ i2d_name_canon(intname, &p);
+
+ ret = 1;
+
+ err:
+
+ if (tmpentry)
+ X509_NAME_ENTRY_free(tmpentry);
+ if (intname)
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
+ local_sk_X509_NAME_ENTRY_pop_free);
+ return ret;
+}
+
+/* Bitmap of all the types of string that will be canonicalized. */
+
+#define ASN1_MASK_CANON \
+ (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
+ | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
+ | B_ASN1_VISIBLESTRING)
+
+static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
+{
+ unsigned char *to, *from;
+ int len, i;
+
+ /* If type not in bitmask just copy string across */
+ if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
+ if (!ASN1_STRING_copy(out, in))
+ return 0;
+ return 1;
+ }
+
+ out->type = V_ASN1_UTF8STRING;
+ out->length = ASN1_STRING_to_UTF8(&out->data, in);
+ if (out->length == -1)
+ return 0;
+
+ to = out->data;
+ from = to;
+
+ len = out->length;
+
+ /*
+ * Convert string in place to canonical form. Ultimately we may need to
+ * handle a wider range of characters but for now ignore anything with
+ * MSB set and rely on the isspace() and tolower() functions.
+ */
+
+ /* Ignore leading spaces */
+ while ((len > 0) && !(*from & 0x80) && isspace(*from)) {
+ from++;
+ len--;
+ }
+
+ to = from + len - 1;
+
+ /* Ignore trailing spaces */
+ while ((len > 0) && !(*to & 0x80) && isspace(*to)) {
+ to--;
+ len--;
+ }
+
+ to = out->data;
+
+ i = 0;
+ while (i < len) {
+ /* If MSB set just copy across */
+ if (*from & 0x80) {
+ *to++ = *from++;
+ i++;
+ }
+ /* Collapse multiple spaces */
+ else if (isspace(*from)) {
+ /* Copy one space across */
+ *to++ = ' ';
+ /*
+ * Ignore subsequent spaces. Note: don't need to check len here
+ * because we know the last character is a non-space so we can't
+ * overflow.
+ */
+ do {
+ from++;
+ i++;
+ }
+ while (!(*from & 0x80) && isspace(*from));
+ } else {
+ *to++ = tolower(*from);
+ from++;
+ i++;
+ }
+ }
+
+ out->length = to - out->data;
+
+ return 1;
+
+}
+
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
+ unsigned char **in)
+{
+ int i, len, ltmp;
+ ASN1_VALUE *v;
+ STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
+
+ len = 0;
+ for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
+ v = sk_ASN1_VALUE_value(intname, i);
+ ltmp = ASN1_item_ex_i2d(&v, in,
+ ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
+ if (ltmp < 0)
+ return ltmp;
+ len += ltmp;
+ }
+ return len;
+}
+
int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
{
X509_NAME *in;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_nx509.c b/Cryptlib/OpenSSL/crypto/asn1/x_nx509.c
new file mode 100644
index 00000000..5aa0ed58
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_nx509.c
@@ -0,0 +1,72 @@
+/* x_nx509.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+/* Old netscape certificate wrapper format */
+
+ASN1_SEQUENCE(NETSCAPE_X509) = {
+ ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING),
+ ASN1_OPT(NETSCAPE_X509, cert, X509)
+} ASN1_SEQUENCE_END(NETSCAPE_X509)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509)
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_pubkey.c b/Cryptlib/OpenSSL/crypto/asn1/x_pubkey.c
index 307798c7..4b682018 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/x_pubkey.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_pubkey.c
@@ -60,6 +60,7 @@
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
+#include "asn1_locl.h"
#ifndef OPENSSL_NO_RSA
# include <openssl/rsa.h>
#endif
@@ -68,7 +69,8 @@
#endif
/* Minor tweak to operation: free up EVP_PKEY */
-static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
{
if (operation == ASN1_OP_FREE_POST) {
X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
@@ -87,145 +89,28 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
{
X509_PUBKEY *pk = NULL;
- X509_ALGOR *a;
- ASN1_OBJECT *o;
- unsigned char *s, *p = NULL;
- int i;
if (x == NULL)
return (0);
if ((pk = X509_PUBKEY_new()) == NULL)
- goto err;
- a = pk->algor;
-
- /* set the algorithm id */
- if ((o = OBJ_nid2obj(pkey->type)) == NULL)
- goto err;
- ASN1_OBJECT_free(a->algorithm);
- a->algorithm = o;
-
- /* Set the parameter list */
- if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA)) {
- if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL)) {
- ASN1_TYPE_free(a->parameter);
- if (!(a->parameter = ASN1_TYPE_new())) {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
- goto err;
+ goto error;
+
+ if (pkey->ameth) {
+ if (pkey->ameth->pub_encode) {
+ if (!pkey->ameth->pub_encode(pk, pkey)) {
+ X509err(X509_F_X509_PUBKEY_SET,
+ X509_R_PUBLIC_KEY_ENCODE_ERROR);
+ goto error;
}
- a->parameter->type = V_ASN1_NULL;
+ } else {
+ X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED);
+ goto error;
}
- }
-#ifndef OPENSSL_NO_DSA
- else if (pkey->type == EVP_PKEY_DSA) {
- unsigned char *pp;
- DSA *dsa;
-
- dsa = pkey->pkey.dsa;
- dsa->write_params = 0;
- ASN1_TYPE_free(a->parameter);
- if ((i = i2d_DSAparams(dsa, NULL)) <= 0)
- goto err;
- if (!(p = (unsigned char *)OPENSSL_malloc(i))) {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- pp = p;
- i2d_DSAparams(dsa, &pp);
- if (!(a->parameter = ASN1_TYPE_new())) {
- OPENSSL_free(p);
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- a->parameter->type = V_ASN1_SEQUENCE;
- if (!(a->parameter->value.sequence = ASN1_STRING_new())) {
- OPENSSL_free(p);
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (!ASN1_STRING_set(a->parameter->value.sequence, p, i)) {
- OPENSSL_free(p);
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- OPENSSL_free(p);
- }
-#endif
-#ifndef OPENSSL_NO_EC
- else if (pkey->type == EVP_PKEY_EC) {
- int nid = 0;
- unsigned char *pp;
- EC_KEY *ec_key;
- const EC_GROUP *group;
-
- ec_key = pkey->pkey.ec;
- ASN1_TYPE_free(a->parameter);
-
- if ((a->parameter = ASN1_TYPE_new()) == NULL) {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
- goto err;
- }
-
- group = EC_KEY_get0_group(ec_key);
- if (EC_GROUP_get_asn1_flag(group)
- && (nid = EC_GROUP_get_curve_name(group))) {
- /* just set the OID */
- a->parameter->type = V_ASN1_OBJECT;
- a->parameter->value.object = OBJ_nid2obj(nid);
- } else { /* explicit parameters */
-
- if ((i = i2d_ECParameters(ec_key, NULL)) == 0) {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
- goto err;
- }
- if ((p = (unsigned char *)OPENSSL_malloc(i)) == NULL) {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- pp = p;
- if (!i2d_ECParameters(ec_key, &pp)) {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
- OPENSSL_free(p);
- goto err;
- }
- a->parameter->type = V_ASN1_SEQUENCE;
- if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL) {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
- OPENSSL_free(p);
- goto err;
- }
- ASN1_STRING_set(a->parameter->value.sequence, p, i);
- OPENSSL_free(p);
- }
- }
-#endif
- else if (1) {
+ } else {
X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM);
- goto err;
- }
-
- if ((i = i2d_PublicKey(pkey, NULL)) <= 0)
- goto err;
- if ((s = (unsigned char *)OPENSSL_malloc(i + 1)) == NULL) {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
- goto err;
+ goto error;
}
- p = s;
- i2d_PublicKey(pkey, &p);
- if (!M_ASN1_BIT_STRING_set(pk->public_key, s, i)) {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- /* Set number of unused bits to zero */
- pk->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
- pk->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-
- OPENSSL_free(s);
-
-#if 0
- CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
- pk->pkey = pkey;
-#endif
if (*x != NULL)
X509_PUBKEY_free(*x);
@@ -233,7 +118,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
*x = pk;
return 1;
- err:
+ error:
if (pk != NULL)
X509_PUBKEY_free(pk);
return 0;
@@ -242,107 +127,36 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
{
EVP_PKEY *ret = NULL;
- long j;
- int type;
- const unsigned char *p;
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
- const unsigned char *cp;
- X509_ALGOR *a;
-#endif
if (key == NULL)
- goto err;
+ goto error;
if (key->pkey != NULL) {
CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
- return (key->pkey);
+ return key->pkey;
}
if (key->public_key == NULL)
- goto err;
+ goto error;
- type = OBJ_obj2nid(key->algor->algorithm);
if ((ret = EVP_PKEY_new()) == NULL) {
X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
- goto err;
+ goto error;
}
- ret->type = EVP_PKEY_type(type);
-
- /* the parameters must be extracted before the public key (ECDSA!) */
-
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
- a = key->algor;
-#endif
- if (0) ;
-#ifndef OPENSSL_NO_DSA
- else if (ret->type == EVP_PKEY_DSA) {
- if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) {
- if ((ret->pkey.dsa = DSA_new()) == NULL) {
- X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- ret->pkey.dsa->write_params = 0;
- cp = p = a->parameter->value.sequence->data;
- j = a->parameter->value.sequence->length;
- if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j))
- goto err;
- }
- ret->save_parameters = 1;
- }
-#endif
-#ifndef OPENSSL_NO_EC
- else if (ret->type == EVP_PKEY_EC) {
- if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) {
- /*
- * type == V_ASN1_SEQUENCE => we have explicit parameters (e.g.
- * parameters in the X9_62_EC_PARAMETERS-structure )
- */
- if ((ret->pkey.ec = EC_KEY_new()) == NULL) {
- X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- cp = p = a->parameter->value.sequence->data;
- j = a->parameter->value.sequence->length;
- if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j)) {
- X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB);
- goto err;
- }
- } else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT)) {
- /*
- * type == V_ASN1_OBJECT => the parameters are given by an asn1
- * OID
- */
- EC_KEY *ec_key;
- EC_GROUP *group;
-
- if (ret->pkey.ec == NULL)
- ret->pkey.ec = EC_KEY_new();
- ec_key = ret->pkey.ec;
- if (ec_key == NULL)
- goto err;
- group =
- EC_GROUP_new_by_curve_name(OBJ_obj2nid
- (a->parameter->value.object));
- if (group == NULL)
- goto err;
- EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
- if (EC_KEY_set_group(ec_key, group) == 0)
- goto err;
- EC_GROUP_free(group);
- }
- /*
- * the case implicitlyCA is currently not implemented
- */
- ret->save_parameters = 1;
+ if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) {
+ X509err(X509_F_X509_PUBKEY_GET, X509_R_UNSUPPORTED_ALGORITHM);
+ goto error;
}
-#endif
- p = key->public_key->data;
- j = key->public_key->length;
- if (!d2i_PublicKey(type, &ret, &p, (long)j)) {
- X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB);
- goto err;
+ if (ret->ameth->pub_decode) {
+ if (!ret->ameth->pub_decode(ret, key)) {
+ X509err(X509_F_X509_PUBKEY_GET, X509_R_PUBLIC_KEY_DECODE_ERROR);
+ goto error;
+ }
+ } else {
+ X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
+ goto error;
}
/* Check to see if another thread set key->pkey first */
@@ -356,8 +170,10 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
}
CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
- return (ret);
- err:
+
+ return ret;
+
+ error:
if (ret != NULL)
EVP_PKEY_free(ret);
return (NULL);
@@ -520,3 +336,36 @@ int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
return (ret);
}
#endif
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+ int ptype, void *pval,
+ unsigned char *penc, int penclen)
+{
+ if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
+ return 0;
+ if (penc) {
+ if (pub->public_key->data)
+ OPENSSL_free(pub->public_key->data);
+ pub->public_key->data = penc;
+ pub->public_key->length = penclen;
+ /* Set number of unused bits to zero */
+ pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ }
+ return 1;
+}
+
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+ const unsigned char **pk, int *ppklen,
+ X509_ALGOR **pa, X509_PUBKEY *pub)
+{
+ if (ppkalg)
+ *ppkalg = pub->algor->algorithm;
+ if (pk) {
+ *pk = pub->public_key->data;
+ *ppklen = pub->public_key->length;
+ }
+ if (pa)
+ *pa = pub->algor;
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_req.c b/Cryptlib/OpenSSL/crypto/asn1/x_req.c
index 5b303fb6..ae293aa0 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/x_req.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_req.c
@@ -80,7 +80,8 @@
*
*/
-static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
{
X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_x509.c b/Cryptlib/OpenSSL/crypto/asn1/x_x509.c
index d6958f6c..5f266a26 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/x_x509.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_x509.c
@@ -81,7 +81,8 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
extern void policy_cache_free(X509_POLICY_CACHE *cache);
-static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
{
X509 *ret = (X509 *)*pval;
@@ -99,6 +100,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
ret->rfc3779_asid = NULL;
#endif
ret->aux = NULL;
+ ret->crldp = NULL;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
break;
@@ -113,7 +115,10 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
X509_CERT_AUX_free(ret->aux);
ASN1_OCTET_STRING_free(ret->skid);
AUTHORITY_KEYID_free(ret->akid);
+ CRL_DIST_POINTS_free(ret->crldp);
policy_cache_free(ret->policy_cache);
+ GENERAL_NAMES_free(ret->altname);
+ NAME_CONSTRAINTS_free(ret->nc);
#ifndef OPENSSL_NO_RFC3779
sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
ASIdentifiers_free(ret->rfc3779_asid);
@@ -139,18 +144,6 @@ IMPLEMENT_ASN1_FUNCTIONS(X509)
IMPLEMENT_ASN1_DUP_FUNCTION(X509)
-static ASN1_METHOD meth = {
- (I2D_OF(void)) i2d_X509,
- (D2I_OF(void)) d2i_X509,
- (void *(*)(void))X509_new,
- (void (*)(void *))X509_free
-};
-
-ASN1_METHOD *X509_asn1_meth(void)
-{
- return (&meth);
-}
-
int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
@@ -184,7 +177,7 @@ X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
/* Save start position */
q = *pp;
- if(!a || *a == NULL) {
+ if (!a || *a == NULL) {
freeret = 1;
}
ret = d2i_X509(a, pp, length);
@@ -199,7 +192,7 @@ X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
goto err;
return ret;
err:
- if(freeret) {
+ if (freeret) {
X509_free(ret);
if (a)
*a = NULL;
@@ -215,3 +208,23 @@ int i2d_X509_AUX(X509 *a, unsigned char **pp)
length += i2d_X509_CERT_AUX(a->aux, pp);
return length;
}
+
+int i2d_re_X509_tbs(X509 *x, unsigned char **pp)
+{
+ x->cert_info->enc.modified = 1;
+ return i2d_X509_CINF(x->cert_info, pp);
+}
+
+void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
+ const X509 *x)
+{
+ if (psig)
+ *psig = x->signature;
+ if (palg)
+ *palg = x->sig_alg;
+}
+
+int X509_get_signature_nid(const X509 *x)
+{
+ return OBJ_obj2nid(x->sig_alg->algorithm);
+}