Add new 'spkac' utility and several SPKAC utility functions.
authorDr. Stephen Henson <steve@openssl.org>
Fri, 3 Sep 1999 01:08:34 +0000 (01:08 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 3 Sep 1999 01:08:34 +0000 (01:08 +0000)
12 files changed:
CHANGES
apps/Makefile.ssl
apps/ca.c
apps/progs.h
apps/spkac.c [new file with mode: 0644]
crypto/asn1/Makefile.ssl
crypto/asn1/t_spki.c [new file with mode: 0644]
crypto/x509/Makefile.ssl
crypto/x509/x509.h
crypto/x509/x509_err.c
crypto/x509/x509spki.c [new file with mode: 0644]
util/libeay.num

diff --git a/CHANGES b/CHANGES
index 0cc163b..649de47 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,13 @@
 
  Changes between 0.9.4 and 0.9.5  [xx XXX 1999]
 
+  *) Add various utility functions to handle SPKACs, these were previously
+     handled by poking round in the structure internals. Added new function
+     NETSCAPE_SPKI_print() to print out SPKAC and a new utility 'spkac' to
+     print, verify and generate SPKACs. Based on an original idea from
+     Massimiliano Pala <madwolf@comune.modena.it> but extensively modified.
+     [Steve Henson]
+
   *) RIPEMD160 is operational on all platforms and is back in 'make test'.
      [Andy Polyakov]
 
index 8363ec9..bd8a825 100644 (file)
@@ -37,7 +37,7 @@ E_EXE=        verify asn1pars req dgst dh enc gendh errstr ca crl \
        rsa dsa dsaparam \
        x509 genrsa gendsa s_server s_client speed \
        s_time version pkcs7 crl2pkcs7 sess_id ciphers nseq pkcs12 \
-       pkcs8
+       pkcs8 spkac
 
 PROGS= $(PROGRAM).c
 
@@ -51,7 +51,7 @@ E_OBJ=        verify.o asn1pars.o req.o dgst.o dh.o enc.o gendh.o errstr.o ca.o \
        rsa.o dsa.o dsaparam.o \
        x509.o genrsa.o gendsa.o s_server.o s_client.o speed.o \
        s_time.o $(A_OBJ) $(S_OBJ) version.o sess_id.o \
-       ciphers.o nseq.o pkcs12.o pkcs8.o
+       ciphers.o nseq.o pkcs12.o pkcs8.o spkac.o
 
 #      pem_mail.o
 
@@ -60,7 +60,7 @@ E_SRC=        verify.c asn1pars.c req.c dgst.c dh.c enc.c gendh.c errstr.c ca.c \
        rsa.c dsa.c dsaparam.c \
        x509.c genrsa.c gendsa.c s_server.c s_client.c speed.c \
        s_time.c $(A_SRC) $(S_SRC) version.c sess_id.c \
-       ciphers.c nseq.c pkcs12.c pkcs8.c
+       ciphers.c nseq.c pkcs12.c pkcs8.c spkac.o
 
 #      pem_mail.c
 
index e1eb275..42dc420 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -1941,7 +1941,6 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
        X509_REQ *req=NULL;
        CONF_VALUE *cv=NULL;
        NETSCAPE_SPKI *spki = NULL;
-       unsigned char *spki_der = NULL,*p;
        X509_REQ_INFO *ri;
        char *type,*buf;
        EVP_PKEY *pktmp=NULL;
@@ -2013,25 +2012,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
                        {
                        if (strcmp(type, "SPKAC") == 0)
                                {
-                               spki_der=(unsigned char *)Malloc(
-                                       strlen(cv->value)+1);
-                               if (spki_der == NULL)
-                                       {
-                                       BIO_printf(bio_err,"Malloc failure\n");
-                                       goto err;
-                                       }
-                               j = EVP_DecodeBlock(spki_der, (unsigned char *)cv->value,
-                                       strlen(cv->value));
-                               if (j <= 0)
-                                       {
-                                       BIO_printf(bio_err, "Can't b64 decode SPKAC structure\n");
-                                       goto err;
-                                       }
-
-                               p=spki_der;
-                               spki = d2i_NETSCAPE_SPKI(&spki, &p, j);
-                               Free(spki_der);
-                               spki_der = NULL;
+                               spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
                                if (spki == NULL)
                                        {
                                        BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
@@ -2071,7 +2052,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
 
        BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
 
-       if ((pktmp=X509_PUBKEY_get(spki->spkac->pubkey)) == NULL)
+       if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
                {
                BIO_printf(bio_err,"error unpacking SPKAC public key\n");
                goto err;
@@ -2092,7 +2073,6 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
 err:
        if (req != NULL) X509_REQ_free(req);
        if (parms != NULL) CONF_free(parms);
-       if (spki_der != NULL) Free(spki_der);
        if (spki != NULL) NETSCAPE_SPKI_free(spki);
        if (ne != NULL) X509_NAME_ENTRY_free(ne);
 
index df06718..47a4d6b 100644 (file)
@@ -28,6 +28,7 @@ extern int ciphers_main(int argc,char *argv[]);
 extern int nseq_main(int argc,char *argv[]);
 extern int pkcs12_main(int argc,char *argv[]);
 extern int pkcs8_main(int argc,char *argv[]);
+extern int spkac_main(int argc,char *argv[]);
 
 #ifdef SSLEAY_SRC  /* Defined only in openssl.c. */
 
@@ -94,6 +95,7 @@ FUNCTION functions[] = {
        {FUNC_TYPE_GENERAL,"pkcs12",pkcs12_main},
 #endif
        {FUNC_TYPE_GENERAL,"pkcs8",pkcs8_main},
+       {FUNC_TYPE_GENERAL,"spkac",spkac_main},
        {FUNC_TYPE_MD,"md2",dgst_main},
        {FUNC_TYPE_MD,"md5",dgst_main},
        {FUNC_TYPE_MD,"sha",dgst_main},
diff --git a/apps/spkac.c b/apps/spkac.c
new file mode 100644 (file)
index 0000000..74bdae7
--- /dev/null
@@ -0,0 +1,255 @@
+/* apps/spkac.c */
+
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 1999. Based on an original idea by Massimiliano Pala
+ * (madwolf@openca.org).
+ */
+/* ====================================================================
+ * 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 <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG   spkac_main
+
+/* -in arg     - input file - default stdin
+ * -out arg    - output file - default stdout
+ */
+
+int MAIN(int argc, char **argv)
+       {
+       int i,badops=0, ret = 1;
+       BIO *in = NULL,*out = NULL, *key = NULL;
+       int verify=0,noout=0;
+       char *infile = NULL,*outfile = NULL,*prog;
+       char *spkac = "SPKAC", *spksect = "default", *spkstr = NULL;
+       char *challenge = NULL, *keyfile = NULL;
+       LHASH *conf;
+       NETSCAPE_SPKI *spki = NULL;
+       EVP_PKEY *pkey = NULL;
+
+       apps_startup();
+
+       if (!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+       prog=argv[0];
+       argc--;
+       argv++;
+       while (argc >= 1)
+               {
+               if (strcmp(*argv,"-in") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       infile= *(++argv);
+                       }
+               else if (strcmp(*argv,"-out") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       outfile= *(++argv);
+                       }
+               else if (strcmp(*argv,"-key") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       keyfile= *(++argv);
+                       }
+               else if (strcmp(*argv,"-challenge") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       challenge= *(++argv);
+                       }
+               else if (strcmp(*argv,"-spkac") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       spkac= *(++argv);
+                       }
+               else if (strcmp(*argv,"-spksect") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       spksect= *(++argv);
+                       }
+               else if (strcmp(*argv,"-noout") == 0)
+                       noout=1;
+               else if (strcmp(*argv,"-verify") == 0)
+                       verify=1;
+               else badops = 1;
+               argc--;
+               argv++;
+               }
+
+       if (badops)
+               {
+bad:
+               BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+               BIO_printf(bio_err,"where options are\n");
+               BIO_printf(bio_err," -in arg       input file\n");
+               BIO_printf(bio_err," -out arg      output file\n");
+               BIO_printf(bio_err," -spkac arg    alternative SPKAC name\n");
+               BIO_printf(bio_err," -noout        don't print SPKAC\n");
+               BIO_printf(bio_err," -verify       verify SPKAC signature\n");
+               goto end;
+               }
+
+       ERR_load_crypto_strings();
+
+       if(keyfile) {
+               if(strcmp(keyfile, "-")) key = BIO_new_file(keyfile, "r");
+               else key = BIO_new_fp(stdin, BIO_NOCLOSE);
+               if(!key) {
+                       BIO_printf(bio_err, "Error opening key file\n");
+                       ERR_print_errors(bio_err);
+                       goto end;
+               }
+               pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL);
+               if(!pkey) {
+                       BIO_printf(bio_err, "Error reading private key\n");
+                       ERR_print_errors(bio_err);
+                       goto end;
+               }
+               spki = NETSCAPE_SPKI_new();
+               if(challenge) ASN1_STRING_set(spki->spkac->challenge,
+                                                challenge, strlen(challenge));
+               NETSCAPE_SPKI_set_pubkey(spki, pkey);
+               NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
+               spkstr = NETSCAPE_SPKI_b64_encode(spki);
+
+               if (outfile) out = BIO_new_file(outfile, "w");
+               else out = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+               if(!out) {
+                       BIO_printf(bio_err, "Error opening output file\n");
+                       ERR_print_errors(bio_err);
+                       goto end;
+               }
+               BIO_printf(out, "SPKAC=%s\n", spkstr);
+               ret = 0;
+               goto end;
+       }
+
+       
+
+       if (infile) in = BIO_new_file(infile, "r");
+       else in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+       if(!in) {
+               BIO_printf(bio_err, "Error opening input file\n");
+               ERR_print_errors(bio_err);
+               goto end;
+       }
+
+       conf = CONF_load_bio(NULL, in, NULL);
+
+       if(!conf) {
+               BIO_printf(bio_err, "Error parsing config file\n");
+               ERR_print_errors(bio_err);
+               goto end;
+       }
+
+       spkstr = CONF_get_string(conf, spksect, spkac);
+               
+       if(!spkstr) {
+               BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac);
+               ERR_print_errors(bio_err);
+               goto end;
+       }
+
+       spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
+       if(!spki) {
+               BIO_printf(bio_err, "Error loading SPKAC\n");
+               ERR_print_errors(bio_err);
+               goto end;
+       }
+
+       if (outfile) out = BIO_new_file(outfile, "w");
+       else out = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+       if(!out) {
+               BIO_printf(bio_err, "Error opening output file\n");
+               ERR_print_errors(bio_err);
+               goto end;
+       }
+
+       if(!noout) NETSCAPE_SPKI_print(out, spki);
+       if(verify) {
+               EVP_PKEY *pktmp;
+               pktmp = NETSCAPE_SPKI_get_pubkey(spki);
+               i = NETSCAPE_SPKI_verify(spki, pktmp);
+               EVP_PKEY_free(pktmp);
+               if(i) BIO_printf(bio_err, "Signature OK\n");
+               else {
+                       BIO_printf(bio_err, "Signature Failure\n");
+                       ERR_print_errors(bio_err);
+                       goto end;
+               }
+       }
+
+       ret = 0;
+
+end:
+       NETSCAPE_SPKI_free(spki);
+       BIO_free(in);
+       BIO_free(out);
+       BIO_free(key);
+       EVP_PKEY_free(pkey);
+       if(spkstr) Free(spkstr);
+       EXIT(ret);
+       }
index dfdcc4a..69b9884 100644 (file)
@@ -30,7 +30,7 @@ LIBSRC=       a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \
        d2i_r_pr.c i2d_r_pr.c d2i_r_pu.c i2d_r_pu.c \
        d2i_s_pr.c i2d_s_pr.c d2i_s_pu.c i2d_s_pu.c \
        d2i_pu.c d2i_pr.c i2d_pu.c i2d_pr.c\
-       t_req.c t_x509.c t_crl.c t_pkey.c \
+       t_req.c t_x509.c t_crl.c t_pkey.c t_spki.c \
        p7_i_s.c p7_signi.c p7_signd.c p7_recip.c p7_enc_c.c p7_evp.c \
        p7_dgst.c p7_s_e.c p7_enc.c p7_lib.c \
        f_int.c f_string.c i2d_dhp.c i2d_dsap.c d2i_dhp.c d2i_dsap.c n_pkey.c \
@@ -45,7 +45,7 @@ LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
        d2i_r_pr.o i2d_r_pr.o d2i_r_pu.o i2d_r_pu.o \
        d2i_s_pr.o i2d_s_pr.o d2i_s_pu.o i2d_s_pu.o \
        d2i_pu.o d2i_pr.o i2d_pu.o i2d_pr.o \
-       t_req.o t_x509.o t_crl.o t_pkey.o \
+       t_req.o t_x509.o t_crl.o t_pkey.o t_spki.o \
        p7_i_s.o p7_signi.o p7_signd.o p7_recip.o p7_enc_c.o p7_evp.o \
        p7_dgst.o p7_s_e.o p7_enc.o p7_lib.o \
        f_int.o f_string.o i2d_dhp.o i2d_dsap.o d2i_dhp.o d2i_dsap.o n_pkey.o \
@@ -833,6 +833,23 @@ t_req.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 t_req.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 t_req.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 t_req.o: ../../include/openssl/x509v3.h ../cryptlib.h
+t_spki.o: ../../include/openssl/asn1.h ../../include/openssl/asn1_mac.h
+t_spki.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
+t_spki.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+t_spki.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h
+t_spki.o: ../../include/openssl/des.h ../../include/openssl/dh.h
+t_spki.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
+t_spki.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+t_spki.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+t_spki.o: ../../include/openssl/md2.h ../../include/openssl/md5.h
+t_spki.o: ../../include/openssl/mdc2.h ../../include/openssl/objects.h
+t_spki.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+t_spki.o: ../../include/openssl/pkcs7.h ../../include/openssl/rc2.h
+t_spki.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
+t_spki.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
+t_spki.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+t_spki.o: ../../include/openssl/stack.h ../../include/openssl/x509.h
+t_spki.o: ../../include/openssl/x509_vfy.h ../cryptlib.h
 t_x509.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 t_x509.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
 t_x509.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
diff --git a/crypto/asn1/t_spki.c b/crypto/asn1/t_spki.c
new file mode 100644 (file)
index 0000000..d708434
--- /dev/null
@@ -0,0 +1,116 @@
+/* t_spki.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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 "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1_mac.h>
+
+/* Print out an SPKI */
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
+{
+       EVP_PKEY *pkey;
+       ASN1_IA5STRING *chal;
+       int i, n;
+       char *s;
+       BIO_printf(out, "Netscape SPKI:\n");
+       i=OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm);
+       BIO_printf(out,"  Public Key Algorithm: %s\n",
+                               (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
+       pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+       if(!pkey) BIO_printf(out, "  Unable to load public key\n");
+       else {
+#ifndef 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 NO_DSA
+               if (pkey->type == EVP_PKEY_DSA)
+               {
+               BIO_printf(out,"  DSA Public Key:\n");
+               DSA_print(out,pkey->pkey.dsa,2);
+               }
+               else
+#endif
+                       BIO_printf(out,"  Unknown Public Key:\n");
+               EVP_PKEY_free(pkey);
+       }
+       chal = spki->spkac->challenge;
+       if(chal->length)
+               BIO_printf(out, "  Challenge String: %s\n", chal->data);
+       i=OBJ_obj2nid(spki->sig_algor->algorithm);
+       BIO_printf(out,"  Signature Algorithm: %s",
+                               (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
+
+       n=spki->signature->length;
+       s=(char *)spki->signature->data;
+       for (i=0; i<n; i++)
+               {
+               if ((i%18) == 0) BIO_write(out,"\n      ",7);
+               BIO_printf(out,"%02x%s",(unsigned char)s[i],
+                                               ((i+1) == n)?"":":");
+               }
+       BIO_write(out,"\n",1);
+       return 1;
+}
index 14bb60d..6562b68 100644 (file)
@@ -23,13 +23,13 @@ APPS=
 
 LIB=$(TOP)/libcrypto.a
 LIBSRC=        x509_def.c x509_d2.c x509_r2x.c x509_cmp.c \
-       x509_obj.c x509_req.c x509_vfy.c \
+       x509_obj.c x509_req.c x509spki.c x509_vfy.c \
        x509_set.c x509rset.c x509_err.c \
        x509name.c x509_v3.c x509_ext.c \
        x509type.c x509_lu.c x_all.c x509_txt.c \
        by_file.c by_dir.c 
 LIBOBJ= x509_def.o x509_d2.o x509_r2x.o x509_cmp.o \
-       x509_obj.o x509_req.o x509_vfy.o \
+       x509_obj.o x509_req.o x509spki.o x509_vfy.o \
        x509_set.o x509rset.o x509_err.o \
        x509name.o x509_v3.o x509_ext.o \
        x509type.o x509_lu.o x_all.o x509_txt.o \
@@ -380,6 +380,24 @@ x509rset.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 x509rset.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 x509rset.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 x509rset.o: ../cryptlib.h
+x509spki.o: ../../include/openssl/asn1.h ../../include/openssl/asn1_mac.h
+x509spki.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
+x509spki.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+x509spki.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h
+x509spki.o: ../../include/openssl/des.h ../../include/openssl/dh.h
+x509spki.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
+x509spki.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+x509spki.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+x509spki.o: ../../include/openssl/md2.h ../../include/openssl/md5.h
+x509spki.o: ../../include/openssl/mdc2.h ../../include/openssl/objects.h
+x509spki.o: ../../include/openssl/opensslconf.h
+x509spki.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h
+x509spki.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+x509spki.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
+x509spki.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+x509spki.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509spki.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x509spki.o: ../cryptlib.h
 x509type.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 x509type.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
 x509type.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
index 7bb4dbf..1a3071c 100644 (file)
@@ -552,6 +552,13 @@ int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
 int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
 int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
 
+NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(char *str, int len);
+char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
+
 int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
 int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
 int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
@@ -947,6 +954,8 @@ PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
 #define X509_F_BY_FILE_CTRL                             101
 #define X509_F_DIR_CTRL                                         102
 #define X509_F_GET_CERT_BY_SUBJECT                      103
+#define X509_F_NETSCAPE_SPKI_B64_DECODE                         129
+#define X509_F_NETSCAPE_SPKI_B64_ENCODE                         130
 #define X509_F_X509V3_ADD_EXT                           104
 #define X509_F_X509_CHECK_PRIVATE_KEY                   128
 #define X509_F_X509_EXTENSION_CREATE_BY_NID             108
@@ -972,6 +981,7 @@ PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
 
 /* Reason codes. */
 #define X509_R_BAD_X509_FILETYPE                        100
+#define X509_R_BASE64_DECODE_ERROR                      118
 #define X509_R_CANT_CHECK_DH_KEY                        114
 #define X509_R_CERT_ALREADY_IN_HASH_TABLE               101
 #define X509_R_ERR_ASN1_LIB                             102
index 9afd4cc..a2a0f11 100644 (file)
@@ -69,6 +69,8 @@ static ERR_STRING_DATA X509_str_functs[]=
 {ERR_PACK(0,X509_F_BY_FILE_CTRL,0),    "BY_FILE_CTRL"},
 {ERR_PACK(0,X509_F_DIR_CTRL,0),        "DIR_CTRL"},
 {ERR_PACK(0,X509_F_GET_CERT_BY_SUBJECT,0),     "GET_CERT_BY_SUBJECT"},
+{ERR_PACK(0,X509_F_NETSCAPE_SPKI_B64_DECODE,0),        "NETSCAPE_SPKI_b64_decode"},
+{ERR_PACK(0,X509_F_NETSCAPE_SPKI_B64_ENCODE,0),        "NETSCAPE_SPKI_b64_encode"},
 {ERR_PACK(0,X509_F_X509V3_ADD_EXT,0),  "X509v3_add_ext"},
 {ERR_PACK(0,X509_F_X509_CHECK_PRIVATE_KEY,0),  "X509_check_private_key"},
 {ERR_PACK(0,X509_F_X509_EXTENSION_CREATE_BY_NID,0),    "X509_EXTENSION_create_by_NID"},
@@ -97,6 +99,7 @@ static ERR_STRING_DATA X509_str_functs[]=
 static ERR_STRING_DATA X509_str_reasons[]=
        {
 {X509_R_BAD_X509_FILETYPE                ,"bad x509 filetype"},
+{X509_R_BASE64_DECODE_ERROR              ,"base64 decode error"},
 {X509_R_CANT_CHECK_DH_KEY                ,"cant check dh key"},
 {X509_R_CERT_ALREADY_IN_HASH_TABLE       ,"cert already in hash table"},
 {X509_R_ERR_ASN1_LIB                     ,"err asn1 lib"},
diff --git a/crypto/x509/x509spki.c b/crypto/x509/x509spki.c
new file mode 100644 (file)
index 0000000..984e35a
--- /dev/null
@@ -0,0 +1,121 @@
+/* x509spki.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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 "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1_mac.h>
+
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
+{
+       if ((x == NULL) || (x->spkac == NULL)) return(0);
+       return(X509_PUBKEY_set(&(x->spkac->pubkey),pkey));
+}
+
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
+{
+       if ((x == NULL) || (x->spkac == NULL))
+               return(NULL);
+       return(X509_PUBKEY_get(x->spkac->pubkey));
+}
+
+/* Load a Netscape SPKI from a base64 encoded string */
+
+NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(char *str, int len)
+{
+       unsigned char *spki_der, *p;
+       int spki_len;
+       NETSCAPE_SPKI *spki;
+       if(len <= 0) len = strlen(str);
+       if (!(spki_der = Malloc(len + 1))) {
+               X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE);
+               return NULL;
+       }
+       spki_len = EVP_DecodeBlock(spki_der, str, len);
+       if(spki_len < 0) {
+               X509err(X509_F_NETSCAPE_SPKI_B64_DECODE,
+                                               X509_R_BASE64_DECODE_ERROR);
+               Free(spki_der);
+               return NULL;
+       }
+       p = spki_der;
+       spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
+       Free(spki_der);
+       return spki;
+}
+
+/* Generate a base64 encoded string from an SPKI */
+
+char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
+{
+       unsigned char *der_spki, *p;
+       char *b64_str;
+       int der_len;
+       der_len = i2d_NETSCAPE_SPKI(spki, NULL);
+       der_spki = Malloc(der_len);
+       b64_str = Malloc(der_len * 2);
+       if(!der_spki || !b64_str) {
+               X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE);
+               return NULL;
+       }
+       p = der_spki;
+       i2d_NETSCAPE_SPKI(spki, &p);
+       EVP_EncodeBlock(b64_str, der_spki, der_len);
+       Free(der_spki);
+       return b64_str;
+}
index c8e8dd5..8e7e63d 100755 (executable)
@@ -1868,3 +1868,9 @@ DH_get_default_method                   1892
 DSA_set_ex_data                         1893
 DH_set_default_method                   1894
 DSA_get_ex_data                         1895
+X509V3_EXT_REQ_add_conf                 1896
+NETSCAPE_SPKI_print                     1897
+NETSCAPE_SPKI_set_pubkey                1898
+NETSCAPE_SPKI_b64_encode                1899
+NETSCAPE_SPKI_get_pubkey                1900
+NETSCAPE_SPKI_b64_decode                1901