From 1241126adf6c451d6a7115ffdc68fa64c4d55593 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Fri, 27 Jul 2001 02:22:42 +0000 Subject: [PATCH] More linker bloat reorganisation: Split private key PEM and normal PEM handling. Private key handling needs to link in stuff like PKCS#8. Relocate the ASN1 *_dup() functions, to the relevant ASN1 modules using new macro IMPLEMENT_ASN1_DUP_FUNCTION. Previously these were all in crypto/x509/x_all.c along with every ASN1 BIO/fp function which linked in *every* ASN1 function if a single dup was used. Move the authority key id ASN1 structure to a separate file. This is used in the X509 routines and its previous location linked in all the v3 extension code. Also move ASN1_tag2bit to avoid linking in a_bytes.c which is now largely obsolete. So far under Linux stripped binary with single PEM_read_X509 is now 238K compared to 380K before these changes. --- crypto/asn1/a_bytes.c | 20 +-- crypto/asn1/asn1t.h | 6 + crypto/asn1/tasn_dec.c | 19 +++ crypto/asn1/x_algor.c | 1 + crypto/asn1/x_attrib.c | 1 + crypto/asn1/x_crl.c | 1 + crypto/asn1/x_exten.c | 1 + crypto/asn1/x_name.c | 2 + crypto/asn1/x_req.c | 1 + crypto/asn1/x_x509.c | 1 + crypto/pem/Makefile.ssl | 4 +- crypto/pem/pem.h | 3 + crypto/pem/pem_all.c | 1 - crypto/pem/pem_lib.c | 251 +++---------------------------------- crypto/pem/pem_oth.c | 85 +++++++++++++ crypto/pem/pem_pk8.c | 243 +++++++++++++++++++++++++++++++++++ crypto/pem/pem_pkey.c | 139 ++++++++++++++++++++ crypto/pkcs12/p12_p8e.c | 2 +- crypto/pkcs7/pk7_asn1.c | 1 + crypto/rsa/rsa_asn1.c | 10 ++ crypto/x509/x_all.c | 54 -------- crypto/x509v3/Makefile.ssl | 4 +- crypto/x509v3/v3_akey.c | 8 -- crypto/x509v3/v3_akeya.c | 72 +++++++++++ 24 files changed, 612 insertions(+), 318 deletions(-) create mode 100644 crypto/pem/pem_oth.c create mode 100644 crypto/pem/pem_pk8.c create mode 100644 crypto/pem/pem_pkey.c create mode 100644 crypto/x509v3/v3_akeya.c diff --git a/crypto/asn1/a_bytes.c b/crypto/asn1/a_bytes.c index aa4b570d38..bb88660f58 100644 --- a/crypto/asn1/a_bytes.c +++ b/crypto/asn1/a_bytes.c @@ -60,24 +60,6 @@ #include "cryptlib.h" #include -static unsigned long tag2bit[32]={ -0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ -B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,/* tags 4- 7 */ -B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags 8-11 */ -B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */ -0, 0, B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */ -B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING, /* tags 20-22 */ -B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ -B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING, /* tags 25-27 */ -B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */ - }; - -unsigned long ASN1_tag2bit(int tag) -{ - if((tag < 0) || (tag > 30)) return 0; - return tag2bit[tag]; -} - static int asn1_collate_primitive(ASN1_STRING *a, ASN1_CTX *c); /* type is a 'bitmap' of acceptable string types. */ @@ -99,7 +81,7 @@ ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, unsigned char **pp, i=ASN1_R_TAG_VALUE_TOO_HIGH;; goto err; } - if (!(tag2bit[tag] & type)) + if (!(ASN1_tag2bit(tag) & type)) { i=ASN1_R_WRONG_TYPE; goto err; diff --git a/crypto/asn1/asn1t.h b/crypto/asn1/asn1t.h index 6e1bf87e5c..ed372f8554 100644 --- a/crypto/asn1/asn1t.h +++ b/crypto/asn1/asn1t.h @@ -780,6 +780,12 @@ typedef struct ASN1_AUX_st { return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ } +#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname * stname##_dup(stname *x) \ + { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + #define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index bd0a7d50a2..f3b7c41db9 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c @@ -75,6 +75,25 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long le static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx); +/* Table to convert tags to bit values, used for MSTRING type */ +static unsigned long tag2bit[32]={ +0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ +B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,/* tags 4- 7 */ +B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags 8-11 */ +B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */ +0, 0, B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */ +B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING, /* tags 20-22 */ +B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ +B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING, /* tags 25-27 */ +B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */ + }; + +unsigned long ASN1_tag2bit(int tag) +{ + if((tag < 0) || (tag > 30)) return 0; + return tag2bit[tag]; +} + /* Macro to initialize and invalidate the cache */ #define asn1_tlc_clear(c) if(c) (c)->valid = 0 diff --git a/crypto/asn1/x_algor.c b/crypto/asn1/x_algor.c index f135598ad3..00b9ea54a1 100644 --- a/crypto/asn1/x_algor.c +++ b/crypto/asn1/x_algor.c @@ -67,6 +67,7 @@ ASN1_SEQUENCE(X509_ALGOR) = { } ASN1_SEQUENCE_END(X509_ALGOR) IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR) IMPLEMENT_STACK_OF(X509_ALGOR) IMPLEMENT_ASN1_SET_OF(X509_ALGOR) diff --git a/crypto/asn1/x_attrib.c b/crypto/asn1/x_attrib.c index 959e1ad42e..1e3713f18f 100644 --- a/crypto/asn1/x_attrib.c +++ b/crypto/asn1/x_attrib.c @@ -94,6 +94,7 @@ ASN1_SEQUENCE(X509_ATTRIBUTE) = { } ASN1_SEQUENCE_END(X509_ATTRIBUTE) IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE) X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value) { diff --git a/crypto/asn1/x_crl.c b/crypto/asn1/x_crl.c index 8843f34138..11fce96825 100644 --- a/crypto/asn1/x_crl.c +++ b/crypto/asn1/x_crl.c @@ -127,6 +127,7 @@ ASN1_SEQUENCE_ref(X509_CRL, 0, CRYPTO_LOCK_X509_CRL) = { IMPLEMENT_ASN1_FUNCTIONS(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) diff --git a/crypto/asn1/x_exten.c b/crypto/asn1/x_exten.c index d55c0528a3..702421b6c8 100644 --- a/crypto/asn1/x_exten.c +++ b/crypto/asn1/x_exten.c @@ -68,3 +68,4 @@ ASN1_SEQUENCE(X509_EXTENSION) = { } ASN1_SEQUENCE_END(X509_EXTENSION) IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION) diff --git a/crypto/asn1/x_name.c b/crypto/asn1/x_name.c index 9a111a3d05..caece0f158 100644 --- a/crypto/asn1/x_name.c +++ b/crypto/asn1/x_name.c @@ -76,6 +76,7 @@ ASN1_SEQUENCE(X509_NAME_ENTRY) = { } ASN1_SEQUENCE_END(X509_NAME_ENTRY) IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) /* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } * so declare two template wrappers for this @@ -107,6 +108,7 @@ const ASN1_EXTERN_FUNCS x509_name_ff = { IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) { diff --git a/crypto/asn1/x_req.c b/crypto/asn1/x_req.c index 59bb3dee75..b3f18ebc12 100644 --- a/crypto/asn1/x_req.c +++ b/crypto/asn1/x_req.c @@ -109,3 +109,4 @@ ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_INFO) = { } ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ) IMPLEMENT_ASN1_FUNCTIONS(X509_REQ) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ) diff --git a/crypto/asn1/x_x509.c b/crypto/asn1/x_x509.c index dafb074ccc..6a2adfc658 100644 --- a/crypto/asn1/x_x509.c +++ b/crypto/asn1/x_x509.c @@ -126,6 +126,7 @@ ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = { } ASN1_SEQUENCE_END_ref(X509, X509) IMPLEMENT_ASN1_FUNCTIONS(X509) +IMPLEMENT_ASN1_DUP_FUNCTION(X509) static ASN1_METHOD meth={ (int (*)()) i2d_X509, diff --git a/crypto/pem/Makefile.ssl b/crypto/pem/Makefile.ssl index eb2a10844a..c07ba33d29 100644 --- a/crypto/pem/Makefile.ssl +++ b/crypto/pem/Makefile.ssl @@ -24,10 +24,10 @@ APPS= LIB=$(TOP)/libcrypto.a LIBSRC= pem_sign.c pem_seal.c pem_info.c pem_lib.c pem_all.c pem_err.c \ - pem_x509.c pem_xaux.c + pem_x509.c pem_xaux.c pem_oth.c pem_pk8.c pem_pkey.c LIBOBJ= pem_sign.o pem_seal.o pem_info.o pem_lib.o pem_all.o pem_err.o \ - pem_x509.o pem_xaux.o + pem_x509.o pem_xaux.o pem_oth.o pem_pk8.o pem_pkey.o SRC= $(LIBSRC) diff --git a/crypto/pem/pem.h b/crypto/pem/pem.h index 5c0a2013f2..b7a0c418b5 100644 --- a/crypto/pem/pem.h +++ b/crypto/pem/pem.h @@ -489,6 +489,8 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,long *len); int PEM_write_bio(BIO *bp,const char *name,char *hdr,unsigned char *data, long len); +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp, + pem_password_cb *cb, void *u); char * PEM_ASN1_read_bio(char *(*d2i)(),const char *name,BIO *bp,char **x, pem_password_cb *cb, void *u); int PEM_ASN1_write_bio(int (*i2d)(),const char *name,BIO *bp,char *x, @@ -527,6 +529,7 @@ int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, void ERR_load_PEM_strings(void); +int PEM_def_callback(char *buf, int num, int w, void *key); void PEM_proc_type(char *buf, int type); void PEM_dek_info(char *buf, const char *type, int len, char *str); diff --git a/crypto/pem/pem_all.c b/crypto/pem/pem_all.c index 8cda647e87..e72b7134ce 100644 --- a/crypto/pem/pem_all.c +++ b/crypto/pem/pem_all.c @@ -190,7 +190,6 @@ IMPLEMENT_PEM_rw(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) * (When reading, parameter PEM_STRING_EVP_PKEY is a wildcard for anything * appropriate.) */ -IMPLEMENT_PEM_read(PrivateKey, EVP_PKEY, PEM_STRING_EVP_PKEY, PrivateKey) IMPLEMENT_PEM_write_cb(PrivateKey, EVP_PKEY, ((x->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA), PrivateKey) IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c index 009d967b80..1c1a64a711 100644 --- a/crypto/pem/pem_lib.c +++ b/crypto/pem/pem_lib.c @@ -73,19 +73,10 @@ const char *PEM_version="PEM" OPENSSL_VERSION_PTEXT; #define MIN_LENGTH 4 -static int def_callback(char *buf, int num, int w, void *userdata); static int load_iv(unsigned char **fromp,unsigned char *to, int num); static int check_pem(const char *nm, const char *name); -static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, - int nid, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u); -static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, - int nid, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u); - -static int def_callback(char *buf, int num, int w, void *key) + +int PEM_def_callback(char *buf, int num, int w, void *key) { #ifdef OPENSSL_NO_FP_API /* We should not ever call the default callback routine from @@ -224,14 +215,14 @@ static int check_pem(const char *nm, const char *name) return 0; } -char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x, +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp, pem_password_cb *cb, void *u) { EVP_CIPHER_INFO cipher; char *nm=NULL,*header=NULL; - unsigned char *p=NULL,*data=NULL; + unsigned char *data=NULL; long len; - char *ret=NULL; + int ret = 0; for (;;) { @@ -239,7 +230,7 @@ char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x, if(ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) ERR_add_error_data(2, "Expecting: ", name); - return(NULL); + return 0; } if(check_pem(nm, name)) break; OPENSSL_free(nm); @@ -248,51 +239,20 @@ char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x, } if (!PEM_get_EVP_CIPHER_INFO(header,&cipher)) goto err; if (!PEM_do_header(&cipher,data,&len,cb,u)) goto err; - p=data; - if (strcmp(name,PEM_STRING_EVP_PKEY) == 0) { - if (strcmp(nm,PEM_STRING_RSA) == 0) - ret=d2i(EVP_PKEY_RSA,x,&p,len); - else if (strcmp(nm,PEM_STRING_DSA) == 0) - ret=d2i(EVP_PKEY_DSA,x,&p,len); - else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf; - p8inf=d2i_PKCS8_PRIV_KEY_INFO( - (PKCS8_PRIV_KEY_INFO **) x, &p, len); - ret = (char *)EVP_PKCS82PKEY(p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - } else if (strcmp(nm,PEM_STRING_PKCS8) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf; - X509_SIG *p8; - int klen; - char psbuf[PEM_BUFSIZE]; - p8 = d2i_X509_SIG(NULL, &p, len); - if(!p8) goto p8err; - if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u); - else klen=def_callback(psbuf,PEM_BUFSIZE,0,u); - if (klen <= 0) { - PEMerr(PEM_F_PEM_ASN1_READ_BIO, - PEM_R_BAD_PASSWORD_READ); - goto err; - } - p8inf = PKCS8_decrypt(p8, psbuf, klen); - X509_SIG_free(p8); - if(!p8inf) goto p8err; - ret = (char *)EVP_PKCS82PKEY(p8inf); - if(x) { - if(*x) EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; - } - PKCS8_PRIV_KEY_INFO_free(p8inf); - } - } else ret=d2i(x,&p,len); -p8err: - if (ret == NULL) - PEMerr(PEM_F_PEM_ASN1_READ_BIO,ERR_R_ASN1_LIB); + + *pdata = data; + *plen = len; + + if (pnm) + *pnm = nm; + + ret = 1; + err: - OPENSSL_free(nm); + if (!pnm) OPENSSL_free(nm); OPENSSL_free(header); - OPENSSL_free(data); - return(ret); + if (!ret) OPENSSL_free(data); + return ret; } #ifndef OPENSSL_NO_FP_API @@ -358,7 +318,7 @@ int PEM_ASN1_write_bio(int (*i2d)(), const char *name, BIO *bp, char *x, if (kstr == NULL) { if (callback == NULL) - klen=def_callback(buf,PEM_BUFSIZE,1,u); + klen=PEM_def_callback(buf,PEM_BUFSIZE,1,u); else klen=(*callback)(buf,PEM_BUFSIZE,1,u); if (klen <= 0) @@ -422,7 +382,7 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, if (cipher->cipher == NULL) return(1); if (callback == NULL) - klen=def_callback(buf,PEM_BUFSIZE,0,u); + klen=PEM_def_callback(buf,PEM_BUFSIZE,0,u); else klen=callback(buf,PEM_BUFSIZE,0,u); if (klen <= 0) @@ -794,174 +754,3 @@ err: BUF_MEM_free(dataB); return(0); } - -/* These functions write a private key in PKCS#8 format: it is a "drop in" - * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc' - * is NULL then it uses the unencrypted private key form. The 'nid' versions - * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. - */ - -int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); -} - -int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); -} - -int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); -} - -int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); -} - -static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - X509_SIG *p8; - PKCS8_PRIV_KEY_INFO *p8inf; - char buf[PEM_BUFSIZE]; - int ret; - if(!(p8inf = EVP_PKEY2PKCS8(x))) { - PEMerr(PEM_F_PEM_WRITE_BIO_PKCS8PRIVATEKEY, - PEM_R_ERROR_CONVERTING_PRIVATE_KEY); - return 0; - } - if(enc || (nid != -1)) { - if(!kstr) { - if(!cb) klen = def_callback(buf, PEM_BUFSIZE, 1, u); - else klen = cb(buf, PEM_BUFSIZE, 1, u); - if(klen <= 0) { - PEMerr(PEM_F_PEM_WRITE_BIO_PKCS8PRIVATEKEY, - PEM_R_READ_KEY); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return 0; - } - - kstr = buf; - } - p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); - if(kstr == buf) memset(buf, 0, klen); - PKCS8_PRIV_KEY_INFO_free(p8inf); - if(isder) ret = i2d_PKCS8_bio(bp, p8); - else ret = PEM_write_bio_PKCS8(bp, p8); - X509_SIG_free(p8); - return ret; - } else { - if(isder) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); - else ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return ret; - } -} - -/* Finally the DER version to read PKCS#8 encrypted private keys. It has to be - * here to access the default callback. - */ - -EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) -{ - PKCS8_PRIV_KEY_INFO *p8inf = NULL; - X509_SIG *p8 = NULL; - int klen; - EVP_PKEY *ret; - char psbuf[PEM_BUFSIZE]; - p8 = d2i_PKCS8_bio(bp, NULL); - if(!p8) return NULL; - if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u); - else klen=def_callback(psbuf,PEM_BUFSIZE,0,u); - if (klen <= 0) { - PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ); - X509_SIG_free(p8); - return NULL; - } - p8inf = PKCS8_decrypt(p8, psbuf, klen); - X509_SIG_free(p8); - if(!p8inf) return NULL; - ret = EVP_PKCS82PKEY(p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - if(!ret) return NULL; - if(x) { - if(*x) EVP_PKEY_free(*x); - *x = ret; - } - return ret; -} - -#ifndef OPENSSL_NO_FP_API - -int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); -} - -int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); -} - -int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); -} - -int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u) -{ - return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); -} - -static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - BIO *bp; - int ret; - if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { - PEMerr(PEM_F_PEM_F_DO_PK8KEY_FP,ERR_R_BUF_LIB); - return(0); - } - ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); - BIO_free(bp); - return ret; -} - -EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) -{ - BIO *bp; - EVP_PKEY *ret; - if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { - PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP,ERR_R_BUF_LIB); - return NULL; - } - ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); - BIO_free(bp); - return ret; -} - -#endif - -IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG) -IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, - PKCS8_PRIV_KEY_INFO) diff --git a/crypto/pem/pem_oth.c b/crypto/pem/pem_oth.c new file mode 100644 index 0000000000..8d9064ea7c --- /dev/null +++ b/crypto/pem/pem_oth.c @@ -0,0 +1,85 @@ +/* crypto/pem/pem_oth.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 +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include + +/* Handle 'other' PEMs: not private keys */ + +char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x, + pem_password_cb *cb, void *u) + { + unsigned char *p=NULL,*data=NULL; + long len; + char *ret=NULL; + + if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u)) + return NULL; + p = data; + ret=d2i(x,&p,len); + if (ret == NULL) + PEMerr(PEM_F_PEM_ASN1_READ_BIO,ERR_R_ASN1_LIB); + OPENSSL_free(data); + return(ret); + } diff --git a/crypto/pem/pem_pk8.c b/crypto/pem/pem_pk8.c new file mode 100644 index 0000000000..f44182ffb5 --- /dev/null +++ b/crypto/pem/pem_pk8.c @@ -0,0 +1,243 @@ +/* crypto/pem/pem_pkey.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 +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include + +static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, + int nid, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, + int nid, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); + +/* These functions write a private key in PKCS#8 format: it is a "drop in" + * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc' + * is NULL then it uses the unencrypted private key form. The 'nid' versions + * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. + */ + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); +} + +static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + X509_SIG *p8; + PKCS8_PRIV_KEY_INFO *p8inf; + char buf[PEM_BUFSIZE]; + int ret; + if(!(p8inf = EVP_PKEY2PKCS8(x))) { + PEMerr(PEM_F_PEM_WRITE_BIO_PKCS8PRIVATEKEY, + PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + return 0; + } + if(enc || (nid != -1)) { + if(!kstr) { + if(!cb) klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); + else klen = cb(buf, PEM_BUFSIZE, 1, u); + if(klen <= 0) { + PEMerr(PEM_F_PEM_WRITE_BIO_PKCS8PRIVATEKEY, + PEM_R_READ_KEY); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return 0; + } + + kstr = buf; + } + p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); + if(kstr == buf) memset(buf, 0, klen); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if(isder) ret = i2d_PKCS8_bio(bp, p8); + else ret = PEM_write_bio_PKCS8(bp, p8); + X509_SIG_free(p8); + return ret; + } else { + if(isder) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + else ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; + } +} + +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + X509_SIG *p8 = NULL; + int klen; + EVP_PKEY *ret; + char psbuf[PEM_BUFSIZE]; + p8 = d2i_PKCS8_bio(bp, NULL); + if(!p8) return NULL; + if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u); + else klen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u); + if (klen <= 0) { + PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ); + X509_SIG_free(p8); + return NULL; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + if(!p8inf) return NULL; + ret = EVP_PKCS82PKEY(p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if(!ret) return NULL; + if(x) { + if(*x) EVP_PKEY_free(*x); + *x = ret; + } + return ret; +} + +#ifndef OPENSSL_NO_FP_API + +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); +} + +static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + BIO *bp; + int ret; + if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + PEMerr(PEM_F_PEM_F_DO_PK8KEY_FP,ERR_R_BUF_LIB); + return(0); + } + ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); + BIO_free(bp); + return ret; +} + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + BIO *bp; + EVP_PKEY *ret; + if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP,ERR_R_BUF_LIB); + return NULL; + } + ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); + BIO_free(bp); + return ret; +} + +#endif + +IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG) +IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, + PKCS8_PRIV_KEY_INFO) diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c new file mode 100644 index 0000000000..270892d72b --- /dev/null +++ b/crypto/pem/pem_pkey.c @@ -0,0 +1,139 @@ +/* crypto/pem/pem_pkey.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 +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include + + +EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) + { + char *nm=NULL; + unsigned char *p=NULL,*data=NULL; + long len; + EVP_PKEY *ret=NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) + return NULL; + p = data; + + if (strcmp(nm,PEM_STRING_RSA) == 0) + ret=d2i_PrivateKey(EVP_PKEY_RSA,x,&p,len); + else if (strcmp(nm,PEM_STRING_DSA) == 0) + ret=d2i_PrivateKey(EVP_PKEY_DSA,x,&p,len); + else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); + ret = EVP_PKCS82PKEY(p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + } else if (strcmp(nm,PEM_STRING_PKCS8) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + X509_SIG *p8; + int klen; + char psbuf[PEM_BUFSIZE]; + p8 = d2i_X509_SIG(NULL, &p, len); + if(!p8) goto p8err; + if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u); + else klen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u); + if (klen <= 0) { + PEMerr(PEM_F_PEM_ASN1_READ_BIO, + PEM_R_BAD_PASSWORD_READ); + goto err; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + if(!p8inf) goto p8err; + ret = EVP_PKCS82PKEY(p8inf); + if(x) { + if(*x) EVP_PKEY_free((EVP_PKEY *)*x); + *x = ret; + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + } +p8err: + if (ret == NULL) + PEMerr(PEM_F_PEM_ASN1_READ_BIO,ERR_R_ASN1_LIB); +err: + OPENSSL_free(nm); + OPENSSL_free(data); + return(ret); + } + +#ifndef OPENSSL_NO_FP_API +EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) + { + BIO *b; + EVP_PKEY *ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + PEMerr(PEM_F_PEM_ASN1_READ,ERR_R_BUF_LIB); + return(0); + } + BIO_set_fp(b,fp,BIO_NOCLOSE); + ret=PEM_read_bio_PrivateKey(b,x,cb,u); + BIO_free(b); + return(ret); + } +#endif diff --git a/crypto/pkcs12/p12_p8e.c b/crypto/pkcs12/p12_p8e.c index 7a17b31b5d..3d47956652 100644 --- a/crypto/pkcs12/p12_p8e.c +++ b/crypto/pkcs12/p12_p8e.c @@ -65,7 +65,7 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8inf) { - X509_SIG *p8; + X509_SIG *p8 = NULL; X509_ALGOR *pbe; if (!(p8 = X509_SIG_new())) { diff --git a/crypto/pkcs7/pk7_asn1.c b/crypto/pkcs7/pk7_asn1.c index 613aa13a4f..62b5be1bc4 100644 --- a/crypto/pkcs7/pk7_asn1.c +++ b/crypto/pkcs7/pk7_asn1.c @@ -82,6 +82,7 @@ ASN1_SEQUENCE(PKCS7) = { }ASN1_SEQUENCE_END(PKCS7) IMPLEMENT_ASN1_FUNCTIONS(PKCS7) +IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7) ASN1_SEQUENCE(PKCS7_SIGNED) = { ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER), diff --git a/crypto/rsa/rsa_asn1.c b/crypto/rsa/rsa_asn1.c index 9501923822..1455a7e0e4 100644 --- a/crypto/rsa/rsa_asn1.c +++ b/crypto/rsa/rsa_asn1.c @@ -109,3 +109,13 @@ ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = { IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey) IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey) + +RSA *RSAPublicKey_dup(RSA *rsa) + { + return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa); + } + +RSA *RSAPrivateKey_dup(RSA *rsa) + { + return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa); + } diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index 3be4368c4f..69920e6d03 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -113,21 +113,6 @@ int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) x->signature, x->spkac,pkey,md)); } -X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa) - { - return ASN1_item_dup(ASN1_ITEM_rptr(X509_ATTRIBUTE),xa); - } - -X509 *X509_dup(X509 *x509) - { - return ASN1_item_dup(ASN1_ITEM_rptr(X509),x509); - } - -X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex) - { - return ASN1_item_dup(ASN1_ITEM_rptr(X509_EXTENSION),ex); - } - #ifndef OPENSSL_NO_FP_API X509 *d2i_X509_fp(FILE *fp, X509 **x509) { @@ -150,11 +135,6 @@ int i2d_X509_bio(BIO *bp, X509 *x509) return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509); } -X509_CRL *X509_CRL_dup(X509_CRL *crl) - { - return ASN1_item_dup(ASN1_ITEM_rptr(X509_CRL), crl); - } - #ifndef OPENSSL_NO_FP_API X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) { @@ -177,11 +157,6 @@ int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); } -PKCS7 *PKCS7_dup(PKCS7 *p7) - { - return ASN1_item_dup(ASN1_ITEM_rptr(PKCS7), p7); - } - #ifndef OPENSSL_NO_FP_API PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) { @@ -204,11 +179,6 @@ int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7) return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); } -X509_REQ *X509_REQ_dup(X509_REQ *req) - { - return ASN1_item_dup(ASN1_ITEM_rptr(X509_REQ), req); - } - #ifndef OPENSSL_NO_FP_API X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) { @@ -232,15 +202,6 @@ int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) } #ifndef OPENSSL_NO_RSA -RSA *RSAPublicKey_dup(RSA *rsa) - { - return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa); - } - -RSA *RSAPrivateKey_dup(RSA *rsa) - { - return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa); - } #ifndef OPENSSL_NO_FP_API RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) @@ -364,21 +325,6 @@ int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa) #endif -X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn) - { - return ASN1_item_dup(ASN1_ITEM_rptr(X509_ALGOR), xn); - } - -X509_NAME *X509_NAME_dup(X509_NAME *xn) - { - return ASN1_item_dup(ASN1_ITEM_rptr(X509_NAME), xn); - } - -X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne) - { - return ASN1_item_dup(ASN1_ITEM_rptr(X509_NAME_ENTRY), ne); - } - int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md, unsigned int *len) { diff --git a/crypto/x509v3/Makefile.ssl b/crypto/x509v3/Makefile.ssl index 97d26fd2eb..8d455d7d85 100644 --- a/crypto/x509v3/Makefile.ssl +++ b/crypto/x509v3/Makefile.ssl @@ -26,11 +26,11 @@ LIB=$(TOP)/libcrypto.a LIBSRC= v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c \ v3_lib.c v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c v3_skey.c v3_akey.c \ v3_pku.c v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c v3_info.c \ -v3_ocsp.c +v3_ocsp.c v3_akeya.c LIBOBJ= v3_bcons.o v3_bitst.o v3_conf.o v3_extku.o v3_ia5.o v3_lib.o \ v3_prn.o v3_utl.o v3err.o v3_genn.o v3_alt.o v3_skey.o v3_akey.o v3_pku.o \ v3_int.o v3_enum.o v3_sxnet.o v3_cpols.o v3_crld.o v3_purp.o v3_info.o \ -v3_ocsp.o +v3_ocsp.o v3_akeya.o SRC= $(LIBSRC) diff --git a/crypto/x509v3/v3_akey.c b/crypto/x509v3/v3_akey.c index 8ec41ab9d6..97e686f97a 100644 --- a/crypto/x509v3/v3_akey.c +++ b/crypto/x509v3/v3_akey.c @@ -78,14 +78,6 @@ NID_authority_key_identifier, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYI NULL }; -ASN1_SEQUENCE(AUTHORITY_KEYID) = { - ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0), - ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1), - ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2) -} ASN1_SEQUENCE_END(AUTHORITY_KEYID) - -IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID) - static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist) { diff --git a/crypto/x509v3/v3_akeya.c b/crypto/x509v3/v3_akeya.c new file mode 100644 index 0000000000..2aafa26ba7 --- /dev/null +++ b/crypto/x509v3/v3_akeya.c @@ -0,0 +1,72 @@ +/* v3_akey_asn1.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 +#include "cryptlib.h" +#include +#include +#include +#include + +ASN1_SEQUENCE(AUTHORITY_KEYID) = { + ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0), + ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1), + ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2) +} ASN1_SEQUENCE_END(AUTHORITY_KEYID) + +IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID) -- 2.25.1