diff options
Diffstat (limited to 'crypto/asn1')
-rw-r--r-- | crypto/asn1/asn1.h | 6 | ||||
-rw-r--r-- | crypto/asn1/asn1_err.c | 2 | ||||
-rw-r--r-- | crypto/asn1/asn_pack.c | 4 | ||||
-rw-r--r-- | crypto/asn1/p5_pbe.c | 20 | ||||
-rw-r--r-- | crypto/asn1/p5_pbev2.c | 119 |
5 files changed, 125 insertions, 26 deletions
diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index 3de083984e..f55663e0f0 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h @@ -681,8 +681,8 @@ STACK *ASN1_seq_unpack(unsigned char *buf, int len, char *(*d2i)(), void (*free_func)() ); unsigned char *ASN1_seq_pack(STACK *safes, int (*i2d)(), unsigned char **buf, int *len ); -char *ASN1_unpack_string(ASN1_STRING *oct, char *(*d2i)()); -ASN1_STRING *ASN1_pack_string(char *obj, int (*i2d)(), ASN1_OCTET_STRING **oct); +void *ASN1_unpack_string(ASN1_STRING *oct, char *(*d2i)()); +ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_OCTET_STRING **oct); /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes @@ -836,6 +836,7 @@ ASN1_STRING *ASN1_pack_string(char *obj, int (*i2d)(), ASN1_OCTET_STRING **oct); #define ASN1_F_PKCS12_MAC_DATA_NEW 259 #define ASN1_F_PKCS12_NEW 260 #define ASN1_F_PKCS12_SAFEBAG_NEW 261 +#define ASN1_F_PKCS5_PBE2_SET 281 #define ASN1_F_PKCS7_DIGEST_NEW 192 #define ASN1_F_PKCS7_ENCRYPT_NEW 193 #define ASN1_F_PKCS7_ENC_CONTENT_NEW 194 @@ -890,6 +891,7 @@ ASN1_STRING *ASN1_pack_string(char *obj, int (*i2d)(), ASN1_OCTET_STRING **oct); #define ASN1_R_DECODING_ERROR 111 #define ASN1_R_ENCODE_ERROR 156 #define ASN1_R_ERROR_PARSING_SET_ELEMENT 112 +#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 157 #define ASN1_R_EXPECTING_AN_ENUMERATED 154 #define ASN1_R_EXPECTING_AN_INTEGER 113 #define ASN1_R_EXPECTING_AN_OBJECT 114 diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c index cc0431b994..900291fb6a 100644 --- a/crypto/asn1/asn1_err.c +++ b/crypto/asn1/asn1_err.c @@ -209,6 +209,7 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_PACK(0,ASN1_F_PKCS12_MAC_DATA_NEW,0), "PKCS12_MAC_DATA_new"}, {ERR_PACK(0,ASN1_F_PKCS12_NEW,0), "PKCS12_new"}, {ERR_PACK(0,ASN1_F_PKCS12_SAFEBAG_NEW,0), "PKCS12_SAFEBAG_new"}, +{ERR_PACK(0,ASN1_F_PKCS5_PBE2_SET,0), "PKCS5_PBE2_SET"}, {ERR_PACK(0,ASN1_F_PKCS7_DIGEST_NEW,0), "PKCS7_DIGEST_new"}, {ERR_PACK(0,ASN1_F_PKCS7_ENCRYPT_NEW,0), "PKCS7_ENCRYPT_new"}, {ERR_PACK(0,ASN1_F_PKCS7_ENC_CONTENT_NEW,0), "PKCS7_ENC_CONTENT_new"}, @@ -266,6 +267,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]= {ASN1_R_DECODING_ERROR ,"decoding error"}, {ASN1_R_ENCODE_ERROR ,"encode error"}, {ASN1_R_ERROR_PARSING_SET_ELEMENT ,"error parsing set element"}, +{ASN1_R_ERROR_SETTING_CIPHER_PARAMS ,"error setting cipher params"}, {ASN1_R_EXPECTING_AN_ENUMERATED ,"expecting an enumerated"}, {ASN1_R_EXPECTING_AN_INTEGER ,"expecting an integer"}, {ASN1_R_EXPECTING_AN_OBJECT ,"expecting an object"}, diff --git a/crypto/asn1/asn_pack.c b/crypto/asn1/asn_pack.c index 4e846285a8..662a2626a1 100644 --- a/crypto/asn1/asn_pack.c +++ b/crypto/asn1/asn_pack.c @@ -104,7 +104,7 @@ unsigned char *ASN1_seq_pack(STACK *safes, int (*i2d)(), unsigned char **buf, /* Extract an ASN1 object from an ASN1_STRING */ -char *ASN1_unpack_string (ASN1_STRING *oct, char *(*d2i)()) +void *ASN1_unpack_string (ASN1_STRING *oct, char *(*d2i)()) { unsigned char *p; char *ret; @@ -117,7 +117,7 @@ char *ASN1_unpack_string (ASN1_STRING *oct, char *(*d2i)()) /* Pack an ASN1 object into an ASN1_STRING */ -ASN1_STRING *ASN1_pack_string (char *obj, int (*i2d)(), ASN1_STRING **oct) +ASN1_STRING *ASN1_pack_string (void *obj, int (*i2d)(), ASN1_STRING **oct) { unsigned char *p; ASN1_STRING *octmp; diff --git a/crypto/asn1/p5_pbe.c b/crypto/asn1/p5_pbe.c index c7a3ecf9fb..5145c6349e 100644 --- a/crypto/asn1/p5_pbe.c +++ b/crypto/asn1/p5_pbe.c @@ -63,8 +63,6 @@ /* PKCS#5 password based encryption structure */ -#define PKCS5_SALT_LEN 8 - int i2d_PBEPARAM(PBEPARAM *a, unsigned char **pp) { M_ASN1_I2D_vars(a); @@ -112,8 +110,6 @@ void PBEPARAM_free (PBEPARAM *a) X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen) { - unsigned char *pdata, *ptmp; - int plen; PBEPARAM *pbe; ASN1_OBJECT *al; X509_ALGOR *algor; @@ -132,17 +128,6 @@ X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, 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); @@ -150,12 +135,11 @@ X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, } astype->type = V_ASN1_SEQUENCE; - if (!(astype->value.sequence=ASN1_STRING_new())) { + if(!ASN1_pack_string(pbe, i2d_PBEPARAM, &astype->value.sequence)) { ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); return NULL; } - ASN1_STRING_set (astype->value.sequence, pdata, plen); - Free (pdata); + PBEPARAM_free (pbe); al = OBJ_nid2obj(alg); /* never need to free al */ if (!(algor = X509_ALGOR_new())) { diff --git a/crypto/asn1/p5_pbev2.c b/crypto/asn1/p5_pbev2.c index ee1ed87d9a..6400c10364 100644 --- a/crypto/asn1/p5_pbev2.c +++ b/crypto/asn1/p5_pbev2.c @@ -109,14 +109,14 @@ void PBE2PARAM_free (PBE2PARAM *a) int i2d_PBKDF2PARAM(PBKDF2PARAM *a, unsigned char **pp) { M_ASN1_I2D_vars(a); - M_ASN1_I2D_len (a->salt, i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_len (a->salt, i2d_ASN1_TYPE); M_ASN1_I2D_len (a->iter, i2d_ASN1_INTEGER); M_ASN1_I2D_len (a->keylength, i2d_ASN1_INTEGER); M_ASN1_I2D_len (a->prf, i2d_X509_ALGOR); M_ASN1_I2D_seq_total (); - M_ASN1_I2D_put (a->salt, i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_put (a->salt, i2d_ASN1_TYPE); M_ASN1_I2D_put (a->iter, i2d_ASN1_INTEGER); M_ASN1_I2D_put (a->keylength, i2d_ASN1_INTEGER); M_ASN1_I2D_put (a->prf, i2d_X509_ALGOR); @@ -129,7 +129,7 @@ PBKDF2PARAM *PBKDF2PARAM_new(void) PBKDF2PARAM *ret=NULL; ASN1_CTX c; M_ASN1_New_Malloc(ret, PBKDF2PARAM); - M_ASN1_New(ret->salt, ASN1_OCTET_STRING_new); + M_ASN1_New(ret->salt, ASN1_TYPE_new); M_ASN1_New(ret->iter, ASN1_INTEGER_new); ret->keylength = NULL; ret->prf = NULL; @@ -143,7 +143,7 @@ PBKDF2PARAM *d2i_PBKDF2PARAM(PBKDF2PARAM **a, unsigned char **pp, M_ASN1_D2I_vars(a,PBKDF2PARAM *,PBKDF2PARAM_new); M_ASN1_D2I_Init(); M_ASN1_D2I_start_sequence(); - M_ASN1_D2I_get (ret->salt, d2i_ASN1_OCTET_STRING); + M_ASN1_D2I_get (ret->salt, d2i_ASN1_TYPE); M_ASN1_D2I_get (ret->iter, d2i_ASN1_INTEGER); M_ASN1_D2I_get_opt (ret->keylength, d2i_ASN1_INTEGER, V_ASN1_INTEGER); M_ASN1_D2I_get_opt (ret->prf, d2i_X509_ALGOR, V_ASN1_SEQUENCE); @@ -160,3 +160,114 @@ void PBKDF2PARAM_free (PBKDF2PARAM *a) Free ((char *)a); } +/* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: + * yes I know this is horrible! + */ + +X509_ALGOR *PKCS5_pbe2_set(EVP_CIPHER *cipher, int iter, unsigned char *salt, + int saltlen) +{ + X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; + int alg_nid; + EVP_CIPHER_CTX ctx; + unsigned char iv[EVP_MAX_IV_LENGTH]; + PBKDF2PARAM *kdf = NULL; + PBE2PARAM *pbe2 = NULL; + ASN1_OCTET_STRING *osalt = NULL; + + if(!(pbe2 = PBE2PARAM_new())) goto merr; + + /* Setup the AlgorithmIdentifier for the encryption scheme */ + scheme = pbe2->encryption; + + alg_nid = EVP_CIPHER_type(cipher); + + scheme->algorithm = OBJ_nid2obj(alg_nid); + if(!(scheme->parameter = ASN1_TYPE_new())) goto merr; + + /* Create random IV */ + RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)); + + /* Dummy cipherinit to just setup the IV */ + EVP_CipherInit(&ctx, cipher, NULL, iv, 0); + if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { + ASN1err(ASN1_F_PKCS5_PBE2_SET, + ASN1_R_ERROR_SETTING_CIPHER_PARAMS); + goto err; + } + EVP_CIPHER_CTX_cleanup(&ctx); + + if(!(kdf = PBKDF2PARAM_new())) goto merr; + if(!(osalt = ASN1_OCTET_STRING_new())) goto merr; + + if (!saltlen) saltlen = PKCS5_SALT_LEN; + if (!(osalt->data = Malloc (saltlen))) goto merr; + osalt->length = saltlen; + if (salt) memcpy (osalt->data, salt, saltlen); + else RAND_bytes (osalt->data, saltlen); + + if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr; + + /* Now include salt in kdf structure */ + kdf->salt->value.octet_string = osalt; + kdf->salt->type = V_ASN1_OCTET_STRING; + osalt = NULL; + + /* If its RC2 then we'd better setup the key length */ + + if(alg_nid == NID_rc2_cbc) { + if(!(kdf->keylength = ASN1_INTEGER_new())) goto merr; + if(!ASN1_INTEGER_set (kdf->keylength, + EVP_CIPHER_key_length(cipher))) goto merr; + } + + /* prf can stay NULL because we are using hmacWithSHA1 */ + + /* Now setup the PBE2PARAM keyfunc structure */ + + pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2); + + /* Encode PBKDF2PARAM into parameter of pbe2 */ + + if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr; + + if(!ASN1_pack_string(kdf, i2d_PBKDF2PARAM, + &pbe2->keyfunc->parameter->value.sequence)) goto merr; + pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE; + + PBKDF2PARAM_free(kdf); + kdf = NULL; + + /* Now set up top level AlgorithmIdentifier */ + + if(!(ret = X509_ALGOR_new())) goto merr; + if(!(ret->parameter = ASN1_TYPE_new())) goto merr; + + ret->algorithm = OBJ_nid2obj(NID_pbes2); + + /* Encode PBE2PARAM into parameter */ + + if(!ASN1_pack_string(pbe2, i2d_PBE2PARAM, + &ret->parameter->value.sequence)) goto merr; + ret->parameter->type = V_ASN1_SEQUENCE; + + PBE2PARAM_free(pbe2); + pbe2 = NULL; + + return ret; + + merr: + ASN1err(ASN1_F_PKCS5_PBE2_SET,ERR_R_MALLOC_FAILURE); + + err: + PBE2PARAM_free(pbe2); + /* Note 'scheme' is freed as part of pbe2 */ + ASN1_OCTET_STRING_free(osalt); + PBKDF2PARAM_free(kdf); + X509_ALGOR_free(kalg); + X509_ALGOR_free(ret); + + return NULL; + +} + |