aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/x509
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2015-09-22 16:20:09 +0100
committerDr. Stephen Henson <steve@openssl.org>2015-09-22 16:35:55 +0100
commit1e898fb0f58c9b6cee13917a8453809b1009fec2 (patch)
treec0628c5cc1d16860d3dfc22f271459bd693c78eb /crypto/x509
parent0d0099ea3b1825fe51bce11e076292e408b55feb (diff)
downloadopenssl-1e898fb0f58c9b6cee13917a8453809b1009fec2.tar.gz
Move certificate request and CRL routines to x509 dir.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Diffstat (limited to 'crypto/x509')
-rw-r--r--crypto/x509/Makefile6
-rw-r--r--crypto/x509/t_crl.c137
-rw-r--r--crypto/x509/t_req.c246
-rw-r--r--crypto/x509/t_x509.c357
-rw-r--r--crypto/x509/t_x509a.c116
-rw-r--r--crypto/x509/x509_lcl.h18
-rw-r--r--crypto/x509/x_crl.c506
-rw-r--r--crypto/x509/x_req.c117
-rw-r--r--crypto/x509/x_x509.c227
-rw-r--r--crypto/x509/x_x509a.c200
10 files changed, 1928 insertions, 2 deletions
diff --git a/crypto/x509/Makefile b/crypto/x509/Makefile
index f2bf8f99c9..38d8ad652c 100644
--- a/crypto/x509/Makefile
+++ b/crypto/x509/Makefile
@@ -21,14 +21,16 @@ LIBSRC= x509_def.c x509_d2.c x509_r2x.c x509_cmp.c \
x509name.c x509_v3.c x509_ext.c x509_att.c \
x509type.c x509_lu.c x_all.c x509_txt.c \
x509_trs.c by_file.c by_dir.c x509_vpm.c \
- x_attrib.c x_exten.c x_name.c
+ x_crl.c t_crl.c x_req.c t_req.c x_x509.c t_x509.c \
+ x_x509a.c t_x509a.c x_attrib.c x_exten.c x_name.c
LIBOBJ= x509_def.o x509_d2.o x509_r2x.o x509_cmp.o \
x509_obj.o x509_req.o x509spki.o x509_vfy.o \
x509_set.o x509cset.o x509rset.o x509_err.o \
x509name.o x509_v3.o x509_ext.o x509_att.o \
x509type.o x509_lu.o x_all.o x509_txt.o \
x509_trs.o by_file.o by_dir.o x509_vpm.o \
- x_attrib.o x_exten.o x_name.o
+ x_crl.o t_crl.o x_req.o t_req.o x_x509.o t_x509.o \
+ x_x509a.o t_x509a.o x_attrib.o x_exten.o x_name.o
SRC= $(LIBSRC)
diff --git a/crypto/x509/t_crl.c b/crypto/x509/t_crl.c
new file mode 100644
index 0000000000..8400e851c9
--- /dev/null
+++ b/crypto/x509/t_crl.c
@@ -0,0 +1,137 @@
+/* t_crl.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_NO_STDIO
+int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ X509err(X509_F_X509_CRL_PRINT_FP, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = X509_CRL_print(b, x);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+int X509_CRL_print(BIO *out, X509_CRL *x)
+{
+ STACK_OF(X509_REVOKED) *rev;
+ X509_REVOKED *r;
+ X509_ALGOR *sig_alg;
+ ASN1_BIT_STRING *sig;
+ long l;
+ int i;
+ char *p;
+
+ BIO_printf(out, "Certificate Revocation List (CRL):\n");
+ l = X509_CRL_get_version(x);
+ BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l);
+ X509_CRL_get0_signature(&sig, &sig_alg, x);
+ i = X509_CRL_get_signature_nid(x);
+ X509_signature_print(out, sig_alg, NULL);
+ p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0);
+ BIO_printf(out, "%8sIssuer: %s\n", "", p);
+ OPENSSL_free(p);
+ BIO_printf(out, "%8sLast Update: ", "");
+ ASN1_TIME_print(out, X509_CRL_get_lastUpdate(x));
+ BIO_printf(out, "\n%8sNext Update: ", "");
+ if (X509_CRL_get_nextUpdate(x))
+ ASN1_TIME_print(out, X509_CRL_get_nextUpdate(x));
+ else
+ BIO_printf(out, "NONE");
+ BIO_printf(out, "\n");
+
+ X509V3_extensions_print(out, "CRL extensions",
+ X509_CRL_get0_extensions(x), 0, 8);
+
+ rev = X509_CRL_get_REVOKED(x);
+
+ if (sk_X509_REVOKED_num(rev) > 0)
+ BIO_printf(out, "Revoked Certificates:\n");
+ else
+ BIO_printf(out, "No Revoked Certificates.\n");
+
+ for (i = 0; i < sk_X509_REVOKED_num(rev); i++) {
+ r = sk_X509_REVOKED_value(rev, i);
+ BIO_printf(out, " Serial Number: ");
+ i2a_ASN1_INTEGER(out, X509_REVOKED_get0_serialNumber(r));
+ BIO_printf(out, "\n Revocation Date: ");
+ ASN1_TIME_print(out, X509_REVOKED_get0_revocationDate(r));
+ BIO_printf(out, "\n");
+ X509V3_extensions_print(out, "CRL entry extensions",
+ X509_REVOKED_get0_extensions(r), 0, 8);
+ }
+ X509_signature_print(out, sig_alg, sig);
+
+ return 1;
+
+}
diff --git a/crypto/x509/t_req.c b/crypto/x509/t_req.c
new file mode 100644
index 0000000000..80611b15d7
--- /dev/null
+++ b/crypto/x509/t_req.c
@@ -0,0 +1,246 @@
+/* crypto/asn1/t_req.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 "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+
+#ifndef OPENSSL_NO_STDIO
+int X509_REQ_print_fp(FILE *fp, X509_REQ *x)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = X509_REQ_print(b, x);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
+ unsigned long cflag)
+{
+ long l;
+ int i;
+ EVP_PKEY *pkey;
+ STACK_OF(X509_EXTENSION) *exts;
+ char mlch = ' ';
+ int nmindent = 0;
+
+ if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+ mlch = '\n';
+ nmindent = 12;
+ }
+
+ if (nmflags == X509_FLAG_COMPAT)
+ nmindent = 16;
+
+ if (!(cflag & X509_FLAG_NO_HEADER)) {
+ if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
+ goto err;
+ if (BIO_write(bp, " Data:\n", 10) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_VERSION)) {
+ l = X509_REQ_get_version(x);
+ if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, l) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+ if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
+ goto err;
+ if (X509_NAME_print_ex(bp, X509_REQ_get_subject_name(x),
+ nmindent, nmflags) < 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+ X509_PUBKEY *xpkey;
+ ASN1_OBJECT *koid;
+ if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0)
+ goto err;
+ if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+ goto err;
+ xpkey = X509_REQ_get_X509_PUBKEY(x);
+ X509_PUBKEY_get0_param(&koid, NULL, NULL, NULL, xpkey);
+ if (i2a_ASN1_OBJECT(bp, koid) <= 0)
+ goto err;
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+
+ pkey = X509_REQ_get_pubkey(x);
+ if (pkey == NULL) {
+ BIO_printf(bp, "%12sUnable to load Public Key\n", "");
+ ERR_print_errors(bp);
+ } else {
+ EVP_PKEY_print_public(bp, pkey, 16, NULL);
+ EVP_PKEY_free(pkey);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
+ /* may not be */
+ if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0)
+ goto err;
+
+ if (X509_REQ_get_attr_count(x) == 0) {
+ if (BIO_printf(bp, "%12sa0:00\n", "") <= 0)
+ goto err;
+ } else {
+ for (i = 0; i < X509_REQ_get_attr_count(x); i++) {
+ ASN1_TYPE *at;
+ X509_ATTRIBUTE *a;
+ ASN1_BIT_STRING *bs = NULL;
+ ASN1_OBJECT *aobj;
+ int j, type = 0, count = 1, ii = 0;
+
+ a = X509_REQ_get_attr(x, i);
+ aobj = X509_ATTRIBUTE_get0_object(a);
+ if (X509_REQ_extension_nid(OBJ_obj2nid(aobj)))
+ continue;
+ if (BIO_printf(bp, "%12s", "") <= 0)
+ goto err;
+ if ((j = i2a_ASN1_OBJECT(bp, aobj)) > 0) {
+ ii = 0;
+ count = X509_ATTRIBUTE_count(a);
+ get_next:
+ at = X509_ATTRIBUTE_get0_type(a, ii);
+ type = at->type;
+ bs = at->value.asn1_string;
+ }
+ for (j = 25 - j; j > 0; j--)
+ if (BIO_write(bp, " ", 1) != 1)
+ goto err;
+ if (BIO_puts(bp, ":") <= 0)
+ goto err;
+ if ((type == V_ASN1_PRINTABLESTRING) ||
+ (type == V_ASN1_T61STRING) ||
+ (type == V_ASN1_IA5STRING)) {
+ if (BIO_write(bp, (char *)bs->data, bs->length)
+ != bs->length)
+ goto err;
+ BIO_puts(bp, "\n");
+ } else {
+ BIO_puts(bp, "unable to print attribute\n");
+ }
+ if (++ii < count)
+ goto get_next;
+ }
+ }
+ }
+ if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
+ exts = X509_REQ_get_extensions(x);
+ if (exts) {
+ BIO_printf(bp, "%8sRequested Extensions:\n", "");
+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+ ASN1_OBJECT *obj;
+ X509_EXTENSION *ex;
+ int j;
+ ex = sk_X509_EXTENSION_value(exts, i);
+ if (BIO_printf(bp, "%12s", "") <= 0)
+ goto err;
+ obj = X509_EXTENSION_get_object(ex);
+ i2a_ASN1_OBJECT(bp, obj);
+ j = X509_EXTENSION_get_critical(ex);
+ if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
+ goto err;
+ if (!X509V3_EXT_print(bp, ex, cflag, 16)) {
+ BIO_printf(bp, "%16s", "");
+ ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex));
+ }
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+ X509_ALGOR *sig_alg;
+ ASN1_BIT_STRING *sig;
+ X509_REQ_get0_signature(&sig, &sig_alg, x);
+ if (!X509_signature_print(bp, sig_alg, sig))
+ goto err;
+ }
+
+ return (1);
+ err:
+ X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB);
+ return (0);
+}
+
+int X509_REQ_print(BIO *bp, X509_REQ *x)
+{
+ return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
diff --git a/crypto/x509/t_x509.c b/crypto/x509/t_x509.c
new file mode 100644
index 0000000000..5fcff5f4da
--- /dev/null
+++ b/crypto/x509/t_x509.c
@@ -0,0 +1,357 @@
+/* crypto/asn1/t_x509.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 "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.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/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "internal/asn1_int.h"
+
+#ifndef OPENSSL_NO_STDIO
+int X509_print_fp(FILE *fp, X509 *x)
+{
+ return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
+
+int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag,
+ unsigned long cflag)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = X509_print_ex(b, x, nmflag, cflag);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+int X509_print(BIO *bp, X509 *x)
+{
+ return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
+
+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
+ unsigned long cflag)
+{
+ long l;
+ int ret = 0, i;
+ char *m = NULL, mlch = ' ';
+ int nmindent = 0;
+ X509_CINF *ci;
+ ASN1_INTEGER *bs;
+ EVP_PKEY *pkey = NULL;
+ const char *neg;
+
+ if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+ mlch = '\n';
+ nmindent = 12;
+ }
+
+ if (nmflags == X509_FLAG_COMPAT)
+ nmindent = 16;
+
+ ci = &x->cert_info;
+ if (!(cflag & X509_FLAG_NO_HEADER)) {
+ if (BIO_write(bp, "Certificate:\n", 13) <= 0)
+ goto err;
+ if (BIO_write(bp, " Data:\n", 10) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_VERSION)) {
+ l = X509_get_version(x);
+ if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_SERIAL)) {
+
+ if (BIO_write(bp, " Serial Number:", 22) <= 0)
+ goto err;
+
+ bs = X509_get_serialNumber(x);
+ if (bs->length <= (int)sizeof(long)) {
+ ERR_set_mark();
+ l = ASN1_INTEGER_get(bs);
+ ERR_pop_to_mark();
+ } else {
+ l = -1;
+ }
+ if (l != -1) {
+ if (bs->type == V_ASN1_NEG_INTEGER) {
+ l = -l;
+ neg = "-";
+ } else
+ neg = "";
+ if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0)
+ goto err;
+ } else {
+ neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
+ if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
+ goto err;
+
+ for (i = 0; i < bs->length; i++) {
+ if (BIO_printf(bp, "%02x%c", bs->data[i],
+ ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
+ goto err;
+ }
+ }
+
+ }
+
+ if (!(cflag & X509_FLAG_NO_SIGNAME)) {
+ if (X509_signature_print(bp, &ci->signature, NULL) <= 0)
+ goto err;
+ }
+
+ if (!(cflag & X509_FLAG_NO_ISSUER)) {
+ if (BIO_printf(bp, " Issuer:%c", mlch) <= 0)
+ goto err;
+ if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
+ < 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_VALIDITY)) {
+ if (BIO_write(bp, " Validity\n", 17) <= 0)
+ goto err;
+ if (BIO_write(bp, " Not Before: ", 24) <= 0)
+ goto err;
+ if (!ASN1_TIME_print(bp, X509_get_notBefore(x)))
+ goto err;
+ if (BIO_write(bp, "\n Not After : ", 25) <= 0)
+ goto err;
+ if (!ASN1_TIME_print(bp, X509_get_notAfter(x)))
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+ if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
+ goto err;
+ if (X509_NAME_print_ex
+ (bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+ if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0)
+ goto err;
+ if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+ goto err;
+ if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
+ goto err;
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+
+ pkey = X509_get_pubkey(x);
+ if (pkey == NULL) {
+ BIO_printf(bp, "%12sUnable to load Public Key\n", "");
+ ERR_print_errors(bp);
+ } else {
+ EVP_PKEY_print_public(bp, pkey, 16, NULL);
+ 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))
+ X509V3_extensions_print(bp, "X509v3 extensions",
+ ci->extensions, cflag, 8);
+
+ if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+ if (X509_signature_print(bp, &x->sig_alg, x->signature) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_AUX)) {
+ if (!X509_CERT_AUX_print(bp, x->aux, 0))
+ goto err;
+ }
+ ret = 1;
+ err:
+ OPENSSL_free(m);
+ return (ret);
+}
+
+int X509_ocspid_print(BIO *bp, X509 *x)
+{
+ unsigned char *der = NULL;
+ unsigned char *dertmp;
+ int derlen;
+ int i;
+ unsigned char SHA1md[SHA_DIGEST_LENGTH];
+
+ /*
+ * display the hash of the subject as it would appear in OCSP requests
+ */
+ if (BIO_printf(bp, " Subject OCSP hash: ") <= 0)
+ goto err;
+ derlen = i2d_X509_NAME(x->cert_info.subject, NULL);
+ if ((der = dertmp = OPENSSL_malloc(derlen)) == NULL)
+ goto err;
+ i2d_X509_NAME(x->cert_info.subject, &dertmp);
+
+ 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;
+ }
+ OPENSSL_free(der);
+ der = NULL;
+
+ /*
+ * display the hash of the public key as it would appear in OCSP requests
+ */
+ if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0)
+ goto err;
+
+ 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;
+ }
+ BIO_printf(bp, "\n");
+
+ return (1);
+ err:
+ OPENSSL_free(der);
+ return (0);
+}
+
+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
+{
+ const unsigned char *s;
+ int i, n;
+
+ n = sig->length;
+ s = sig->data;
+ for (i = 0; i < n; i++) {
+ 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 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;
+}
diff --git a/crypto/x509/t_x509a.c b/crypto/x509/t_x509a.c
new file mode 100644
index 0000000000..06b227e388
--- /dev/null
+++ b/crypto/x509/t_x509a.c
@@ -0,0 +1,116 @@
+/* t_x509a.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+/*
+ * X509_CERT_AUX and string set routines
+ */
+
+int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
+{
+ char oidstr[80], first;
+ int i;
+ if (!aux)
+ return 1;
+ if (aux->trust) {
+ first = 1;
+ BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, "");
+ for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
+ if (!first)
+ BIO_puts(out, ", ");
+ else
+ first = 0;
+ OBJ_obj2txt(oidstr, sizeof oidstr,
+ sk_ASN1_OBJECT_value(aux->trust, i), 0);
+ BIO_puts(out, oidstr);
+ }
+ BIO_puts(out, "\n");
+ } else
+ BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
+ if (aux->reject) {
+ first = 1;
+ BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, "");
+ for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
+ if (!first)
+ BIO_puts(out, ", ");
+ else
+ first = 0;
+ OBJ_obj2txt(oidstr, sizeof oidstr,
+ sk_ASN1_OBJECT_value(aux->reject, i), 0);
+ BIO_puts(out, oidstr);
+ }
+ BIO_puts(out, "\n");
+ } else
+ BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
+ if (aux->alias)
+ BIO_printf(out, "%*sAlias: %s\n", indent, "", aux->alias->data);
+ if (aux->keyid) {
+ BIO_printf(out, "%*sKey Id: ", indent, "");
+ for (i = 0; i < aux->keyid->length; i++)
+ BIO_printf(out, "%s%02X", i ? ":" : "", aux->keyid->data[i]);
+ BIO_write(out, "\n", 1);
+ }
+ return 1;
+}
diff --git a/crypto/x509/x509_lcl.h b/crypto/x509/x509_lcl.h
index eb5ae4382a..71c8a2af6b 100644
--- a/crypto/x509/x509_lcl.h
+++ b/crypto/x509/x509_lcl.h
@@ -100,3 +100,21 @@ struct X509_extension_st {
ASN1_BOOLEAN critical;
ASN1_OCTET_STRING *value;
};
+
+/*
+ * 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/crypto/x509/x_crl.c b/crypto/x509/x_crl.c
new file mode 100644
index 0000000000..851b045e43
--- /dev/null
+++ b/crypto/x509/x_crl.c
@@ -0,0 +1,506 @@
+/* crypto/asn1/x_crl.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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include <openssl/x509v3.h>
+#include "x509_lcl.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),
+ ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
+ 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,
+ void *exarg)
+{
+ X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
+
+ if (!a || !a->revoked)
+ return 1;
+ switch (operation) {
+ /*
+ * Just set cmp function here. We don't sort because that would
+ * affect the output of X509_CRL_print().
+ */
+ case ASN1_OP_D2I_POST:
+ (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp);
+ break;
+ }
+ return 1;
+}
+
+
+ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
+ ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
+ ASN1_EMBED(X509_CRL_INFO, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
+ ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
+ ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
+ ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
+ ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
+} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
+
+/*
+ * 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 (X509_EXTENSION_get_critical(ext)) {
+ if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == 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:
+ X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
+ 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(X509_EXTENSION_get_object(ext));
+ if (nid == NID_freshest_crl)
+ crl->flags |= EXFLAG_FRESHEST;
+ if (X509_EXTENSION_get_critical(ext)) {
+ /* 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;
+ }
+ AUTHORITY_KEYID_free(crl->akid);
+ 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_EMBED(X509_CRL, crl, X509_CRL_INFO),
+ ASN1_EMBED(X509_CRL, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
+
+static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
+ const X509_REVOKED *const *b)
+{
+ return (ASN1_STRING_cmp((ASN1_STRING *)(*a)->serialNumber,
+ (ASN1_STRING *)(*b)->serialNumber));
+}
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
+{
+ X509_CRL_INFO *inf;
+ inf = &crl->crl;
+ if (!inf->revoked)
+ inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
+ if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
+ ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ inf->enc.modified = 1;
+ 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(*m));
+ 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;
+}
diff --git a/crypto/x509/x_req.c b/crypto/x509/x_req.c
new file mode 100644
index 0000000000..b2d14e7223
--- /dev/null
+++ b/crypto/x509/x_req.c
@@ -0,0 +1,117 @@
+/* crypto/asn1/x_req.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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+/*-
+ * X509_REQ_INFO is handled in an unusual way to get round
+ * invalid encodings. Some broken certificate requests don't
+ * encode the attributes field if it is empty. This is in
+ * violation of PKCS#10 but we need to tolerate it. We do
+ * this by making the attributes field OPTIONAL then using
+ * the callback to initialise it to an empty STACK.
+ *
+ * This means that the field will be correctly encoded unless
+ * we NULL out the field.
+ *
+ * As a result we no longer need the req_kludge field because
+ * the information is now contained in the attributes field:
+ * 1. If it is NULL then it's the invalid omission.
+ * 2. If it is empty it is the correct encoding.
+ * 3. If it is not empty then some attributes are present.
+ *
+ */
+
+static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
+
+ if (operation == ASN1_OP_NEW_POST) {
+ rinf->attributes = sk_X509_ATTRIBUTE_new_null();
+ if (!rinf->attributes)
+ return 0;
+ }
+ return 1;
+}
+
+ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
+ ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
+ ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
+ ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
+ /* This isn't really OPTIONAL but it gets round invalid
+ * encodings
+ */
+ ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
+} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
+
+ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = {
+ ASN1_EMBED(X509_REQ, req_info, X509_REQ_INFO),
+ ASN1_EMBED(X509_REQ, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ)
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
new file mode 100644
index 0000000000..112e63c4b6
--- /dev/null
+++ b/crypto/x509/x_x509.c
@@ -0,0 +1,227 @@
+/* crypto/asn1/x_x509.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 "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = {
+ ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
+ ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),
+ ASN1_EMBED(X509_CINF, signature, X509_ALGOR),
+ ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
+ ASN1_EMBED(X509_CINF, validity, X509_VAL),
+ ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
+ ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
+ ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
+ ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
+ ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
+} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
+/* X509 top level structure needs a bit of customisation */
+
+extern void policy_cache_free(X509_POLICY_CACHE *cache);
+
+static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ X509 *ret = (X509 *)*pval;
+
+ switch (operation) {
+
+ case ASN1_OP_NEW_POST:
+ ret->valid = 0;
+ ret->name = NULL;
+ ret->ex_flags = 0;
+ ret->ex_pathlen = -1;
+ ret->skid = NULL;
+ ret->akid = NULL;
+#ifndef OPENSSL_NO_RFC3779
+ ret->rfc3779_addr = NULL;
+ ret->rfc3779_asid = NULL;
+#endif
+ ret->aux = NULL;
+ ret->crldp = NULL;
+ CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
+ break;
+
+ case ASN1_OP_D2I_POST:
+ OPENSSL_free(ret->name);
+ ret->name = X509_NAME_oneline(ret->cert_info.subject, NULL, 0);
+ break;
+
+ case ASN1_OP_FREE_POST:
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
+ 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);
+#endif
+ OPENSSL_free(ret->name);
+ break;
+
+ }
+
+ return 1;
+
+}
+
+ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = {
+ ASN1_EMBED(X509, cert_info, X509_CINF),
+ ASN1_EMBED(X509, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509, X509)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509)
+
+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)
+{
+ return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, argl, argp,
+ new_func, dup_func, free_func);
+}
+
+int X509_set_ex_data(X509 *r, int idx, void *arg)
+{
+ return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
+}
+
+void *X509_get_ex_data(X509 *r, int idx)
+{
+ return (CRYPTO_get_ex_data(&r->ex_data, idx));
+}
+
+/*
+ * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with
+ * extra info tagged on the end. Since these functions set how a certificate
+ * is trusted they should only be used when the certificate comes from a
+ * reliable source such as local storage.
+ */
+
+X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
+{
+ const unsigned char *q;
+ X509 *ret;
+ int freeret = 0;
+
+ /* Save start position */
+ q = *pp;
+
+ if (!a || *a == NULL) {
+ freeret = 1;
+ }
+ ret = d2i_X509(a, &q, length);
+ /* If certificate unreadable then forget it */
+ if (!ret)
+ return NULL;
+ /* update length */
+ length -= q - *pp;
+ if (!length)
+ return ret;
+ if (!d2i_X509_CERT_AUX(&ret->aux, &q, length))
+ goto err;
+ *pp = q;
+ return ret;
+ err:
+ if (freeret) {
+ X509_free(ret);
+ if (a)
+ *a = NULL;
+ }
+ return NULL;
+}
+
+int i2d_X509_AUX(X509 *a, unsigned char **pp)
+{
+ int length;
+ length = i2d_X509(a, pp);
+ if (a)
+ 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, 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);
+}
diff --git a/crypto/x509/x_x509a.c b/crypto/x509/x_x509a.c
new file mode 100644
index 0000000000..76608b669f
--- /dev/null
+++ b/crypto/x509/x_x509a.c
@@ -0,0 +1,200 @@
+/* a_x509a.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+/*
+ * X509_CERT_AUX routines. These are used to encode additional user
+ * modifiable data about a certificate. This data is appended to the X509
+ * encoding when the *_X509_AUX routines are used. This means that the
+ * "traditional" X509 routines will simply ignore the extra data.
+ */
+
+static X509_CERT_AUX *aux_get(X509 *x);
+
+ASN1_SEQUENCE(X509_CERT_AUX) = {
+ ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
+ ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
+ ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
+ ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
+ ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1)
+} ASN1_SEQUENCE_END(X509_CERT_AUX)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+static X509_CERT_AUX *aux_get(X509 *x)
+{
+ if (x == NULL)
+ return NULL;
+ if (x->aux == NULL && (x->aux = X509_CERT_AUX_new()) == NULL)
+ return NULL;
+ return x->aux;
+}
+
+int X509_alias_set1(X509 *x, unsigned char *name, int len)
+{
+ X509_CERT_AUX *aux;
+ if (!name) {
+ if (!x || !x->aux || !x->aux->alias)
+ return 1;
+ ASN1_UTF8STRING_free(x->aux->alias);
+ x->aux->alias = NULL;
+ return 1;
+ }
+ if ((aux = aux_get(x)) == NULL)
+ return 0;
+ if (aux->alias == NULL && (aux->alias = ASN1_UTF8STRING_new()) == NULL)
+ return 0;
+ return ASN1_STRING_set(aux->alias, name, len);
+}
+
+int X509_keyid_set1(X509 *x, unsigned char *id, int len)
+{
+ X509_CERT_AUX *aux;
+ if (!id) {
+ if (!x || !x->aux || !x->aux->keyid)
+ return 1;
+ ASN1_OCTET_STRING_free(x->aux->keyid);
+ x->aux->keyid = NULL;
+ return 1;
+ }
+ if ((aux = aux_get(x)) == NULL)
+ return 0;
+ if (aux->keyid ==NULL
+ && (aux->keyid = ASN1_OCTET_STRING_new()) == NULL)
+ return 0;
+ return ASN1_STRING_set(aux->keyid, id, len);
+}
+
+unsigned char *X509_alias_get0(X509 *x, int *len)
+{
+ if (!x->aux || !x->aux->alias)
+ return NULL;
+ if (len)
+ *len = x->aux->alias->length;
+ return x->aux->alias->data;
+}
+
+unsigned char *X509_keyid_get0(X509 *x, int *len)
+{
+ if (!x->aux || !x->aux->keyid)
+ return NULL;
+ if (len)
+ *len = x->aux->keyid->length;
+ return x->aux->keyid->data;
+}
+
+int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
+{
+ X509_CERT_AUX *aux;
+ ASN1_OBJECT *objtmp = NULL;
+ if (obj) {
+ objtmp = OBJ_dup(obj);
+ if (!objtmp)
+ return 0;
+ }
+ if ((aux = aux_get(x)) == NULL)
+ goto err;
+ if (aux->trust == NULL
+ && (aux->trust = sk_ASN1_OBJECT_new_null()) == NULL)
+ goto err;
+ if (!objtmp || sk_ASN1_OBJECT_push(aux->trust, objtmp))
+ return 1;
+ err:
+ ASN1_OBJECT_free(objtmp);
+ return 0;
+}
+
+int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj)
+{
+ X509_CERT_AUX *aux;
+ ASN1_OBJECT *objtmp;
+ if ((objtmp = OBJ_dup(obj)) == NULL)
+ return 0;
+ if ((aux = aux_get(x)) == NULL)
+ goto err;
+ if (aux->reject == NULL
+ && (aux->reject = sk_ASN1_OBJECT_new_null()) == NULL)
+ goto err;
+ return sk_ASN1_OBJECT_push(aux->reject, objtmp);
+ err:
+ ASN1_OBJECT_free(objtmp);
+ return 0;
+}
+
+void X509_trust_clear(X509 *x)
+{
+ if (x->aux) {
+ sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
+ x->aux->trust = NULL;
+ }
+}
+
+void X509_reject_clear(X509 *x)
+{
+ if (x->aux) {
+ sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
+ x->aux->reject = NULL;
+ }
+}