Move the certificate and key loading functions to apps.c, so they can
authorRichard Levitte <levitte@openssl.org>
Thu, 22 Jun 2000 17:42:50 +0000 (17:42 +0000)
committerRichard Levitte <levitte@openssl.org>
Thu, 22 Jun 2000 17:42:50 +0000 (17:42 +0000)
be shared by several applications.

apps/apps.c
apps/apps.h
apps/smime.c
apps/x509.c

index f063d83..892bc98 100644 (file)
 #define NON_MAIN
 #include "apps.h"
 #undef NON_MAIN
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include <openssl/safestack.h>
 
 #ifdef WINDOWS
 #  include "bss_file.c"
@@ -159,6 +164,10 @@ int str2fmt(char *s)
                return(FORMAT_PEM);
        else if ((*s == 'N') || (*s == 'n'))
                return(FORMAT_NETSCAPE);
+       else if ((*s == '1')
+               || (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
+               || (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
+               return(FORMAT_PKCS12);
        else
                return(FORMAT_UNDEF);
        }
@@ -414,3 +423,209 @@ static char *app_get_pass(BIO *err, char *arg, int keepbio)
        if(tmp) *tmp = 0;
        return BUF_strdup(tpass);
 }
+
+X509 *load_cert(char *file, int format)
+       {
+       ASN1_HEADER *ah=NULL;
+       BUF_MEM *buf=NULL;
+       X509 *x=NULL;
+       BIO *cert;
+
+       if ((cert=BIO_new(BIO_s_file())) == NULL)
+               {
+               ERR_print_errors(bio_err);
+               goto end;
+               }
+
+       if (file == NULL)
+               BIO_set_fp(cert,stdin,BIO_NOCLOSE);
+       else
+               {
+               if (BIO_read_filename(cert,file) <= 0)
+                       {
+                       perror(file);
+                       goto end;
+                       }
+               }
+
+       if      (format == FORMAT_ASN1)
+               x=d2i_X509_bio(cert,NULL);
+       else if (format == FORMAT_NETSCAPE)
+               {
+               unsigned char *p,*op;
+               int size=0,i;
+
+               /* We sort of have to do it this way because it is sort of nice
+                * to read the header first and check it, then
+                * try to read the certificate */
+               buf=BUF_MEM_new();
+               for (;;)
+                       {
+                       if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10)))
+                               goto end;
+                       i=BIO_read(cert,&(buf->data[size]),1024*10);
+                       size+=i;
+                       if (i == 0) break;
+                       if (i < 0)
+                               {
+                               perror("reading certificate");
+                               goto end;
+                               }
+                       }
+               p=(unsigned char *)buf->data;
+               op=p;
+
+               /* First load the header */
+               if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL)
+                       goto end;
+               if ((ah->header == NULL) || (ah->header->data == NULL) ||
+                       (strncmp(NETSCAPE_CERT_HDR,(char *)ah->header->data,
+                       ah->header->length) != 0))
+                       {
+                       BIO_printf(bio_err,"Error reading header on certificate\n");
+                       goto end;
+                       }
+               /* header is ok, so now read the object */
+               p=op;
+               ah->meth=X509_asn1_meth();
+               if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL)
+                       goto end;
+               x=(X509 *)ah->data;
+               ah->data=NULL;
+               }
+       else if (format == FORMAT_PEM)
+               x=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL);
+       else if (format == FORMAT_PKCS12)
+               {
+               PKCS12 *p12 = d2i_PKCS12_bio(cert, NULL);
+
+               PKCS12_parse(p12, NULL, NULL, &x, NULL);
+               PKCS12_free(p12);
+               p12 = NULL;
+               }
+       else    {
+               BIO_printf(bio_err,"bad input format specified for input cert\n");
+               goto end;
+               }
+end:
+       if (x == NULL)
+               {
+               BIO_printf(bio_err,"unable to load certificate\n");
+               ERR_print_errors(bio_err);
+               }
+       if (ah != NULL) ASN1_HEADER_free(ah);
+       if (cert != NULL) BIO_free(cert);
+       if (buf != NULL) BUF_MEM_free(buf);
+       return(x);
+       }
+
+EVP_PKEY *load_key(char *file, int format, char *pass)
+       {
+       BIO *key=NULL;
+       EVP_PKEY *pkey=NULL;
+
+       if (file == NULL)
+               {
+               BIO_printf(bio_err,"no keyfile specified\n");
+               goto end;
+               }
+       key=BIO_new(BIO_s_file());
+       if (key == NULL)
+               {
+               ERR_print_errors(bio_err);
+               goto end;
+               }
+       if (BIO_read_filename(key,file) <= 0)
+               {
+               perror(file);
+               goto end;
+               }
+       if (format == FORMAT_ASN1)
+               {
+               pkey=d2i_PrivateKey_bio(key, NULL);
+               }
+       else if (format == FORMAT_PEM)
+               {
+               pkey=PEM_read_bio_PrivateKey(key,NULL,NULL,pass);
+               }
+       else if (format == FORMAT_PKCS12)
+               {
+               PKCS12 *p12 = d2i_PKCS12_bio(key, NULL);
+
+               PKCS12_parse(p12, pass, &pkey, NULL, NULL);
+               PKCS12_free(p12);
+               p12 = NULL;
+               }
+       else
+               {
+               BIO_printf(bio_err,"bad input format specified for key\n");
+               goto end;
+               }
+ end:
+       if (key != NULL) BIO_free(key);
+       if (pkey == NULL)
+               BIO_printf(bio_err,"unable to load Private Key\n");
+       return(pkey);
+       }
+
+STACK_OF(X509) *load_certs(char *file, int format)
+       {
+       BIO *certs;
+       int i;
+       STACK_OF(X509) *othercerts = NULL;
+       STACK_OF(X509_INFO) *allcerts = NULL;
+       X509_INFO *xi;
+
+       if((certs = BIO_new(BIO_s_file())) == NULL)
+               {
+               ERR_print_errors(bio_err);
+               goto end;
+               }
+
+       if (file == NULL)
+               BIO_set_fp(certs,stdin,BIO_NOCLOSE);
+       else
+               {
+               if (BIO_read_filename(certs,file) <= 0)
+                       {
+                       perror(file);
+                       goto end;
+                       }
+               }
+
+       if      (format == FORMAT_PEM)
+               {
+               othercerts = sk_X509_new(NULL);
+               if(!othercerts)
+                       {
+                       sk_X509_free(othercerts);
+                       othercerts = NULL;
+                       goto end;
+                       }
+               allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
+               for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
+                       {
+                       xi = sk_X509_INFO_value (allcerts, i);
+                       if (xi->x509)
+                               {
+                               sk_X509_push(othercerts, xi->x509);
+                               xi->x509 = NULL;
+                               }
+                       }
+               goto end;
+               }
+       else    {
+               BIO_printf(bio_err,"bad input format specified for input cert\n");
+               goto end;
+               }
+end:
+       if (othercerts == NULL)
+               {
+               BIO_printf(bio_err,"unable to load certificates\n");
+               ERR_print_errors(bio_err);
+               }
+       if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
+       if (certs != NULL) BIO_free(certs);
+       return(othercerts);
+       }
+
index 2dcdb88..7885688 100644 (file)
@@ -146,11 +146,18 @@ int chopup_args(ARGS *arg,char *buf, int *argc, char **argv[]);
 int dump_cert_text(BIO *out, X509 *x);
 #endif
 int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
+X509 *load_cert(char *file, int format);
+EVP_PKEY *load_key(char *file, int format, char *pass);
+STACK_OF(X509) *load_certs(char *file, int format);
+
 #define FORMAT_UNDEF    0
 #define FORMAT_ASN1     1
 #define FORMAT_TEXT     2
 #define FORMAT_PEM      3
 #define FORMAT_NETSCAPE 4
+#define FORMAT_PKCS12   5
+
+#define NETSCAPE_CERT_HDR      "certificate"
 
 #define APP_PASS_LEN   1024
 
index e2fc828..e571cdd 100644 (file)
@@ -67,9 +67,6 @@
 
 #undef PROG
 #define PROG smime_main
-static X509 *load_cert(char *file);
-static EVP_PKEY *load_key(char *file, char *pass);
-static STACK_OF(X509) *load_certs(char *file);
 static X509_STORE *setup_verify(char *CAfile, char *CApath);
 static int save_certs(char *signerfile, STACK_OF(X509) *signers);
 
@@ -311,7 +308,7 @@ int MAIN(int argc, char **argv)
                }
                encerts = sk_X509_new_null();
                while (*args) {
-                       if(!(cert = load_cert(*args))) {
+                       if(!(cert = load_cert(*args,FORMAT_PEM))) {
                                BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args);
                                goto end;
                        }
@@ -322,14 +319,14 @@ int MAIN(int argc, char **argv)
        }
 
        if(signerfile && (operation == SMIME_SIGN)) {
-               if(!(signer = load_cert(signerfile))) {
+               if(!(signer = load_cert(signerfile,FORMAT_PEM))) {
                        BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile);
                        goto end;
                }
        }
 
        if(certfile) {
-               if(!(other = load_certs(certfile))) {
+               if(!(other = load_certs(certfile,FORMAT_PEM))) {
                        BIO_printf(bio_err, "Can't read certificate file %s\n", certfile);
                        ERR_print_errors(bio_err);
                        goto end;
@@ -337,7 +334,7 @@ int MAIN(int argc, char **argv)
        }
 
        if(recipfile && (operation == SMIME_DECRYPT)) {
-               if(!(recip = load_cert(recipfile))) {
+               if(!(recip = load_cert(recipfile,FORMAT_PEM))) {
                        BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile);
                        ERR_print_errors(bio_err);
                        goto end;
@@ -351,7 +348,7 @@ int MAIN(int argc, char **argv)
        } else keyfile = NULL;
 
        if(keyfile) {
-               if(!(key = load_key(keyfile, passin))) {
+               if(!(key = load_key(keyfile, FORMAT_PEM, passin))) {
                        BIO_printf(bio_err, "Can't read recipient certificate file %s\n", keyfile);
                        ERR_print_errors(bio_err);
                        goto end;
@@ -447,49 +444,6 @@ end:
        return (ret);
 }
 
-static X509 *load_cert(char *file)
-{
-       BIO *in;
-       X509 *cert;
-       if(!(in = BIO_new_file(file, "r"))) return NULL;
-       cert = PEM_read_bio_X509(in, NULL, NULL,NULL);
-       BIO_free(in);
-       return cert;
-}
-
-static EVP_PKEY *load_key(char *file, char *pass)
-{
-       BIO *in;
-       EVP_PKEY *key;
-       if(!(in = BIO_new_file(file, "r"))) return NULL;
-       key = PEM_read_bio_PrivateKey(in, NULL,NULL,pass);
-       BIO_free(in);
-       return key;
-}
-
-static STACK_OF(X509) *load_certs(char *file)
-{
-       BIO *in;
-       int i;
-       STACK_OF(X509) *othercerts;
-       STACK_OF(X509_INFO) *allcerts;
-       X509_INFO *xi;
-       if(!(in = BIO_new_file(file, "r"))) return NULL;
-       othercerts = sk_X509_new(NULL);
-       if(!othercerts) return NULL;
-       allcerts = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
-       for(i = 0; i < sk_X509_INFO_num(allcerts); i++) {
-               xi = sk_X509_INFO_value (allcerts, i);
-               if (xi->x509) {
-                       sk_X509_push(othercerts, xi->x509);
-                       xi->x509 = NULL;
-               }
-       }
-       sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
-       BIO_free(in);
-       return othercerts;
-}
-
 static X509_STORE *setup_verify(char *CAfile, char *CApath)
 {
        X509_STORE *store;
index cdfc24a..148c315 100644 (file)
@@ -81,8 +81,6 @@
 #define        POSTFIX ".srl"
 #define DEF_DAYS       30
 
-#define CERT_HDR       "certificate"
-
 static char *x509_usage[]={
 "usage: x509 args\n",
 " -inform arg     - input format - default PEM (one of DER, NET or PEM)\n",
@@ -134,8 +132,6 @@ NULL
 };
 
 static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
-static EVP_PKEY *load_key(char *file, int format, char *passin);
-static X509 *load_cert(char *file, int format);
 static int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *digest,
                                                LHASH *conf, char *section);
 static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
@@ -894,8 +890,8 @@ bad:
                ASN1_HEADER ah;
                ASN1_OCTET_STRING os;
 
-               os.data=(unsigned char *)CERT_HDR;
-               os.length=strlen(CERT_HDR);
+               os.data=(unsigned char *)NETSCAPE_CERT_HDR;
+               os.length=strlen(NETSCAPE_CERT_HDR);
                ah.header= &os;
                ah.data=(char *)x;
                ah.meth=X509_asn1_meth();
@@ -1114,133 +1110,6 @@ static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
                }
        }
 
-static EVP_PKEY *load_key(char *file, int format, char *passin)
-       {
-       BIO *key=NULL;
-       EVP_PKEY *pkey=NULL;
-
-       if (file == NULL)
-               {
-               BIO_printf(bio_err,"no keyfile specified\n");
-               goto end;
-               }
-       key=BIO_new(BIO_s_file());
-       if (key == NULL)
-               {
-               ERR_print_errors(bio_err);
-               goto end;
-               }
-       if (BIO_read_filename(key,file) <= 0)
-               {
-               perror(file);
-               goto end;
-               }
-       if (format == FORMAT_ASN1)
-               {
-               pkey=d2i_PrivateKey_bio(key, NULL);
-               }
-       else if (format == FORMAT_PEM)
-               {
-               pkey=PEM_read_bio_PrivateKey(key,NULL,NULL,passin);
-               }
-       else
-               {
-               BIO_printf(bio_err,"bad input format specified for key\n");
-               goto end;
-               }
-end:
-       if (key != NULL) BIO_free(key);
-       if (pkey == NULL)
-               BIO_printf(bio_err,"unable to load Private Key\n");
-       return(pkey);
-       }
-
-static X509 *load_cert(char *file, int format)
-       {
-       ASN1_HEADER *ah=NULL;
-       BUF_MEM *buf=NULL;
-       X509 *x=NULL;
-       BIO *cert;
-
-       if ((cert=BIO_new(BIO_s_file())) == NULL)
-               {
-               ERR_print_errors(bio_err);
-               goto end;
-               }
-
-       if (file == NULL)
-               BIO_set_fp(cert,stdin,BIO_NOCLOSE);
-       else
-               {
-               if (BIO_read_filename(cert,file) <= 0)
-                       {
-                       perror(file);
-                       goto end;
-                       }
-               }
-       if      (format == FORMAT_ASN1)
-               x=d2i_X509_bio(cert,NULL);
-       else if (format == FORMAT_NETSCAPE)
-               {
-               unsigned char *p,*op;
-               int size=0,i;
-
-               /* We sort of have to do it this way because it is sort of nice
-                * to read the header first and check it, then
-                * try to read the certificate */
-               buf=BUF_MEM_new();
-               for (;;)
-                       {
-                       if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10)))
-                               goto end;
-                       i=BIO_read(cert,&(buf->data[size]),1024*10);
-                       size+=i;
-                       if (i == 0) break;
-                       if (i < 0)
-                               {
-                               perror("reading certificate");
-                               goto end;
-                               }
-                       }
-               p=(unsigned char *)buf->data;
-               op=p;
-
-               /* First load the header */
-               if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL)
-                       goto end;
-               if ((ah->header == NULL) || (ah->header->data == NULL) ||
-                       (strncmp(CERT_HDR,(char *)ah->header->data,
-                       ah->header->length) != 0))
-                       {
-                       BIO_printf(bio_err,"Error reading header on certificate\n");
-                       goto end;
-                       }
-               /* header is ok, so now read the object */
-               p=op;
-               ah->meth=X509_asn1_meth();
-               if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL)
-                       goto end;
-               x=(X509 *)ah->data;
-               ah->data=NULL;
-               }
-       else if (format == FORMAT_PEM)
-               x=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL);
-       else    {
-               BIO_printf(bio_err,"bad input format specified for input cert\n");
-               goto end;
-               }
-end:
-       if (x == NULL)
-               {
-               BIO_printf(bio_err,"unable to load certificate\n");
-               ERR_print_errors(bio_err);
-               }
-       if (ah != NULL) ASN1_HEADER_free(ah);
-       if (cert != NULL) BIO_free(cert);
-       if (buf != NULL) BUF_MEM_free(buf);
-       return(x);
-       }
-
 /* self sign */
 static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, 
                                                LHASH *conf, char *section)