From 8d8c7266d4de9887fb0190a0770df9dc254a16a3 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 28 Mar 1999 23:17:34 +0000 Subject: [PATCH] Yet more PKCS#12 integration: add lots of files under crypto/pkcs12 and add them to the build environment. --- CHANGES | 5 + Makefile.org | 2 +- crypto/Makefile.ssl | 2 +- crypto/asn1/p5_pbe.c | 68 +++++++ crypto/err/err.h | 2 + crypto/err/err_all.c | 2 + crypto/err/ssleay.ec | 1 + crypto/evp/c_all.c | 2 + crypto/pkcs12/Makefile.ssl | 91 +++++++++ crypto/pkcs12/p12_add.c | 236 +++++++++++++++++++++ crypto/pkcs12/p12_attr.c | 244 ++++++++++++++++++++++ crypto/pkcs12/p12_bags.c | 203 ++++++++++++++++++ crypto/pkcs12/p12_crpt.c | 104 ++++++++++ crypto/pkcs12/p12_crt.c | 170 ++++++++++++++++ crypto/pkcs12/p12_decr.c | 206 +++++++++++++++++++ crypto/pkcs12/p12_init.c | 102 ++++++++++ crypto/pkcs12/p12_key.c | 190 +++++++++++++++++ crypto/pkcs12/p12_kiss.c | 269 ++++++++++++++++++++++++ crypto/pkcs12/p12_lib.c | 123 +++++++++++ crypto/pkcs12/p12_mac.c | 120 +++++++++++ crypto/pkcs12/p12_mutl.c | 187 +++++++++++++++++ crypto/pkcs12/p12_sbag.c | 238 ++++++++++++++++++++++ crypto/pkcs12/p12_utl.c | 140 +++++++++++++ crypto/pkcs12/pk12err.c | 136 +++++++++++++ crypto/pkcs12/pkcs12.err | 52 +++++ crypto/pkcs12/pkcs12.h | 407 +++++++++++++++++++++++++++++++++++++ crypto/x509/x509.h | 2 + 27 files changed, 3302 insertions(+), 2 deletions(-) create mode 100644 crypto/pkcs12/Makefile.ssl create mode 100644 crypto/pkcs12/p12_add.c create mode 100644 crypto/pkcs12/p12_attr.c create mode 100644 crypto/pkcs12/p12_bags.c create mode 100644 crypto/pkcs12/p12_crpt.c create mode 100644 crypto/pkcs12/p12_crt.c create mode 100644 crypto/pkcs12/p12_decr.c create mode 100644 crypto/pkcs12/p12_init.c create mode 100644 crypto/pkcs12/p12_key.c create mode 100644 crypto/pkcs12/p12_kiss.c create mode 100644 crypto/pkcs12/p12_lib.c create mode 100644 crypto/pkcs12/p12_mac.c create mode 100644 crypto/pkcs12/p12_mutl.c create mode 100644 crypto/pkcs12/p12_sbag.c create mode 100644 crypto/pkcs12/p12_utl.c create mode 100644 crypto/pkcs12/pk12err.c create mode 100644 crypto/pkcs12/pkcs12.err create mode 100644 crypto/pkcs12/pkcs12.h diff --git a/CHANGES b/CHANGES index f597acccbc..6750bc4435 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,11 @@ Changes between 0.9.2b and 0.9.3 + *) More PKCS#12 integration. Add new pkcs12 directory with Makefile.ssl and + modify error routines to work internally. Add error codes and PBE init + to library startup routines. + [Steve Henson] + *) Further PKCS#12 integration. Added password based encryption, PKCS#8 and packing functions to asn1 and evp. Changed function names and error codes along the way. diff --git a/Makefile.org b/Makefile.org index d8af86e92a..7c000f2567 100644 --- a/Makefile.org +++ b/Makefile.org @@ -133,7 +133,7 @@ SDIRS= \ des rc2 rc4 rc5 idea bf cast \ bn rsa dsa dh \ buffer bio stack lhash rand err objects \ - evp asn1 pem x509 x509v3 conf txt_db pkcs7 comp + evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp # Do not edit this manually. Use util/ssldir.pl do change this! INSTALLTOP=/usr/local/ssl diff --git a/crypto/Makefile.ssl b/crypto/Makefile.ssl index 70194b4c33..1a03301060 100644 --- a/crypto/Makefile.ssl +++ b/crypto/Makefile.ssl @@ -29,7 +29,7 @@ SDIRS= md2 md5 sha mdc2 hmac ripemd \ des rc2 rc4 rc5 idea bf cast \ bn rsa dsa dh \ buffer bio stack lhash rand err objects \ - evp asn1 pem x509 x509v3 conf txt_db pkcs7 comp + evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp GENERAL=Makefile README diff --git a/crypto/asn1/p5_pbe.c b/crypto/asn1/p5_pbe.c index a94d6c14d8..afcf955996 100644 --- a/crypto/asn1/p5_pbe.c +++ b/crypto/asn1/p5_pbe.c @@ -59,9 +59,12 @@ #include #include "cryptlib.h" #include "asn1_mac.h" +#include "rand.h" /* PKCS#5 password based encryption structure */ +#define PKCS5_SALT_LEN 8 + /* *ASN1err(ASN1_F_PBEPARAM_NEW,ASN1_R_DEOCDE_ERROR) *ASN1err(ASN1_F_D2I_PBEPARAM,ASN1_R_DEOCDE_ERROR) @@ -114,3 +117,68 @@ PBEPARAM *a; ASN1_INTEGER_free (a->iter); Free ((char *)a); } + +/* Return an algorithm identifier for a PKCS#5 PBE algorithm */ + +X509_ALGOR *PKCS5_pbe_set(alg, iter, salt, saltlen) +int alg; +int iter; +unsigned char *salt; +int saltlen; +{ + unsigned char *pdata, *ptmp; + int plen; + PBEPARAM *pbe; + ASN1_OBJECT *al; + X509_ALGOR *algor; + ASN1_TYPE *astype; + + if (!(pbe = PBEPARAM_new ())) { + ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + return NULL; + } + ASN1_INTEGER_set (pbe->iter, iter); + if (!saltlen) saltlen = PKCS5_SALT_LEN; + if (!(pbe->salt->data = Malloc (saltlen))) { + ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + return NULL; + } + pbe->salt->length = saltlen; + if (salt) memcpy (pbe->salt->data, salt, saltlen); + else RAND_bytes (pbe->salt->data, saltlen); + if (!(plen = i2d_PBEPARAM (pbe, NULL))) { + ASN1err(ASN1_F_ASN1_PBE_SET,ASN1_R_ENCODE_ERROR); + return NULL; + } + if (!(pdata = Malloc (plen))) { + ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + return NULL; + } + ptmp = pdata; + i2d_PBEPARAM (pbe, &ptmp); + PBEPARAM_free (pbe); + + if (!(astype = ASN1_TYPE_new())) { + ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + return NULL; + } + + astype->type = V_ASN1_SEQUENCE; + if (!(astype->value.sequence=ASN1_STRING_new())) { + ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + return NULL; + } + ASN1_STRING_set (astype->value.sequence, pdata, plen); + Free (pdata); + + al = OBJ_nid2obj(alg); /* never need to free al */ + if (!(algor = X509_ALGOR_new())) { + ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + return NULL; + } + ASN1_OBJECT_free(algor->algorithm); + algor->algorithm = al; + algor->parameter = astype; + + return (algor); +} diff --git a/crypto/err/err.h b/crypto/err/err.h index fe037109d9..c10868ac7f 100644 --- a/crypto/err/err.h +++ b/crypto/err/err.h @@ -117,6 +117,7 @@ typedef struct err_state_st #define ERR_LIB_BIO 32 #define ERR_LIB_PKCS7 33 #define ERR_LIB_X509V3 34 +#define ERR_LIB_PKCS12 35 #define ERR_LIB_USER 128 @@ -143,6 +144,7 @@ typedef struct err_state_st #define PROXYerr(f,r) ERR_PUT_error(ERR_LIB_PROXY,(f),(r),ERR_file_name,__LINE__) #define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),ERR_file_name,__LINE__) #define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),ERR_file_name,__LINE__) +#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),ERR_file_name,__LINE__) /* Borland C seems too stupid to be able to shift and do longs in * the pre-processor :-( */ diff --git a/crypto/err/err_all.c b/crypto/err/err_all.c index 6917b48fb2..06076064f6 100644 --- a/crypto/err/err_all.c +++ b/crypto/err/err_all.c @@ -79,6 +79,7 @@ #include "x509.h" #include "x509v3.h" #include "conf.h" +#include "pkcs12.h" #include "err.h" void ERR_load_crypto_strings() @@ -114,5 +115,6 @@ void ERR_load_crypto_strings() ERR_load_X509V3_strings(); ERR_load_CRYPTO_strings(); ERR_load_PKCS7_strings(); + ERR_load_PKCS12_strings(); #endif } diff --git a/crypto/err/ssleay.ec b/crypto/err/ssleay.ec index fa2df26ca2..2f9fd16edc 100644 --- a/crypto/err/ssleay.ec +++ b/crypto/err/ssleay.ec @@ -16,6 +16,7 @@ L ASN1 asn1/asn1.err L CONF conf/conf.err L PROXY proxy/proxy.err L PKCS7 pkcs7/pkcs7.err +L PKCS12 pkcs12/pkcs12.err L RSAREF ../rsaref/rsaref.err L SSL ../ssl/ssl.err L SSL2 ../ssl/ssl2.err diff --git a/crypto/evp/c_all.c b/crypto/evp/c_all.c index f2e0500dd3..51f7aba805 100644 --- a/crypto/evp/c_all.c +++ b/crypto/evp/c_all.c @@ -59,6 +59,7 @@ #include #include "cryptlib.h" #include "evp.h" +#include "pkcs12.h" #include "objects.h" void SSLeay_add_all_algorithms() @@ -187,4 +188,5 @@ void SSLeay_add_all_digests() EVP_add_digest_alias(SN_ripemd160,"ripemd"); EVP_add_digest_alias(SN_ripemd160,"rmd160"); #endif + PKCS12_PBE_add(); } diff --git a/crypto/pkcs12/Makefile.ssl b/crypto/pkcs12/Makefile.ssl new file mode 100644 index 0000000000..a53e1c425f --- /dev/null +++ b/crypto/pkcs12/Makefile.ssl @@ -0,0 +1,91 @@ +# +# SSLeay/crypto/asn1/Makefile +# + +DIR= pkcs12 +TOP= ../.. +CC= cc +INCLUDES= -I.. -I../../include +CFLAG=-g +INSTALLTOP=/usr/local/ssl +MAKE= make -f Makefile.ssl +MAKEDEPEND= $(TOP)/util/domd $(TOP) +MAKEFILE= Makefile.ssl +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +ERR=pkcs12 +ERRC=pk12err +GENERAL=Makefile +TEST= +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC= p12_add.c p12_attr.c p12_bags.c p12_crpt.c p12_crt.c p12_decr.c \ + p12_init.c p12_key.c p12_kiss.c p12_lib.c p12_mac.c p12_mutl.c\ + p12_sbag.c p12_utl.c pk12err.c +LIBOBJ= p12_add.o p12_attr.o p12_bags.o p12_crpt.o p12_crt.o p12_decr.o \ + p12_init.o p12_key.o p12_kiss.o p12_lib.o p12_mac.o p12_mutl.o\ + p12_sbag.o p12_utl.o pk12err.o + +SRC= $(LIBSRC) + +EXHEADER= pkcs12.h +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +test: + +all: lib + +lib: $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + sh $(TOP)/util/ranlib.sh $(LIB) + @touch lib + +files: + perl $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO + +links: + @$(TOP)/util/point.sh Makefile.ssl Makefile + @$(TOP)/util/mklink.sh ../../include $(EXHEADER) + @$(TOP)/util/mklink.sh ../../test $(TEST) + @$(TOP)/util/mklink.sh ../../apps $(APPS) + +install: + @for i in $(EXHEADER) ; \ + do \ + (cp $$i $(INSTALLTOP)/include/$$i; \ + chmod 644 $(INSTALLTOP)/include/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) $(INCLUDES) $(PROGS) $(LIBSRC) + +dclean: + perl -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +errors: $(ERRC).c + +$(ERRC).c: $(ERR).err + perl $(TOP)/util/err-ins.pl $(ERR).err $(ERR).h + perl ../err/err_genc.pl -s $(ERR).h $(ERRC).c + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c new file mode 100644 index 0000000000..2022b953f5 --- /dev/null +++ b/crypto/pkcs12/p12_add.c @@ -0,0 +1,236 @@ +/* p12_add.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 +#include +#include "pkcs12.h" + +/* Pack an object into an OCTET STRING and turn into a safebag */ + +PKCS12_SAFEBAG *PKCS12_pack_safebag (obj, i2d, nid1, nid2) +char *obj; +int (*i2d)(); +int nid1; +int nid2; + +{ + PKCS12_BAGS *bag; + PKCS12_SAFEBAG *safebag; + if (!(bag = PKCS12_BAGS_new ())) { + PKCS12err(PKCS12_F_PKCS12_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + M_ASN1_OBJECT_set(bag->type, nid1); + if (!ASN1_pack_string(obj, i2d, &bag->value.octet)) { + PKCS12err(PKCS12_F_PKCS12_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!(safebag = PKCS12_SAFEBAG_new ())) { + PKCS12err(PKCS12_F_PKCS12_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + safebag->value.bag = bag; + M_ASN1_OBJECT_set(safebag->type, nid2); + return safebag; +} + +/* Turn PKCS8 object into a keybag */ + +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG (p8) +PKCS8_PRIV_KEY_INFO *p8; +{ + PKCS12_SAFEBAG *bag; + if (!(bag = PKCS12_SAFEBAG_new())) { + PKCS12err(PKCS12_F_PKCS12_MAKE_SAFEBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + M_ASN1_OBJECT_set(bag->type, NID_keyBag); + bag->value.keybag = p8; + return bag; +} + +/* Turn PKCS8 object into a shrouded keybag */ + +PKCS12_SAFEBAG + *PKCS12_MAKE_SHKEYBAG (pbe_nid, pass, passlen, salt, saltlen, iter, p8)int pbe_nid; +unsigned char *pass; +int passlen; +unsigned char *salt; +int saltlen; +int iter; +PKCS8_PRIV_KEY_INFO *p8; +{ + PKCS12_SAFEBAG *bag; + + /* Set up the safe bag */ + if (!(bag = PKCS12_SAFEBAG_new ())) { + PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + + M_ASN1_OBJECT_set(bag->type, NID_pkcs8ShroudedKeyBag); + if (!(bag->value.shkeybag = + PKCS8_encrypt(pbe_nid, pass, passlen, salt, saltlen, iter, p8))) { + PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + + return bag; +} + +/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */ +PKCS7 *PKCS12_pack_p7data (sk) +STACK *sk; +{ + PKCS7 *p7; + if (!(p7 = PKCS7_new())) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7_DATA, ERR_R_MALLOC_FAILURE); + return NULL; + } + M_ASN1_OBJECT_set(p7->type, NID_pkcs7_data); + if (!(p7->d.data = ASN1_OCTET_STRING_new())) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7_DATA, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!ASN1_seq_pack(sk, i2d_PKCS12_SAFEBAG, &p7->d.data->data, + &p7->d.data->length)) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE); + return NULL; + } + return p7; +} + +/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */ + +PKCS7 *PKCS12_pack_p7encdata (pbe_nid, pass, passlen, salt, saltlen, iter, + bags) +int pbe_nid; +unsigned char *pass; +int passlen; +unsigned char *salt; +int saltlen; +int iter; +STACK *bags; +{ + PKCS7 *p7; + X509_ALGOR *pbe; + if (!(p7 = PKCS7_new())) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); + return NULL; + } + /* The next bit may end up in PKCS7_set_type eventually */ + M_ASN1_OBJECT_set(p7->type, NID_pkcs7_encrypted); + if (!(p7->d.encrypted = PKCS7_ENCRYPT_new ())) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); + return NULL; + } + ASN1_INTEGER_set (p7->d.encrypted->version, 0); + M_ASN1_OBJECT_set(p7->d.encrypted->enc_data->content_type, + NID_pkcs7_data); + if (!(pbe = PKCS5_pbe_set (pbe_nid, iter, salt, saltlen))) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); + return NULL; + } + X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm); + p7->d.encrypted->enc_data->algorithm = pbe; + ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data); + if (!(p7->d.encrypted->enc_data->enc_data = + PKCS12_i2d_encrypt (pbe, i2d_PKCS12_SAFEBAG, pass, passlen, + (char *)bags, 1))) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR); + return NULL; + } + + return p7; +} + +X509_SIG *PKCS8_encrypt (pbe_nid, pass, passlen, salt, saltlen, iter, p8inf) +int pbe_nid; +unsigned char *pass; +int passlen; +unsigned char *salt; +int saltlen; +int iter; +PKCS8_PRIV_KEY_INFO *p8inf; +{ + X509_SIG *p8; + X509_ALGOR *pbe; + + if (!(p8 = X509_SIG_new())) { + PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!(pbe = PKCS5_pbe_set (pbe_nid, iter, salt, saltlen))) { + PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE); + return NULL; + } + X509_ALGOR_free(p8->algor); + p8->algor = pbe; + ASN1_OCTET_STRING_free(p8->digest); + if (!(p8->digest = + PKCS12_i2d_encrypt (pbe, i2d_PKCS8_PRIV_KEY_INFO, pass, passlen, + (char *)p8inf, 0))) { + PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); + return NULL; + } + + return p8; +} diff --git a/crypto/pkcs12/p12_attr.c b/crypto/pkcs12/p12_attr.c new file mode 100644 index 0000000000..f528742d39 --- /dev/null +++ b/crypto/pkcs12/p12_attr.c @@ -0,0 +1,244 @@ +/* p12_attr.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 +#include +#include +#include "pkcs12.h" + +/* Add a local keyid to a safebag */ + +int PKCS12_add_localkeyid (bag, name, namelen) +PKCS12_SAFEBAG *bag; +unsigned char *name; +int namelen; +{ + X509_ATTRIBUTE *attrib; + ASN1_BMPSTRING *oct; + ASN1_TYPE *keyid; + if (!(keyid = ASN1_TYPE_new ())) { + PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); + return 0; + } + keyid->type = V_ASN1_OCTET_STRING; + if (!(oct = ASN1_OCTET_STRING_new())) { + PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!ASN1_OCTET_STRING_set(oct, name, namelen)) { + PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); + return 0; + } + keyid->value.octet_string = oct; + if (!(attrib = X509_ATTRIBUTE_new ())) { + PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); + return 0; + } + M_ASN1_OBJECT_set(attrib->object, NID_localKeyID); + if (!(attrib->value.set = sk_new(NULL))) { + PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); + return 0; + } + sk_push (attrib->value.set, (char *)keyid); + attrib->set = 1; + if (!bag->attrib && !(bag->attrib = sk_new (NULL))) { + PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); + return 0; + } + sk_push (bag->attrib, (char *)attrib); + return 1; +} + +/* Add key usage to PKCS#8 structure */ + +int PKCS8_add_keyusage (p8, usage) +PKCS8_PRIV_KEY_INFO *p8; +int usage; +{ + X509_ATTRIBUTE *attrib; + ASN1_BIT_STRING *bstr; + ASN1_TYPE *keyid; + unsigned char us_val; + us_val = (unsigned char) usage; + if (!(keyid = ASN1_TYPE_new ())) { + PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); + return 0; + } + keyid->type = V_ASN1_BIT_STRING; + if (!(bstr = ASN1_BIT_STRING_new())) { + PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!ASN1_BIT_STRING_set(bstr, &us_val, 1)) { + PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); + return 0; + } + keyid->value.bit_string = bstr; + if (!(attrib = X509_ATTRIBUTE_new ())) { + PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); + return 0; + } + M_ASN1_OBJECT_set(attrib->object, NID_key_usage); + if (!(attrib->value.set = sk_new(NULL))) { + PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); + return 0; + } + sk_push (attrib->value.set, (char *)keyid); + attrib->set = 1; + if (!p8->attributes && !(p8->attributes = sk_new (NULL))) { + PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); + return 0; + } + sk_push (p8->attributes, (char *)attrib); + return 1; +} + +/* Add a friendlyname to a safebag */ + +int PKCS12_add_friendlyname_asc (bag, name, namelen) +PKCS12_SAFEBAG *bag; +unsigned char *name; +int namelen; +{ + unsigned char *uniname; + int ret, unilen; + if (!asc2uni(name, &uniname, &unilen)) { + PKCS12err(PKCS12_F_ADD_FRIENDLYNAME_ASC,ERR_R_MALLOC_FAILURE); + return 0; + } + ret = PKCS12_add_friendlyname_uni (bag, uniname, unilen); + Free(uniname); + return ret; +} + + +int PKCS12_add_friendlyname_uni (bag, name, namelen) +PKCS12_SAFEBAG *bag; +unsigned char *name; +int namelen; +{ + X509_ATTRIBUTE *attrib; + ASN1_BMPSTRING *bmp; + ASN1_TYPE *fname; + /* Zap ending double null if included */ + if(!name[namelen - 1] && !name[namelen - 2]) namelen -= 2; + if (!(fname = ASN1_TYPE_new ())) { + PKCS12err(PKCS12_F_ADD_FRIENDLYNAME_UNI,ERR_R_MALLOC_FAILURE); + return 0; + } + fname->type = V_ASN1_BMPSTRING; + if (!(bmp = ASN1_BMPSTRING_new())) { + PKCS12err(PKCS12_F_ADD_FRIENDLYNAME_UNI,ERR_R_MALLOC_FAILURE); + return 0; + } + if (!(bmp->data = Malloc (namelen))) { + PKCS12err(PKCS12_F_ADD_FRIENDLYNAME_UNI,ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy (bmp->data, name, namelen); + bmp->length = namelen; + fname->value.bmpstring = bmp; + if (!(attrib = X509_ATTRIBUTE_new ())) { + PKCS12err(PKCS12_F_ADD_FRIENDLYNAME_UNI,ERR_R_MALLOC_FAILURE); + return 0; + } + M_ASN1_OBJECT_set(attrib->object, NID_friendlyName); + if (!(attrib->value.set = sk_new(NULL))) { + PKCS12err(PKCS12_F_ADD_FRIENDLYNAME,ERR_R_MALLOC_FAILURE); + return 0; + } + sk_push (attrib->value.set, (char *)fname); + attrib->set = 1; + if (!bag->attrib && !(bag->attrib = sk_new (NULL))) { + PKCS12err(PKCS12_F_ADD_FRIENDLYNAME_UNI, ERR_R_MALLOC_FAILURE); + return 0; + } + sk_push (bag->attrib, (char *)attrib); + return PKCS12_OK; +} + +ASN1_TYPE *PKCS12_get_attr_gen (attrs, attr_nid) +STACK *attrs; +int attr_nid; +{ + X509_ATTRIBUTE *attrib; + int i; + if (!attrs) return NULL; + for (i = 0; i < sk_num (attrs); i++) { + attrib = (X509_ATTRIBUTE *) sk_value (attrs, i); + if (OBJ_obj2nid (attrib->object) == attr_nid) { + if (sk_num (attrib->value.set)) + return (ASN1_TYPE *) + sk_value (attrib->value.set, 0); + else return NULL; + } + } + return NULL; +} + +char *PKCS12_get_friendlyname(bag) +PKCS12_SAFEBAG *bag; +{ + ASN1_TYPE *atype; + if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) return NULL; + if (atype->type != V_ASN1_BMPSTRING) return NULL; + return uni2asc(atype->value.bmpstring->data, + atype->value.bmpstring->length); +} + diff --git a/crypto/pkcs12/p12_bags.c b/crypto/pkcs12/p12_bags.c new file mode 100644 index 0000000000..60d12fb0f2 --- /dev/null +++ b/crypto/pkcs12/p12_bags.c @@ -0,0 +1,203 @@ +/* p12_bags.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 +#include +#include +#include "pkcs12.h" + +/* + *ASN1err(ASN1_F_PKCS12_BAGS_NEW,ASN1_R_DECODE_ERROR) + *ASN1err(ASN1_F_D2I_PKCS12_BAGS,ASN1_R_DECODE_ERROR) + */ + +int i2d_PKCS12_BAGS(a,pp) +PKCS12_BAGS *a; +unsigned char **pp; +{ + int bagnid, v = 0; + M_ASN1_I2D_vars(a); + bagnid = OBJ_obj2nid (a->type); + M_ASN1_I2D_len (a->type, i2d_ASN1_OBJECT); + + switch (bagnid) { + + case NID_x509Certificate: + M_ASN1_I2D_len_EXP_opt (a->value.x509cert, + i2d_ASN1_OCTET_STRING, 0, v); + break; + + case NID_x509Crl: + M_ASN1_I2D_len_EXP_opt (a->value.x509crl, + i2d_ASN1_OCTET_STRING, 0, v); + break; + + case NID_sdsiCertificate: + M_ASN1_I2D_len_EXP_opt (a->value.sdsicert, + i2d_ASN1_IA5STRING, 0, v); + break; + + default: + M_ASN1_I2D_len_EXP_opt (a->value.other, + i2d_ASN1_TYPE, 0, v); + break; + } + + M_ASN1_I2D_seq_total (); + + M_ASN1_I2D_put (a->type, i2d_ASN1_OBJECT); + + switch (bagnid) { + + case NID_x509Certificate: + M_ASN1_I2D_put_EXP_opt (a->value.x509cert, + i2d_ASN1_OCTET_STRING, 0, v); + break; + + case NID_x509Crl: + M_ASN1_I2D_put_EXP_opt (a->value.x509crl, + i2d_ASN1_OCTET_STRING, 0, v); + break; + + case NID_sdsiCertificate: + M_ASN1_I2D_put_EXP_opt (a->value.sdsicert, + i2d_ASN1_IA5STRING, 0, v); + break; + + default: + M_ASN1_I2D_put_EXP_opt (a->value.other, i2d_ASN1_TYPE, 0, v); + break; + } + M_ASN1_I2D_finish(); +} + +PKCS12_BAGS *PKCS12_BAGS_new() +{ + PKCS12_BAGS *ret=NULL; + ASN1_CTX c; + M_ASN1_New_Malloc(ret, PKCS12_BAGS); + ret->type=NULL; + ret->value.other=NULL; + return (ret); + M_ASN1_New_Error(ASN1_F_PKCS12_BAGS_NEW); +} + +PKCS12_BAGS *d2i_PKCS12_BAGS(a,pp,length) +PKCS12_BAGS **a; +unsigned char **pp; +long length; +{ + int bagnid; + M_ASN1_D2I_vars(a,PKCS12_BAGS *,PKCS12_BAGS_new); + M_ASN1_D2I_Init(); + M_ASN1_D2I_start_sequence(); + M_ASN1_D2I_get (ret->type, d2i_ASN1_OBJECT); + bagnid = OBJ_obj2nid (ret->type); + switch (bagnid) { + + case NID_x509Certificate: + M_ASN1_D2I_get_EXP_opt (ret->value.x509cert, + d2i_ASN1_OCTET_STRING, 0); + break; + + case NID_x509Crl: + M_ASN1_D2I_get_EXP_opt (ret->value.x509crl, + d2i_ASN1_OCTET_STRING, 0); + break; + + case NID_sdsiCertificate: + M_ASN1_D2I_get_EXP_opt (ret->value.sdsicert, + d2i_ASN1_IA5STRING, 0); + break; + + default: + M_ASN1_D2I_get_EXP_opt (ret->value.other, + d2i_ASN1_TYPE, 0); + break; + } + + M_ASN1_D2I_Finish(a, PKCS12_BAGS_free, ASN1_F_D2I_PKCS12_BAGS); +} + +void PKCS12_BAGS_free (a) +PKCS12_BAGS *a; +{ + if (a == NULL) return; + switch (OBJ_obj2nid(a->type)) { + + case NID_x509Certificate: + ASN1_OCTET_STRING_free (a->value.x509cert); + break; + + case NID_x509Crl: + ASN1_OCTET_STRING_free (a->value.x509crl); + break; + + case NID_sdsiCertificate: + ASN1_IA5STRING_free (a->value.sdsicert); + break; + + default: + ASN1_TYPE_free (a->value.other); + break; + } + + ASN1_OBJECT_free (a->type); + Free ((char *)a); +} diff --git a/crypto/pkcs12/p12_crpt.c b/crypto/pkcs12/p12_crpt.c new file mode 100644 index 0000000000..96c551e074 --- /dev/null +++ b/crypto/pkcs12/p12_crpt.c @@ -0,0 +1,104 @@ +/* p12_crpt.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 +#include +#include "pkcs12.h" + +/* PKCS#12 specific PBE functions */ + +void PKCS12_PBE_add() +{ +EVP_PBE_alg_add(NID_pbe_WithSHA1And128BitRC4, EVP_rc4(), EVP_sha1(), + PKCS12_PBE_keyivgen); +EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC4, EVP_rc4_40(), EVP_sha1(), + PKCS12_PBE_keyivgen); +EVP_PBE_alg_add(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, + EVP_des_ede3_cbc(), EVP_sha1(), PKCS12_PBE_keyivgen); +EVP_PBE_alg_add(NID_pbe_WithSHA1And2_Key_TripleDES_CBC, + EVP_des_ede_cbc(), EVP_sha1(), PKCS12_PBE_keyivgen); +EVP_PBE_alg_add(NID_pbe_WithSHA1And128BitRC2_CBC, EVP_rc2_cbc(), + EVP_sha1(), PKCS12_PBE_keyivgen); +EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc(), + EVP_sha1(), PKCS12_PBE_keyivgen); +} + +int PKCS12_PBE_keyivgen (pass, passlen, salt, saltlen, iter, cipher, + md, key, iv) +unsigned char *pass; +int passlen; +unsigned char *salt; +int saltlen; +int iter; +EVP_CIPHER *cipher; +EVP_MD *md; +unsigned char *key, *iv; +{ + if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_KEY_ID, + iter, EVP_CIPHER_key_length(cipher), key, md)) { + PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_KEY_GEN_ERROR); + return 0; + } + if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_IV_ID, + iter, EVP_CIPHER_iv_length(cipher), iv, md)) { + PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_IV_GEN_ERROR); + return 0; + } + return 1; +} diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c new file mode 100644 index 0000000000..f2e0aac347 --- /dev/null +++ b/crypto/pkcs12/p12_crt.c @@ -0,0 +1,170 @@ +/* p12_crt.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 +#include +#include +#include +#include "pkcs12.h" + +PKCS12 *PKCS12_create(pass, name, pkey, cert, ca, nid_key, nid_cert, iter, + mac_iter, keytype) +char *pass; +char *name; +EVP_PKEY *pkey; +X509 *cert; +STACK *ca; +int nid_key; +int nid_cert; +int iter; +int mac_iter; +int keytype; +{ + PKCS12 *p12; + STACK *bags, *safes; + PKCS12_SAFEBAG *bag; + PKCS8_PRIV_KEY_INFO *p8; + PKCS7 *authsafe; + X509 *tcert; + int i; + unsigned char keyid[EVP_MAX_MD_SIZE]; + int keyidlen; + + /* Set defaults */ + if(!nid_cert) nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; + if(!nid_key) nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + if(!iter) iter = 1000; + if(!mac_iter) mac_iter = 1; + + if(!pkey || !cert) { + PKCS12err(PKCS12_F_PKCS12_CREATE,PKCS12_R_INVALID_NULL_ARGUMENT); + return NULL; + } + + if(!(bags = sk_new (NULL))) { + PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* Add user certificate */ + if(!(bag = M_PKCS12_x5092certbag(cert))) return NULL; + if(name && !PKCS12_add_friendlyname(bag, name, -1)) return NULL; + X509_digest(cert, EVP_sha1(), keyid, &keyidlen); + if(!PKCS12_add_localkeyid(bag, keyid, keyidlen)) return NULL; + + if(!sk_push(bags, (char *)bag)) { + PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* Add all other certificates */ + if(ca) { + for(i = 0; i < sk_num(ca); i++) { + tcert = (X509 *)sk_value(ca, i); + if(!(bag = M_PKCS12_x5092certbag(tcert))) return NULL; + if(!sk_push(bags, (char *)bag)) { + PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); + return NULL; + } + } + } + + /* Turn certbags into encrypted authsafe */ + authsafe = PKCS12_pack_p7encdata (nid_cert, pass, -1, NULL, 0, + iter, bags); + sk_pop_free(bags, PKCS12_SAFEBAG_free); + + if (!authsafe) return NULL; + + if(!(safes = sk_new (NULL)) || !sk_push(safes, (char *)authsafe)) { + PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* Make a shrouded key bag */ + if(!(p8 = EVP_PKEY2PKCS8 (pkey))) return NULL; + if(keytype && !PKCS8_add_keyusage(p8, keytype)) return NULL; + bag = PKCS12_MAKE_SHKEYBAG (nid_key, pass, -1, NULL, 0, iter, p8); + if(!bag) return NULL; + PKCS8_PRIV_KEY_INFO_free(p8); + if (name && !PKCS12_add_friendlyname (bag, name, -1)) return NULL; + if(!PKCS12_add_localkeyid (bag, keyid, keyidlen)) return NULL; + if(!(bags = sk_new(NULL)) || !sk_push (bags, (char *)bag)) { + PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); + return NULL; + } + /* Turn it into unencrypted safe bag */ + if(!(authsafe = PKCS12_pack_p7data (bags))) return NULL; + sk_pop_free(bags, PKCS12_SAFEBAG_free); + if(!sk_push(safes, (char *)authsafe)) { + PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); + return NULL; + } + + if(!(p12 = PKCS12_init (NID_pkcs7_data))) return NULL; + + if(!M_PKCS12_pack_authsafes (p12, safes)) return NULL; + + sk_pop_free(safes, PKCS7_free); + + if(!PKCS12_set_mac (p12, pass, -1, NULL, 0, mac_iter, NULL)) return NULL; + + return p12; + +} diff --git a/crypto/pkcs12/p12_decr.c b/crypto/pkcs12/p12_decr.c new file mode 100644 index 0000000000..c4af4fa84b --- /dev/null +++ b/crypto/pkcs12/p12_decr.c @@ -0,0 +1,206 @@ +/* p12_decr.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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "hmac.h" +#include "pkcs12.h" + +/* Define this to dump decrypted output to files called DERnnn */ +/*#define DEBUG_DECRYPT*/ + + +/* Encrypt/Decrypt a buffer based on password and algor, result in a + * Malloc'ed buffer + */ + +unsigned char * PKCS12_pbe_crypt (algor, pass, passlen, in, inlen, + data, datalen, en_de) +X509_ALGOR *algor; +unsigned char *pass; +int passlen; +unsigned char *in; +int inlen; +unsigned char **data; +int *datalen; +int en_de; +{ + unsigned char *out; + int outlen, i; + EVP_CIPHER_CTX ctx; + + if(!(out = Malloc (inlen + 8))) { + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* Decrypt data */ + if (!EVP_PBE_ALGOR_CipherInit (algor, pass, passlen, &ctx, en_de)) { + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR); + return NULL; + } + EVP_CipherUpdate (&ctx, out, &i, in, inlen); + outlen = i; + if(!EVP_CipherFinal (&ctx, out + i, &i)) { + Free (out); + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,PKCS12_R_PKCS12_CIPHERFINAL_ERROR); + return NULL; + } + outlen += i; + if (datalen) *datalen = outlen; + if (data) *data = out; + return out; + +} + +/* Decrypt an OCTET STRING and decode ASN1 structure + * if seq & 1 'obj' is a stack of structures to be encoded + * if seq & 2 zero buffer after use + * as a sequence. + */ + +char * PKCS12_decrypt_d2i (algor, d2i, free_func, pass, passlen, oct, seq) +X509_ALGOR *algor; +char * (*d2i)(); +void (*free_func)(); +unsigned char *pass; +int passlen; +ASN1_OCTET_STRING *oct; +int seq; +{ + unsigned char *out, *p, *ret; + int outlen; + if (!PKCS12_pbe_crypt (algor, pass, passlen, oct->data, oct->length, + &out, &outlen, 0)) { + PKCS12err(PKCS12_F_PKCS12_DECRYPT_D2I,PKCS12_R_PKCS12_PBE_CRYPT_ERROR); + return NULL; + } + p = out; +#ifdef DEBUG_DECRYPT + { + FILE *op; + + char fname[30]; + static int fnm = 1; + sprintf(fname, "DER%d", fnm++); + op = fopen(fname, "wb"); + fwrite (p, 1, outlen, op); + fclose(op); + } +#endif + if (seq & 1) ret = (char *) d2i_ASN1_SET(NULL, &p, outlen, d2i, + free_func, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); + else ret = d2i(NULL, &p, outlen); + if (seq & 2) memset(out, 0, outlen); + if(!ret) PKCS12err(PKCS12_F_PKCS12_DECRYPT_D2I,PKCS12_R_DECODE_ERROR); + Free (out); + return ret; +} + +/* Encode ASN1 structure and encrypt, return OCTET STRING + * if 'seq' is non-zero 'obj' is a stack of structures to be encoded + * as a sequence + */ + +ASN1_OCTET_STRING *PKCS12_i2d_encrypt (algor, i2d, pass, passlen, obj, seq) +X509_ALGOR *algor; +int (*i2d)(); +unsigned char *pass; +int passlen; +char *obj; +int seq; +{ + ASN1_OCTET_STRING *oct; + unsigned char *in, *p; + int inlen; + if (!(oct = ASN1_OCTET_STRING_new ())) { + PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,ERR_R_MALLOC_FAILURE); + return NULL; + } + if (seq) inlen = i2d_ASN1_SET((STACK *)obj, NULL, i2d, V_ASN1_SEQUENCE, + V_ASN1_UNIVERSAL, IS_SEQUENCE); + else inlen = i2d (obj, NULL); + if (!inlen) { + PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,PKCS12_R_ENCODE_ERROR); + return NULL; + } + if (!(in = Malloc (inlen))) { + PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,ERR_R_MALLOC_FAILURE); + return NULL; + } + p = in; + if (seq) i2d_ASN1_SET((STACK *)obj, &p, i2d, V_ASN1_SEQUENCE, + V_ASN1_UNIVERSAL, IS_SEQUENCE); + else i2d (obj, &p); + if (!PKCS12_pbe_crypt (algor, pass, passlen, in, inlen, &oct->data, + &oct->length, 1)) { + PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,PKCS12_R_ENCRYPT_ERROR); + Free(in); + return NULL; + } + Free (in); + return oct; +} diff --git a/crypto/pkcs12/p12_init.c b/crypto/pkcs12/p12_init.c new file mode 100644 index 0000000000..055629131a --- /dev/null +++ b/crypto/pkcs12/p12_init.c @@ -0,0 +1,102 @@ +/* p12_init.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 +#include +#include +#include +#include "pkcs12.h" + +/* Initialise a PKCS12 structure to take data */ + +PKCS12 *PKCS12_init (mode) +int mode; +{ + PKCS12 *pkcs12; + if (!(pkcs12 = PKCS12_new())) { + PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!(pkcs12->version = ASN1_INTEGER_new ())) { + PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE); + return NULL; + } + ASN1_INTEGER_set (pkcs12->version, 3); + if (!(pkcs12->authsafes = PKCS7_new())) { + PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE); + return NULL; + } + M_ASN1_OBJECT_set(pkcs12->authsafes->type, mode); + switch (mode) { + case NID_pkcs7_data: + if (!(pkcs12->authsafes->d.data = + ASN1_OCTET_STRING_new())) { + PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE); + return NULL; + } + break; + default: + PKCS12err(PKCS12_F_PKCS12_INIT,PKCS12_R_UNSUPPORTED_PKCS12_MODE); + PKCS12_free(pkcs12); + return NULL; + break; + } + + return pkcs12; +} diff --git a/crypto/pkcs12/p12_key.c b/crypto/pkcs12/p12_key.c new file mode 100644 index 0000000000..f1506ba1cd --- /dev/null +++ b/crypto/pkcs12/p12_key.c @@ -0,0 +1,190 @@ +/* p12_key.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 +#include +#include +#include +#include "pkcs12.h" + + +/* Uncomment out this line to get debugging info about key generation */ +/*#define DEBUG_KEYGEN*/ +#ifdef DEBUG_KEYGEN +#include +extern BIO *bio_err; +void h__dump (unsigned char *p, int len); +#endif + +/* PKCS12 compatible key/IV generation */ +#ifndef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +int PKCS12_key_gen_asc (pass, passlen, salt, saltlen, id, iter, n, out, md_type) +unsigned char *pass, *salt, *out; +int passlen, saltlen, id, iter, n; +EVP_MD *md_type; +{ + int ret; + unsigned char *unipass; + int uniplen; + if (!asc2uni (pass, &unipass, &uniplen)) { + PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC,ERR_R_MALLOC_FAILURE); + return 0; + } + ret = PKCS12_key_gen_uni (unipass, uniplen, salt, saltlen, + id, iter, n, out, md_type); + memset(unipass, 0, uniplen); /* Clear password from memory */ + Free(unipass); + return ret; +} + +int PKCS12_key_gen_uni (pass, passlen, salt, saltlen, id, iter, n, out, md_type) +unsigned char *pass, *salt, *out; +int passlen, saltlen, id, iter, n; +EVP_MD *md_type; +{ + unsigned char *B, *D, *I, *p, *Ai; + int Slen, Plen, Ilen; + int i, j, u, v; + BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */ + EVP_MD_CTX ctx; +#ifdef DEBUG_KEYGEN + unsigned char *tmpout = out; + int tmpn = n; + BIO_printf (bio_err, "KEYGEN DEBUG\n"); + BIO_printf (bio_err, "ID %d, ITER %d\n", id, iter); + BIO_printf (bio_err, "Password (length %d):\n", passlen); + h__dump (pass, passlen); + BIO_printf (bio_err, "Salt (length %d):\n", saltlen); + h__dump (salt, saltlen); + BIO_printf (bio_err, "ID %d, ITER %d\n\n", id, iter); +#endif + v = EVP_MD_block_size (md_type); + u = EVP_MD_size (md_type); + D = Malloc (v); + Ai = Malloc (u); + B = Malloc (v + 1); + Slen = v * ((saltlen+v-1)/v); + Plen = v * ((passlen+v-1)/v); + Ilen = Slen + Plen; + I = Malloc (Ilen); + Ij = BN_new(); + Bpl1 = BN_new(); + if (!D || !Ai || !B || !I || !Ij || !Bpl1) { + PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0; i < v; i++) D[i] = id; + p = I; + for (i = 0; i < Slen; i++) *p++ = salt[i % saltlen]; + for (i = 0; i < Plen; i++) *p++ = pass[i % passlen]; + for (;;) { + EVP_DigestInit (&ctx, md_type); + EVP_DigestUpdate (&ctx, D, v); + EVP_DigestUpdate (&ctx, I, Ilen); + EVP_DigestFinal (&ctx, Ai, NULL); + for (j = 1; j < iter; j++) { + EVP_DigestInit (&ctx, md_type); + EVP_DigestUpdate (&ctx, Ai, u); + EVP_DigestFinal (&ctx, Ai, NULL); + } + memcpy (out, Ai, min (n, u)); + if (u >= n) { + Free (Ai); + Free (B); + Free (D); + Free (I); + BN_free (Ij); + BN_free (Bpl1); +#ifdef DEBUG_KEYGEN + BIO_printf (bio_err, "Output KEY (length %d)\n", tmpn); + h__dump (tmpout, tmpn); +#endif + return 1; + } + n -= u; + out += u; + for (j = 0; j < v; j++) B[j] = Ai[j % u]; + /* Work out B + 1 first then can use B as tmp space */ + BN_bin2bn (B, v, Bpl1); + BN_add_word (Bpl1, 1); + for (j = 0; j < Ilen ; j+=v) { + BN_bin2bn (I + j, v, Ij); + BN_add (Ij, Ij, Bpl1); + BN_bn2bin (Ij, B); + /* If more than 2^(v*8) - 1 cut off MSB */ + if (BN_num_bytes (Ij) > v) { + BN_bn2bin (Ij, B); + memcpy (I + j, B + 1, v); + } else BN_bn2bin (Ij, I + j); + } + } + return 0; /* This can't happen */ +} +#ifdef DEBUG_KEYGEN +void h__dump (p, len) +unsigned char *p; +int len; +{ + for (; len --; p++) BIO_printf (bio_err, "%02X", *p); + BIO_printf (bio_err, "\n"); +} +#endif diff --git a/crypto/pkcs12/p12_kiss.c b/crypto/pkcs12/p12_kiss.c new file mode 100644 index 0000000000..947e47644b --- /dev/null +++ b/crypto/pkcs12/p12_kiss.c @@ -0,0 +1,269 @@ +/* p12_kiss.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 +#include +#include +#include +#include +#include "pkcs12.h" + +/* Simplified PKCS#12 routines */ + +#ifndef NOPROTO +static int parse_pk12( PKCS12 *p12, unsigned char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca); +static int parse_bags( STACK *bags, unsigned char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca, ASN1_OCTET_STRING **keyid, char *keymatch); +static int parse_bag( PKCS12_SAFEBAG *bag, unsigned char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca, ASN1_OCTET_STRING **keyid, char *keymatch); +#else +static int parse_pk12(); +static int parse_bags(); +static int parse_bag(); +#endif + +/* Parse and decrypt a PKCS#12 structure returning user key, user cert + * and other (CA) certs. Note either ca should be NULL, *ca should be NULL, + * or it should point to a valid STACK structure. pkey and cert can be + * passed unitialised. + */ + +int PKCS12_parse (p12, pass, pkey, cert, ca) +PKCS12 *p12; +char *pass; +EVP_PKEY **pkey; +X509 **cert; +STACK **ca; +{ + +/* Check for NULL PKCS12 structure */ + +if(!p12) { + PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); + return 0; +} + +/* Allocate stack for ca certificates if needed */ +if ((ca != NULL) && (*ca == NULL)) { + if (!(*ca = sk_new(NULL))) { + PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE); + return 0; + } +} + +if(pkey) *pkey = NULL; +if(cert) *cert = NULL; + +/* Check the mac */ + +if (!PKCS12_verify_mac (p12, pass, -1)) { + PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); + goto err; +} + +if (!parse_pk12 (p12, pass, -1, pkey, cert, ca)) { + PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR); + goto err; +} + +return 1; + +err: + +if (pkey && *pkey) EVP_PKEY_free (*pkey); +if (cert && *cert) X509_free (*cert); +if (ca) sk_pop_free (*ca, X509_free); +return 0; + +} + +/* Parse the outer PKCS#12 structure */ + +static int parse_pk12 (p12, pass, passlen, pkey, cert, ca) +PKCS12 *p12; +unsigned char *pass; +int passlen; +EVP_PKEY **pkey; +X509 **cert; +STACK **ca; +{ + STACK *asafes, *bags; + int i, bagnid; + PKCS7 *p7; + ASN1_OCTET_STRING *keyid = NULL; + char keymatch = 0; + if (!( asafes = M_PKCS12_unpack_authsafes (p12))) return 0; + for (i = 0; i < sk_num (asafes); i++) { + p7 = (PKCS7 *) sk_value (asafes, i); + bagnid = OBJ_obj2nid (p7->type); + if (bagnid == NID_pkcs7_data) { + bags = M_PKCS12_unpack_p7data (p7); + } else if (bagnid == NID_pkcs7_encrypted) { + bags = M_PKCS12_unpack_p7encdata (p7, pass, passlen); + } else continue; + if (!bags) { + sk_pop_free (asafes, PKCS7_free); + return 0; + } + if (!parse_bags (bags, pass, passlen, pkey, cert, ca, + &keyid, &keymatch)) { + sk_pop_free (bags, PKCS12_SAFEBAG_free); + sk_pop_free (asafes, PKCS7_free); + return 0; + } + sk_pop_free (bags, PKCS12_SAFEBAG_free); + } + sk_pop_free (asafes, PKCS7_free); + if (keyid) ASN1_OCTET_STRING_free (keyid); + return 1; +} + + +static int parse_bags (bags, pass, passlen, pkey, cert, ca, keyid, keymatch) +STACK *bags; +unsigned char *pass; +int passlen; +EVP_PKEY **pkey; +X509 **cert; +STACK **ca; +ASN1_OCTET_STRING **keyid; +char *keymatch; +{ + int i; + for (i = 0; i < sk_num (bags); i++) { + if (!parse_bag ((PKCS12_SAFEBAG *)sk_value (bags, i), + pass, passlen, pkey, cert, ca, keyid, + keymatch)) return 0; + } + return 1; +} + +#define MATCH_KEY 0x1 +#define MATCH_CERT 0x2 +#define MATCH_ALL 0x3 + +static int parse_bag (bag, pass, passlen, pkey, cert, ca, keyid, keymatch) +PKCS12_SAFEBAG *bag; +unsigned char *pass; +int passlen; +EVP_PKEY **pkey; +X509 **cert; +STACK **ca; +ASN1_OCTET_STRING **keyid; +char *keymatch; +{ + PKCS8_PRIV_KEY_INFO *p8; + X509 *x509; + ASN1_OCTET_STRING *lkey = NULL; + ASN1_TYPE *attrib; + + + if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) + lkey = attrib->value.octet_string; + + /* Check for any local key id matching (if needed) */ + if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) { + if (*keyid) { + if (ASN1_OCTET_STRING_cmp (*keyid, lkey)) lkey = NULL; + } else { + if (!(*keyid = ASN1_OCTET_STRING_dup (lkey))) { + PKCS12err(PKCS12_F_PARSE_BAGS,ERR_R_MALLOC_FAILURE); + return 0; + } + } + } + + switch (M_PKCS12_bag_type(bag)) + { + case NID_keyBag: + if (!lkey || !pkey) return 1; + if (!(*pkey = EVP_PKCS82PKEY (bag->value.keybag))) return 0; + *keymatch |= MATCH_KEY; + break; + + case NID_pkcs8ShroudedKeyBag: + if (!lkey || !pkey) return 1; + if (!(p8 = M_PKCS12_decrypt_skey (bag, pass, passlen))) + return 0; + *pkey = EVP_PKCS82PKEY (p8); + PKCS8_PRIV_KEY_INFO_free (p8); + if (!(*pkey)) return 0; + *keymatch |= MATCH_KEY; + break; + + case NID_certBag: + if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) + return 1; + if (!(x509 = M_PKCS12_certbag2x509(bag))) return 0; + if (lkey) { + *keymatch |= MATCH_CERT; + if (cert) *cert = x509; + } else if (ca) sk_push (*ca, (char *)x509); + break; + + case NID_safeContentsBag: + return parse_bags(bag->value.safes, pass, passlen, + pkey, cert, ca, keyid, keymatch); + break; + + default: + return 1; + break; + } + return 1; +} + diff --git a/crypto/pkcs12/p12_lib.c b/crypto/pkcs12/p12_lib.c new file mode 100644 index 0000000000..f83aae28fc --- /dev/null +++ b/crypto/pkcs12/p12_lib.c @@ -0,0 +1,123 @@ +/* p12_lib.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 +#include +#include +#include "pkcs12.h" + +/* + *ASN1err(ASN1_F_PKCS12_NEW,ASN1_R_DECODE_ERROR) + *ASN1err(ASN1_F_D2I_PKCS12,ASN1_R_DECODE_ERROR) + */ + +int i2d_PKCS12(a,pp) +PKCS12 *a; +unsigned char **pp; +{ + M_ASN1_I2D_vars(a); + + M_ASN1_I2D_len (a->version, i2d_ASN1_INTEGER); + M_ASN1_I2D_len (a->authsafes, i2d_PKCS7); + M_ASN1_I2D_len (a->mac, i2d_PKCS12_MAC_DATA); + + M_ASN1_I2D_seq_total(); + + M_ASN1_I2D_put (a->version, i2d_ASN1_INTEGER); + M_ASN1_I2D_put (a->authsafes, i2d_PKCS7); + M_ASN1_I2D_put (a->mac, i2d_PKCS12_MAC_DATA); + + M_ASN1_I2D_finish(); +} + +PKCS12 *d2i_PKCS12(a,pp,length) +PKCS12 **a; +unsigned char **pp; +long length; +{ + M_ASN1_D2I_vars(a,PKCS12 *,PKCS12_new); + M_ASN1_D2I_Init(); + M_ASN1_D2I_start_sequence(); + M_ASN1_D2I_get (ret->version, d2i_ASN1_INTEGER); + M_ASN1_D2I_get (ret->authsafes, d2i_PKCS7); + M_ASN1_D2I_get_opt (ret->mac, d2i_PKCS12_MAC_DATA, V_ASN1_SEQUENCE); + M_ASN1_D2I_Finish(a, PKCS12_free, ASN1_F_D2I_PKCS12); +} + +PKCS12 *PKCS12_new() +{ + PKCS12 *ret=NULL; + ASN1_CTX c; + M_ASN1_New_Malloc(ret, PKCS12); + ret->version=NULL; + ret->mac=NULL; + ret->authsafes=NULL; + return (ret); + M_ASN1_New_Error(ASN1_F_PKCS12_NEW); +} + +void PKCS12_free (a) +PKCS12 *a; +{ + if (a == NULL) return; + ASN1_INTEGER_free (a->version); + PKCS12_MAC_DATA_free (a->mac); + PKCS7_free (a->authsafes); + Free ((char *)a); +} diff --git a/crypto/pkcs12/p12_mac.c b/crypto/pkcs12/p12_mac.c new file mode 100644 index 0000000000..907c371b7a --- /dev/null +++ b/crypto/pkcs12/p12_mac.c @@ -0,0 +1,120 @@ +/* p12_mac.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 +#include +#include +#include "pkcs12.h" +/* + *ASN1err(ASN1_F_PKCS12_MAC_DATA_NEW,ASN1_R_DECODE_ERROR) + *ASN1err(ASN1_F_D2I_PKCS12_MAC_DATA,ASN1_R_DECODE_ERROR) + */ + +int i2d_PKCS12_MAC_DATA(a,pp) +PKCS12_MAC_DATA *a; +unsigned char **pp; +{ + M_ASN1_I2D_vars(a); + M_ASN1_I2D_len (a->dinfo, i2d_X509_SIG); + M_ASN1_I2D_len (a->salt, i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_len (a->iter, i2d_ASN1_INTEGER); + + M_ASN1_I2D_seq_total(); + + M_ASN1_I2D_put (a->dinfo, i2d_X509_SIG); + M_ASN1_I2D_put (a->salt, i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_put (a->iter, i2d_ASN1_INTEGER); + M_ASN1_I2D_finish(); +} + +PKCS12_MAC_DATA *PKCS12_MAC_DATA_new() +{ + PKCS12_MAC_DATA *ret=NULL; + ASN1_CTX c; + M_ASN1_New_Malloc(ret, PKCS12_MAC_DATA); + ret->dinfo = X509_SIG_new(); + ret->salt = ASN1_OCTET_STRING_new(); + ret->iter = NULL; + return (ret); + M_ASN1_New_Error(ASN1_F_PKCS12_MAC_DATA_NEW); +} + +PKCS12_MAC_DATA *d2i_PKCS12_MAC_DATA(a,pp,length) +PKCS12_MAC_DATA **a; +unsigned char **pp; +long length; +{ + M_ASN1_D2I_vars(a,PKCS12_MAC_DATA *,PKCS12_MAC_DATA_new); + M_ASN1_D2I_Init(); + M_ASN1_D2I_start_sequence(); + M_ASN1_D2I_get (ret->dinfo, d2i_X509_SIG); + M_ASN1_D2I_get (ret->salt, d2i_ASN1_OCTET_STRING); + M_ASN1_D2I_get_opt (ret->iter, d2i_ASN1_INTEGER, V_ASN1_INTEGER); + M_ASN1_D2I_Finish(a, PKCS12_MAC_DATA_free, ASN1_F_D2I_PKCS12_MAC_DATA); +} + +void PKCS12_MAC_DATA_free (a) +PKCS12_MAC_DATA *a; +{ + if (a == NULL) return; + X509_SIG_free (a->dinfo); + ASN1_OCTET_STRING_free (a->salt); + ASN1_INTEGER_free (a->iter); + Free ((char *)a); +} diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c new file mode 100644 index 0000000000..b788e44058 --- /dev/null +++ b/crypto/pkcs12/p12_mutl.c @@ -0,0 +1,187 @@ +/* p12_mutl.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 +#include +#include +#include +#include +#include "pkcs12.h" + +/* Generate a MAC */ +int PKCS12_gen_mac (p12, pass, passlen, mac, maclen) +PKCS12 *p12; +unsigned char *pass; +int passlen; +unsigned char *mac; +unsigned int *maclen; +{ + EVP_MD *md_type; + HMAC_CTX hmac; + unsigned char key[PKCS12_MAC_KEY_LENGTH], *salt; + int saltlen, iter; + salt = p12->mac->salt->data; + saltlen = p12->mac->salt->length; + if (!p12->mac->iter) iter = 1; + else iter = ASN1_INTEGER_get (p12->mac->iter); + if(!(md_type = + EVP_get_digestbyobj (p12->mac->dinfo->algor->algorithm))) { + PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); + return 0; + } + if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, + PKCS12_MAC_KEY_LENGTH, key, md_type)) { + PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_KEY_GEN_ERROR); + return 0; + } + HMAC_Init (&hmac, key, PKCS12_MAC_KEY_LENGTH, md_type); + HMAC_Update (&hmac, p12->authsafes->d.data->data, + p12->authsafes->d.data->length); + HMAC_Final (&hmac, mac, maclen); + return 1; +} + +/* Verify the mac */ +int PKCS12_verify_mac (p12, pass, passlen) +PKCS12 *p12; +unsigned char *pass; +int passlen; +{ + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + if(p12->mac == NULL) { + PKCS12err(PKCS12_F_VERIFY_MAC,PKCS12_R_MAC_ABSENT); + return 0; + } + if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) { + PKCS12err(PKCS12_F_VERIFY_MAC,PKCS12_R_MAC_GENERATION_ERROR); + return 0; + } + if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) + || memcmp (mac, p12->mac->dinfo->digest->data, maclen)) { + PKCS12err(PKCS12_F_VERIFY_MAC,PKCS12_R_MAC_VERIFY_ERROR); + return 0; + } + return 1; +} + +/* Set a mac */ + +int PKCS12_set_mac (p12, pass, passlen, salt, saltlen, iter, md_type) +PKCS12 *p12; +unsigned char *pass; +int passlen; +unsigned char *salt; +int saltlen; +int iter; +EVP_MD *md_type; +{ + unsigned char mac[EVP_MAX_MD_SIZE]; + int maclen; + if (!md_type) md_type = EVP_sha1(); + if (PKCS12_setup_mac (p12, iter, salt, saltlen, md_type) == + PKCS12_ERROR) { + PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR); + return 0; + } + if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) { + PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR); + return 0; + } + if (!(ASN1_OCTET_STRING_set (p12->mac->dinfo->digest, mac, maclen))) { + PKCS12err(PKCS12_F_PKCS12_PKCS12_SET_MAC,PKCS12_R_MAC_STRING_SET_ERROR); + return 0; + } + return 1; +} + +/* Set up a mac structure */ +int PKCS12_setup_mac (p12, iter, salt, saltlen, md_type) +PKCS12 *p12; +int iter; +unsigned char *salt; +int saltlen; +EVP_MD *md_type; +{ + if (!(p12->mac = PKCS12_MAC_DATA_new ())) return PKCS12_ERROR; + if (iter > 1) { + if(!(p12->mac->iter = ASN1_INTEGER_new())) { + PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_set (p12->mac->iter, iter); + } + if (!saltlen) saltlen = PKCS12_SALT_LEN; + p12->mac->salt->length = saltlen; + if (!(p12->mac->salt->data = Malloc (saltlen))) { + PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!salt) RAND_bytes (p12->mac->salt->data, saltlen); + else memcpy (p12->mac->salt->data, salt, saltlen); + M_ASN1_OBJECT_set(p12->mac->dinfo->algor->algorithm, + EVP_MD_type(md_type)); + if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) { + PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + return 0; + } + p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL; + + return 1; +} diff --git a/crypto/pkcs12/p12_sbag.c b/crypto/pkcs12/p12_sbag.c new file mode 100644 index 0000000000..11049bb35d --- /dev/null +++ b/crypto/pkcs12/p12_sbag.c @@ -0,0 +1,238 @@ +/* p12_sbag.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 +#include +#include +#include "pkcs12.h" + +/* + *ASN1err(ASN1_F_PKCS12_SAFEBAG_NEW,ASN1_R_DECODE_ERROR) + *ASN1err(ASN1_F_D2I_PKCS12_SAFEBAG,ASN1_R_DECODE_ERROR) + */ + +int i2d_PKCS12_SAFEBAG(a,pp) +PKCS12_SAFEBAG *a; +unsigned char **pp; +{ + int bagnid, v = 0; + M_ASN1_I2D_vars(a); + bagnid = OBJ_obj2nid (a->type); + M_ASN1_I2D_len (a->type, i2d_ASN1_OBJECT); + + switch (bagnid) { + + case NID_keyBag: + M_ASN1_I2D_len_EXP_opt (a->value.keybag, + i2d_PKCS8_PRIV_KEY_INFO, 0, v); + break; + + case NID_pkcs8ShroudedKeyBag: + M_ASN1_I2D_len_EXP_opt (a->value.shkeybag, + i2d_X509_SIG, 0, v); + break; + + case NID_safeContentsBag: + M_ASN1_I2D_len_EXP_SEQUENCE_opt (a->value.safes, + i2d_PKCS12_SAFEBAG, 0, V_ASN1_SEQUENCE, v); + break; + + case NID_certBag: + case NID_crlBag: + case NID_secretBag: + M_ASN1_I2D_len_EXP_opt (a->value.bag, + i2d_PKCS12_BAGS, 0, v); + break; + + default: + M_ASN1_I2D_len_EXP_opt (a->value.other, + i2d_ASN1_TYPE, 0, v); + break; + } + + M_ASN1_I2D_len_SET (a->attrib, i2d_X509_ATTRIBUTE); + + M_ASN1_I2D_seq_total (); + + M_ASN1_I2D_put (a->type, i2d_ASN1_OBJECT); + + switch (bagnid) { + + case NID_keyBag: + M_ASN1_I2D_put_EXP_opt (a->value.keybag, + i2d_PKCS8_PRIV_KEY_INFO, 0, v); + break; + + case NID_pkcs8ShroudedKeyBag: + M_ASN1_I2D_put_EXP_opt (a->value.shkeybag, + i2d_X509_SIG, 0, v); + break; + + case NID_safeContentsBag: + M_ASN1_I2D_put_EXP_SEQUENCE_opt (a->value.safes, + i2d_PKCS12_SAFEBAG, 0, V_ASN1_SEQUENCE, v); + break; + + case NID_certBag: + case NID_crlBag: + case NID_secretBag: + M_ASN1_I2D_put_EXP_opt (a->value.bag, + i2d_PKCS12_BAGS, 0, v); + break; + + default: + M_ASN1_I2D_put_EXP_opt (a->value.other, + i2d_ASN1_TYPE, 0, v); + break; + } + + M_ASN1_I2D_put_SET (a->attrib, i2d_X509_ATTRIBUTE); + + M_ASN1_I2D_finish(); +} + +PKCS12_SAFEBAG *PKCS12_SAFEBAG_new() +{ + PKCS12_SAFEBAG *ret=NULL; + ASN1_CTX c; + M_ASN1_New_Malloc(ret, PKCS12_SAFEBAG); + ret->type=NULL; + ret->value.other=NULL; + M_ASN1_New(ret->attrib, sk_new_null); + ret->rest=NULL; + return (ret); + M_ASN1_New_Error(PKCS12_F_PKCS12_SAFEBAG_NEW); +} + +PKCS12_SAFEBAG *d2i_PKCS12_SAFEBAG(a,pp,length) +PKCS12_SAFEBAG **a; +unsigned char **pp; +long length; +{ + int bagnid; + M_ASN1_D2I_vars(a,PKCS12_SAFEBAG *,PKCS12_SAFEBAG_new); + M_ASN1_D2I_Init(); + M_ASN1_D2I_start_sequence(); + M_ASN1_D2I_get (ret->type, d2i_ASN1_OBJECT); + bagnid = OBJ_obj2nid (ret->type); + + switch (bagnid) { + + case NID_keyBag: + M_ASN1_D2I_get_EXP_opt (ret->value.keybag, + d2i_PKCS8_PRIV_KEY_INFO, 0); + break; + + case NID_pkcs8ShroudedKeyBag: + M_ASN1_D2I_get_EXP_opt (ret->value.shkeybag, + d2i_X509_SIG, 0); + break; + + case NID_safeContentsBag: + M_ASN1_D2I_get_EXP_set_opt(ret->value.safes, + d2i_PKCS12_SAFEBAG, PKCS12_SAFEBAG_free, + 0, V_ASN1_SEQUENCE); + break; + + case NID_certBag: + case NID_crlBag: + case NID_secretBag: + M_ASN1_D2I_get_EXP_opt (ret->value.bag, + d2i_PKCS12_BAGS, 0); + break; + + default: + M_ASN1_D2I_get_EXP_opt (ret->value.other, + d2i_ASN1_TYPE, 0); + break; + } + M_ASN1_D2I_get_set_opt(ret->attrib, d2i_X509_ATTRIBUTE, + X509_ATTRIBUTE_free); + M_ASN1_D2I_Finish(a, PKCS12_SAFEBAG_free, ASN1_F_D2I_PKCS12_SAFEBAG); +} + +void PKCS12_SAFEBAG_free (a) +PKCS12_SAFEBAG *a; +{ + if (a == NULL) return; + switch (OBJ_obj2nid(a->type)) { + + case NID_keyBag: + PKCS8_PRIV_KEY_INFO_free (a->value.keybag); + break; + + case NID_pkcs8ShroudedKeyBag: + X509_SIG_free (a->value.shkeybag); + break; + + case NID_certBag: + case NID_crlBag: + case NID_secretBag: + PKCS12_BAGS_free (a->value.bag); + break; + + default: + ASN1_TYPE_free (a->value.other); + break; + } + + ASN1_OBJECT_free (a->type); + sk_pop_free (a->attrib, X509_ATTRIBUTE_free); + Free ((char *)a); +} diff --git a/crypto/pkcs12/p12_utl.c b/crypto/pkcs12/p12_utl.c new file mode 100644 index 0000000000..ae689c9b99 --- /dev/null +++ b/crypto/pkcs12/p12_utl.c @@ -0,0 +1,140 @@ +/* p12_utl.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 +#include +#include +#include +#include "pkcs12.h" + +/* Cheap and nasty Unicode stuff */ + +unsigned char *asc2uni (asc, uni, unilen) +unsigned char *asc, **uni; +int *unilen; +{ + int ulen, i; + unsigned char *unitmp; + ulen = strlen(asc)*2 + 2; + if (!(unitmp = Malloc (ulen))) return NULL; + for (i = 0; i < ulen; i+=2) { + unitmp[i] = 0; + unitmp[i + 1] = asc[i>>1]; + } + if (unilen) *unilen = ulen; + if (uni) *uni = unitmp; + return unitmp; +} + +char *uni2asc (uni, unilen) +unsigned char *uni; +int unilen; +{ + int asclen, i; + char *asctmp; + asclen = unilen / 2; + /* If no terminating zero allow for one */ + if (uni[unilen - 1]) asclen++; + uni++; + if (!(asctmp = Malloc (asclen))) return NULL; + for (i = 0; i < unilen; i+=2) asctmp[i>>1] = uni[i]; + asctmp[asclen - 1] = 0; + return asctmp; +} + +/* Tag an object type onto an error code */ + +void PKCS12_add_obj_error (obj) +ASN1_OBJECT *obj; +{ + char obj_tmp[80]; + if (!obj) strcpy (obj_tmp, "NULL"); + else i2t_ASN1_OBJECT(obj_tmp, 80, obj); + ERR_add_error_data(2, "TYPE=", obj_tmp); +} + +int i2d_PKCS12_bio(bp, p12) +BIO *bp; +PKCS12 *p12; +{ + return ASN1_i2d_bio((int(*)())i2d_PKCS12, bp, (unsigned char *)p12); +} + +int i2d_PKCS12_fp(fp, p12) +FILE *fp; +PKCS12 *p12; +{ + return ASN1_i2d_fp((int(*)())i2d_PKCS12, fp, (unsigned char *)p12); +} + +PKCS12 *d2i_PKCS12_bio(bp, p12) +BIO *bp; +PKCS12 **p12; +{ + return (PKCS12 *)ASN1_d2i_bio((char *(*)())PKCS12_new, + (char *(*)())d2i_PKCS12, bp, (unsigned char **)p12); +} +PKCS12 *d2i_PKCS12_fp(fp, p12) +FILE *fp; +PKCS12 **p12; +{ + return (PKCS12 *)ASN1_d2i_fp((char *(*)())PKCS12_new, + (char *(*)())d2i_PKCS12, fp, (unsigned char **)(p12)); +} + diff --git a/crypto/pkcs12/pk12err.c b/crypto/pkcs12/pk12err.c new file mode 100644 index 0000000000..185d4e184a --- /dev/null +++ b/crypto/pkcs12/pk12err.c @@ -0,0 +1,136 @@ +/* lib/pkcs12/pkcs12_err.c */ +/* Copyright (C) 1995-1997 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 "err.h" +#include "pkcs12.h" + +/* BEGIN ERROR CODES */ +#ifndef NO_ERR +static ERR_STRING_DATA PKCS12_str_functs[]= + { +{ERR_PACK(0,PKCS12_F_ADD_FRIENDLYNAME,0), "ADD_FRIENDLYNAME"}, +{ERR_PACK(0,PKCS12_F_ADD_FRIENDLYNAME_ASC,0), "ADD_FRIENDLYNAME_ASC"}, +{ERR_PACK(0,PKCS12_F_ADD_FRIENDLYNAME_UNI,0), "ADD_FRIENDLYNAME_UNI"}, +{ERR_PACK(0,PKCS12_F_PARSE_BAGS,0), "PARSE_BAGS"}, +{ERR_PACK(0,PKCS12_F_PKCS12_ADD_LOCALKEYID,0), "PKCS12_add_localkeyid"}, +{ERR_PACK(0,PKCS12_F_PKCS12_CREATE,0), "PKCS12_create"}, +{ERR_PACK(0,PKCS12_F_PKCS12_DECRYPT_D2I,0), "PKCS12_decrypt_d2i"}, +{ERR_PACK(0,PKCS12_F_PKCS12_GEN_MAC,0), "PKCS12_gen_mac"}, +{ERR_PACK(0,PKCS12_F_PKCS12_I2D_ENCRYPT,0), "PKCS12_i2d_encrypt"}, +{ERR_PACK(0,PKCS12_F_PKCS12_INIT,0), "PKCS12_init"}, +{ERR_PACK(0,PKCS12_F_PKCS12_KEY_GEN_ASC,0), "PKCS12_key_gen_asc"}, +{ERR_PACK(0,PKCS12_F_PKCS12_KEY_GEN_UNI,0), "PKCS12_key_gen_uni"}, +{ERR_PACK(0,PKCS12_F_PKCS12_MAKE_SAFEBAG,0), "PKCS12_MAKE_SAFEBAG"}, +{ERR_PACK(0,PKCS12_F_PKCS12_MAKE_SHKEYBAG,0), "PKCS12_MAKE_SHKEYBAG"}, +{ERR_PACK(0,PKCS12_F_PKCS12_PACK_P7DATA,0), "PKCS12_pack_p7data"}, +{ERR_PACK(0,PKCS12_F_PKCS12_PACK_P7ENCDATA,0), "PKCS12_pack_p7encdata"}, +{ERR_PACK(0,PKCS12_F_PKCS12_PACK_P7_DATA,0), "PKCS12_PACK_P7_DATA"}, +{ERR_PACK(0,PKCS12_F_PKCS12_PACK_SAFEBAG,0), "PKCS12_pack_safebag"}, +{ERR_PACK(0,PKCS12_F_PKCS12_PARSE,0), "PKCS12_parse"}, +{ERR_PACK(0,PKCS12_F_PKCS12_PBE_CRYPT,0), "PKCS12_pbe_crypt"}, +{ERR_PACK(0,PKCS12_F_PKCS12_PBE_KEYIVGEN,0), "PKCS12_PBE_KEYIVGEN"}, +{ERR_PACK(0,PKCS12_F_PKCS12_PKCS12_SET_MAC,0), "PKCS12_PKCS12_SET_MAC"}, +{ERR_PACK(0,PKCS12_F_PKCS12_SETUP_MAC,0), "PKCS12_setup_mac"}, +{ERR_PACK(0,PKCS12_F_PKCS12_SET_MAC,0), "PKCS12_set_mac"}, +{ERR_PACK(0,PKCS12_F_PKCS8_ADD_KEYUSAGE,0), "PKCS8_add_keyusage"}, +{ERR_PACK(0,PKCS12_F_PKCS8_ENCRYPT,0), "PKCS8_encrypt"}, +{ERR_PACK(0,PKCS12_F_VERIFY_MAC,0), "VERIFY_MAC"}, +{0,NULL}, + }; + +static ERR_STRING_DATA PKCS12_str_reasons[]= + { +{PKCS12_R_CANT_PACK_STRUCTURE ,"cant pack structure"}, +{PKCS12_R_DECODE_ERROR ,"decode error"}, +{PKCS12_R_ENCODE_ERROR ,"encode error"}, +{PKCS12_R_ENCRYPT_ERROR ,"encrypt error"}, +{PKCS12_R_INVALID_NULL_ARGUMENT ,"invalid null argument"}, +{PKCS12_R_INVALID_NULL_PKCS12_POINTER ,"invalid null pkcs12 pointer"}, +{PKCS12_R_IV_GEN_ERROR ,"iv gen error"}, +{PKCS12_R_KEY_GEN_ERROR ,"key gen error"}, +{PKCS12_R_MAC_ABSENT ,"mac absent"}, +{PKCS12_R_MAC_GENERATION_ERROR ,"mac generation error"}, +{PKCS12_R_MAC_SETUP_ERROR ,"mac setup error"}, +{PKCS12_R_MAC_STRING_SET_ERROR ,"mac string set error"}, +{PKCS12_R_MAC_VERIFY_ERROR ,"mac verify error"}, +{PKCS12_R_MAC_VERIFY_FAILURE ,"mac verify failure"}, +{PKCS12_R_PARSE_ERROR ,"parse error"}, +{PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR ,"pkcs12 algor cipherinit error"}, +{PKCS12_R_PKCS12_CIPHERFINAL_ERROR ,"pkcs12 cipherfinal error"}, +{PKCS12_R_PKCS12_PBE_CRYPT_ERROR ,"pkcs12 pbe crypt error"}, +{PKCS12_R_UNKNOWN_DIGEST_ALGORITHM ,"unknown digest algorithm"}, +{PKCS12_R_UNSUPPORTED_PKCS12_MODE ,"unsupported pkcs12 mode"}, +{0,NULL}, + }; + +#endif + +void ERR_load_PKCS12_strings() + { + static int init=1; + + if (init) + { + init=0; +#ifndef NO_ERR + ERR_load_strings(ERR_LIB_PKCS12,PKCS12_str_functs); + ERR_load_strings(ERR_LIB_PKCS12,PKCS12_str_reasons); +#endif + + } + } diff --git a/crypto/pkcs12/pkcs12.err b/crypto/pkcs12/pkcs12.err new file mode 100644 index 0000000000..beaa6a6a5f --- /dev/null +++ b/crypto/pkcs12/pkcs12.err @@ -0,0 +1,52 @@ +/* Error codes for the PKCS12 functions. */ + +/* Function codes. */ +#define PKCS12_F_ADD_FRIENDLYNAME 100 +#define PKCS12_F_ADD_FRIENDLYNAME_ASC 101 +#define PKCS12_F_ADD_FRIENDLYNAME_UNI 102 +#define PKCS12_F_PARSE_BAGS 103 +#define PKCS12_F_PKCS12_ADD_LOCALKEYID 104 +#define PKCS12_F_PKCS12_CREATE 105 +#define PKCS12_F_PKCS12_DECRYPT_D2I 106 +#define PKCS12_F_PKCS12_GEN_MAC 107 +#define PKCS12_F_PKCS12_I2D_ENCRYPT 108 +#define PKCS12_F_PKCS12_INIT 109 +#define PKCS12_F_PKCS12_KEY_GEN_ASC 110 +#define PKCS12_F_PKCS12_KEY_GEN_UNI 111 +#define PKCS12_F_PKCS12_MAKE_SAFEBAG 112 +#define PKCS12_F_PKCS12_MAKE_SHKEYBAG 113 +#define PKCS12_F_PKCS12_PACK_P7DATA 114 +#define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 +#define PKCS12_F_PKCS12_PACK_P7_DATA 116 +#define PKCS12_F_PKCS12_PACK_SAFEBAG 117 +#define PKCS12_F_PKCS12_PARSE 118 +#define PKCS12_F_PKCS12_PBE_CRYPT 119 +#define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 +#define PKCS12_F_PKCS12_PKCS12_SET_MAC 121 +#define PKCS12_F_PKCS12_SETUP_MAC 122 +#define PKCS12_F_PKCS12_SET_MAC 123 +#define PKCS12_F_PKCS8_ADD_KEYUSAGE 124 +#define PKCS12_F_PKCS8_ENCRYPT 125 +#define PKCS12_F_VERIFY_MAC 126 + +/* Reason codes. */ +#define PKCS12_R_CANT_PACK_STRUCTURE 100 +#define PKCS12_R_DECODE_ERROR 101 +#define PKCS12_R_ENCODE_ERROR 102 +#define PKCS12_R_ENCRYPT_ERROR 103 +#define PKCS12_R_INVALID_NULL_ARGUMENT 104 +#define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 +#define PKCS12_R_IV_GEN_ERROR 106 +#define PKCS12_R_KEY_GEN_ERROR 107 +#define PKCS12_R_MAC_ABSENT 108 +#define PKCS12_R_MAC_GENERATION_ERROR 109 +#define PKCS12_R_MAC_SETUP_ERROR 110 +#define PKCS12_R_MAC_STRING_SET_ERROR 111 +#define PKCS12_R_MAC_VERIFY_ERROR 112 +#define PKCS12_R_MAC_VERIFY_FAILURE 113 +#define PKCS12_R_PARSE_ERROR 114 +#define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 +#define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 +#define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 +#define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 +#define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 diff --git a/crypto/pkcs12/pkcs12.h b/crypto/pkcs12/pkcs12.h new file mode 100644 index 0000000000..c626ad15e9 --- /dev/null +++ b/crypto/pkcs12/pkcs12.h @@ -0,0 +1,407 @@ +/* pkcs12.h */ +/* 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). + * + */ + +#ifndef HEADER_PKCS12_H +#define HEADER_PKCS12_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "bio.h" +#include "x509.h" + +#define PKCS12_LIB_NAME "PKCS12 library" + +#define PKCS12_KEY_ID 1 +#define PKCS12_IV_ID 2 +#define PKCS12_MAC_ID 3 + +#define PKCS12_MAC_KEY_LENGTH 20 + +#define PKCS12_SALT_LEN 8 + +/* Uncomment out next line for unicode password and names, otherwise ASCII */ + +/*#define PBE_UNICODE*/ + +#ifdef PBE_UNICODE +#define PKCS12_key_gen PKCS12_key_gen_uni +#define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni +#else +#define PKCS12_key_gen PKCS12_key_gen_asc +#define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc +#endif + +/* MS key usage constants */ + +#define KEY_EX 0x10 +#define KEY_SIG 0x80 + +/* Various ASN1 macros */ + +#ifndef M_ASN1_D2I_get_set_opt +#define M_ASN1_D2I_get_set_opt(r,func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ + { M_ASN1_D2I_get_set(r,func); } +#endif + +#ifndef M_ASN1_I2D_len_SET_opt +#define M_ASN1_I2D_len_SET_opt(a,f) \ + if (a != NULL) M_ASN1_I2D_len_SET(a,f); +#endif + +#ifndef M_ASN1_I2D_put_SET_opt +#define M_ASN1_I2D_put_SET_opt(a,f) \ + if (a != NULL) M_ASN1_I2D_put_SET(a,f); + +#endif + +typedef struct { +X509_SIG *dinfo; +ASN1_OCTET_STRING *salt; +ASN1_INTEGER *iter; /* defaults to 1 */ +} PKCS12_MAC_DATA; + +typedef struct { +ASN1_INTEGER *version; +PKCS12_MAC_DATA *mac; +PKCS7 *authsafes; +} PKCS12; + +#define PKCS8_OK 0 +#define PKCS8_NO_OCTET 1 + +typedef struct { +ASN1_OBJECT *type; +union { + struct pkcs12_bag_st *bag; /* secret, crl and certbag */ + struct pkcs8_priv_key_info_st *keybag; /* keybag */ + X509_SIG *shkeybag; /* shrouded key bag */ + STACK /* PKCS12_SAFEBAG */ *safes; + ASN1_TYPE *other; +}value; +STACK *attrib; +ASN1_TYPE *rest; +} PKCS12_SAFEBAG; + +typedef struct pkcs12_bag_st { +ASN1_OBJECT *type; +union { + ASN1_OCTET_STRING *x509cert; + ASN1_OCTET_STRING *x509crl; + ASN1_OCTET_STRING *octet; + ASN1_IA5STRING *sdsicert; + ASN1_TYPE *other; /* Secret or other bag */ +}value; +} PKCS12_BAGS; + +#define PKCS12_ERROR 0 +#define PKCS12_OK 1 + +#define M_PKCS12_bag_type(bag) OBJ_obj2nid(bag->type) +#define M_PKCS12_cert_bag_type(bag) OBJ_obj2nid(bag->value.bag->type) +#define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type + +#define M_PKCS12_x5092certbag(x509) \ +PKCS12_pack_safebag ((char *)(x509), i2d_X509, NID_x509Certificate, NID_certBag) + +#define M_PKCS12_x509crl2certbag(crl) \ +PKCS12_pack_safebag ((char *)(crl), i2d_X509CRL, NID_x509Crl, NID_crlBag) + +#define M_PKCS12_certbag2x509(bg) \ +(X509 *) ASN1_unpack_string ((bg)->value.bag->value.octet, \ +(char *(*)())d2i_X509) + +#define M_PKCS12_certbag2x509crl(bg) \ +(X509CRL *) ASN1_unpack_string ((bg)->value.bag->value.octet, \ +(char *(*)())d2i_X509CRL) + +/*#define M_PKCS12_pkcs82rsa(p8) \ +(RSA *) ASN1_unpack_string ((p8)->pkey, (char *(*)())d2i_RSAPrivateKey)*/ + +#define M_PKCS12_unpack_p7data(p7) \ +ASN1_seq_unpack ((p7)->d.data->data, p7->d.data->length, \ + (char *(*)())d2i_PKCS12_SAFEBAG, PKCS12_SAFEBAG_free) + +#define M_PKCS12_pack_authsafes(p12, safes) \ +ASN1_seq_pack((safes), (int (*)())i2d_PKCS7,\ + &(p12)->authsafes->d.data->data, &(p12)->authsafes->d.data->length) + +#define M_PKCS12_unpack_authsafes(p12) \ +ASN1_seq_unpack((p12)->authsafes->d.data->data, \ + (p12)->authsafes->d.data->length, (char *(*)())d2i_PKCS7, \ + PKCS7_free) + +#define M_PKCS12_unpack_p7encdata(p7, pass, passlen) \ +(STACK *) PKCS12_decrypt_d2i ((p7)->d.encrypted->enc_data->algorithm,\ + (char *(*)())d2i_PKCS12_SAFEBAG, PKCS12_SAFEBAG_free, \ + (pass), (passlen), \ + (p7)->d.encrypted->enc_data->enc_data, 3) + +#define M_PKCS12_decrypt_skey(bag, pass, passlen) \ +(PKCS8_PRIV_KEY_INFO *) PKCS12_decrypt_d2i ((bag)->value.shkeybag->algor, \ +(char *(*)())d2i_PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free, \ + (pass), (passlen), \ + (bag)->value.shkeybag->digest, 2) + +#define M_PKCS8_decrypt(p8, pass, passlen) \ +(PKCS8_PRIV_KEY_INFO *) PKCS12_decrypt_d2i ((p8)->algor, \ +(char *(*)())d2i_PKCS8_PRIV_KEY_INFO, (pass), (passlen), (p8)->digest, 2) + +#define PKCS12_get_attr(bag, attr_nid) \ + PKCS12_get_attr_gen(bag->attrib, attr_nid) + +#define PKCS8_get_attr(p8, attr_nid) \ + PKCS12_get_attr_gen(p8->attributes, attr_nid) + +#define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0) + +#define M_ASN1_OBJECT_set(obj, nid) \ +{\ +ASN1_OBJECT_free(obj); \ +obj = OBJ_nid2obj((nid));\ +} + +#ifndef NOPROTO +int i2d_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO *a, unsigned char **pp); +PKCS8_PRIV_KEY_INFO *PKCS8_PRIV_KEY_INFO_new(void); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO **a, unsigned char **pp, long length); +void PKCS8_PRIV_KEY_INFO_free(PKCS8_PRIV_KEY_INFO *a); +PKCS12_SAFEBAG *PKCS12_pack_safebag(char *obj, int (*i2d)(), int nid1, int nid2); +PKCS8_PRIV_KEY_INFO *PKEY2PKCS8(EVP_PKEY *pkey); +EVP_PKEY *PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8); +X509_SIG *PKCS8_encrypt(int pbe_nid, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); +PKCS7 *PKCS12_pack_p7data(STACK *sk); +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, STACK *bags); +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen); +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen); +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen); +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); +ASN1_TYPE *PKCS12_get_attr_gen(STACK *attrs, int attr_nid); +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); +unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, unsigned char *pass, int passlen, unsigned char *in, int inlen, unsigned char **data, int *datalen, int en_de); +char *PKCS12_decrypt_d2i(X509_ALGOR *algor, char *(*d2i)(), void (*free_func)(), unsigned char *pass, int passlen, ASN1_STRING *oct, int seq); +ASN1_STRING *PKCS12_i2d_encrypt(X509_ALGOR *algor, int (*i2d)(), unsigned char *pass, int passlen, char *obj, int seq); +PKCS12 *PKCS12_init(int mode); +X509_ALGOR *PKCS12_pbe_set(int alg, int iter, unsigned char *salt, int saltlen); +int PKCS12_key_gen_asc(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, EVP_MD *md_type); +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, EVP_MD *md_type); +int PKCS12_PBE_keyivgen(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, EVP_CIPHER *cipher, EVP_MD *md_type, unsigned char *key, unsigned char *iv); +int PKCS12_gen_mac(PKCS12 *p12, unsigned char *pass, int passlen, unsigned char *mac, unsigned int *maclen); +int PKCS12_gen_mac(PKCS12 *p12, unsigned char *pass, int passlen, unsigned char *mac, unsigned int *maclen); +int PKCS12_verify_mac(PKCS12 *p12, unsigned char *pass, int passlen); +int PKCS12_set_mac(PKCS12 *p12, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, EVP_MD *md_type); +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, EVP_MD *md_type); +unsigned char *asc2uni(unsigned char *asc, unsigned char **uni, int *unilen); +char *uni2asc(unsigned char *uni, int unilen); +void PKCS12_add_obj_error(ASN1_OBJECT *obj); +int i2d_PKCS12_BAGS(PKCS12_BAGS *a, unsigned char **pp); +PKCS12_BAGS *PKCS12_BAGS_new(void); +PKCS12_BAGS *d2i_PKCS12_BAGS(PKCS12_BAGS **a, unsigned char **pp, long length); +void PKCS12_BAGS_free(PKCS12_BAGS *a); +int i2d_PKCS12(PKCS12 *a, unsigned char **pp); +PKCS12 *d2i_PKCS12(PKCS12 **a, unsigned char **pp, long length); +PKCS12 *PKCS12_new(void); +void PKCS12_free(PKCS12 *a); +int i2d_PKCS12_MAC_DATA(PKCS12_MAC_DATA *a, unsigned char **pp); +PKCS12_MAC_DATA *PKCS12_MAC_DATA_new(void); +PKCS12_MAC_DATA *d2i_PKCS12_MAC_DATA(PKCS12_MAC_DATA **a, unsigned char **pp, long length); +void PKCS12_MAC_DATA_free(PKCS12_MAC_DATA *a); +int i2d_PKCS12_SAFEBAG(PKCS12_SAFEBAG *a, unsigned char **pp); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_new(void); +PKCS12_SAFEBAG *d2i_PKCS12_SAFEBAG(PKCS12_SAFEBAG **a, unsigned char **pp, long length); +void PKCS12_SAFEBAG_free(PKCS12_SAFEBAG *a); +void ERR_load_PKCS12_strings(void); +void ERR_PKCS12_error(int function, int reason, char *file, int line); +void PKCS12_add_obj(void); +void PKCS12_lib_init(void); +void PKCS12_PBE_add(void); +int PKCS12_parse(PKCS12 *p12, char *pass, EVP_PKEY **pkey, X509 **cert, STACK **ca); +PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, STACK *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype); +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); + +#else + +int i2d_PKCS8_PRIV_KEY_INFO(); +PKCS8_PRIV_KEY_INFO *PKCS8_PRIV_KEY_INFO_new(); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO(); +void PKCS8_PRIV_KEY_INFO_free(); +PKCS12_SAFEBAG *PKCS12_pack_safebag(); +PKCS8_PRIV_KEY_INFO *PKEY2PKCS8(); +EVP_PKEY *PKCS82PKEY(); +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(); +X509_SIG *PKCS8_encrypt(); +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(); +PKCS7 *PKCS12_pack_p7data(); +PKCS7 *PKCS12_pack_p7encdata(); +int PKCS12_add_localkeyid(); +int PKCS12_add_friendlyname_asc(); +int PKCS12_add_friendlyname_uni(); +char *PKCS12_get_friendlyname(); +unsigned char *PKCS12_pbe_crypt(); +char *PKCS12_decrypt_d2i(); +ASN1_STRING *PKCS12_i2d_encrypt(); +PKCS12 *PKCS12_init(); +X509_ALGOR *PKCS12_pbe_set(); +int PKCS12_key_gen_asc(); +int PKCS12_key_gen_uni(); +int PKCS12_gen_mac(); +int PKCS12_verify_mac(); +int PKCS12_set_mac(); +int PKCS12_setup_mac(); +unsigned char *asc2uni(); +char *uni2asc(); +void PKCS12_add_obj_error(); +int i2d_PKCS12_BAGS(); +PKCS12_BAGS *PKCS12_BAGS_new(); +PKCS12_BAGS *d2i_PKCS12_BAGS(); +void PKCS12_BAGS_free(); +int i2d_PKCS12(); +PKCS12 *d2i_PKCS12(); +PKCS12 *PKCS12_new(); +void PKCS12_free(); +int i2d_PKCS12_MAC_DATA(); +PKCS12_MAC_DATA *PKCS12_MAC_DATA_new(); +PKCS12_MAC_DATA *d2i_PKCS12_MAC_DATA(); +void PKCS12_MAC_DATA_free(); +int i2d_PKCS12_SAFEBAG(); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_new(); +PKCS12_SAFEBAG *d2i_PKCS12_SAFEBAG(); +void PKCS12_SAFEBAG_free(); +void ERR_load_PKCS12_strings(); +void ERR_PKCS12_error (); +void PKCS12_add_obj(); +void PKCS12_lib_init(); +void PKCS12_PBE_add(); +int PKCS8_add_keyusage(); +ASN1_TYPE *PKCS12_get_attr_gen(); +int PKCS12_parse(); +PKCS12 *PKCS12_create(); +int i2d_PKCS12_bio(); +int i2d_PKCS12_fp(); +PKCS12 *d2i_PKCS12_bio(); +PKCS12 *d2i_PKCS12_fp(); + +#endif + +/* BEGIN ERROR CODES */ +/* Error codes for the PKCS12 functions. */ + +/* Function codes. */ +#define PKCS12_F_ADD_FRIENDLYNAME 100 +#define PKCS12_F_ADD_FRIENDLYNAME_ASC 101 +#define PKCS12_F_ADD_FRIENDLYNAME_UNI 102 +#define PKCS12_F_PARSE_BAGS 103 +#define PKCS12_F_PKCS12_ADD_LOCALKEYID 104 +#define PKCS12_F_PKCS12_CREATE 105 +#define PKCS12_F_PKCS12_DECRYPT_D2I 106 +#define PKCS12_F_PKCS12_GEN_MAC 107 +#define PKCS12_F_PKCS12_I2D_ENCRYPT 108 +#define PKCS12_F_PKCS12_INIT 109 +#define PKCS12_F_PKCS12_KEY_GEN_ASC 110 +#define PKCS12_F_PKCS12_KEY_GEN_UNI 111 +#define PKCS12_F_PKCS12_MAKE_SAFEBAG 112 +#define PKCS12_F_PKCS12_MAKE_SHKEYBAG 113 +#define PKCS12_F_PKCS12_PACK_P7DATA 114 +#define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 +#define PKCS12_F_PKCS12_PACK_P7_DATA 116 +#define PKCS12_F_PKCS12_PACK_SAFEBAG 117 +#define PKCS12_F_PKCS12_PARSE 118 +#define PKCS12_F_PKCS12_PBE_CRYPT 119 +#define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 +#define PKCS12_F_PKCS12_PKCS12_SET_MAC 121 +#define PKCS12_F_PKCS12_SETUP_MAC 122 +#define PKCS12_F_PKCS12_SET_MAC 123 +#define PKCS12_F_PKCS8_ADD_KEYUSAGE 124 +#define PKCS12_F_PKCS8_ENCRYPT 125 +#define PKCS12_F_VERIFY_MAC 126 + +/* Reason codes. */ +#define PKCS12_R_CANT_PACK_STRUCTURE 100 +#define PKCS12_R_DECODE_ERROR 101 +#define PKCS12_R_ENCODE_ERROR 102 +#define PKCS12_R_ENCRYPT_ERROR 103 +#define PKCS12_R_INVALID_NULL_ARGUMENT 104 +#define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 +#define PKCS12_R_IV_GEN_ERROR 106 +#define PKCS12_R_KEY_GEN_ERROR 107 +#define PKCS12_R_MAC_ABSENT 108 +#define PKCS12_R_MAC_GENERATION_ERROR 109 +#define PKCS12_R_MAC_SETUP_ERROR 110 +#define PKCS12_R_MAC_STRING_SET_ERROR 111 +#define PKCS12_R_MAC_VERIFY_ERROR 112 +#define PKCS12_R_MAC_VERIFY_FAILURE 113 +#define PKCS12_R_PARSE_ERROR 114 +#define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 +#define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 +#define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 +#define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 +#define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index c4677be1ee..8cdfe0fc9d 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h @@ -863,6 +863,7 @@ int i2d_PBEPARAM(PBEPARAM *a, unsigned char **pp); PBEPARAM *PBEPARAM_new(void); PBEPARAM *d2i_PBEPARAM(PBEPARAM **a, unsigned char **pp, long length); void PBEPARAM_free(PBEPARAM *a); +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen); /* PKCS#8 utilities */ @@ -1198,6 +1199,7 @@ PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(); int EVP_PBE_ALGOR_CipherInit(); int EVP_PBE_alg_add(); +X509_ALGOR *PKCS5_pbe_set(); #endif