Break out the parameter handling code for encrypting data to handle RC2.
Needed for Windows 2k pk-init support. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17067 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -1071,33 +1071,222 @@ _hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
|
||||
}
|
||||
|
||||
|
||||
struct hx509cipher {
|
||||
const heim_oid *(*oid_func)(void);
|
||||
const EVP_CIPHER *(*evp_func)(void);
|
||||
int (*get_params)(hx509_context, const hx509_crypto,
|
||||
const heim_octet_string *, heim_octet_string *);
|
||||
int (*set_params)(hx509_context, const heim_octet_string *,
|
||||
hx509_crypto, heim_octet_string *);
|
||||
};
|
||||
|
||||
struct hx509_crypto_data {
|
||||
char *name;
|
||||
const struct hx509cipher *cipher;
|
||||
const EVP_CIPHER *c;
|
||||
heim_octet_string key;
|
||||
heim_oid oid;
|
||||
void *param;
|
||||
};
|
||||
|
||||
static const EVP_CIPHER *
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static const heim_oid *
|
||||
oid_private_rc2_40(void)
|
||||
{
|
||||
return &private_rc2_40_oid;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
CMSCBCParam_get(hx509_context context, const hx509_crypto crypto,
|
||||
const heim_octet_string *ivec, heim_octet_string *param)
|
||||
{
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
assert(crypto->param == NULL);
|
||||
if (ivec == NULL)
|
||||
return 0;
|
||||
|
||||
ASN1_MALLOC_ENCODE(CMSCBCParameter, param->data, param->length,
|
||||
ivec, &size, ret);
|
||||
if (ret == 0 && size != param->length)
|
||||
_hx509_abort("Internal asn1 encoder failure");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
CMSCBCParam_set(hx509_context context, const heim_octet_string *param,
|
||||
hx509_crypto crypto, heim_octet_string *ivec)
|
||||
{
|
||||
if (ivec == NULL)
|
||||
return 0;
|
||||
|
||||
return decode_CMSCBCParameter(param->data, param->length, ivec, NULL);
|
||||
}
|
||||
|
||||
struct _RC2_params {
|
||||
int maximum_effective_key;
|
||||
};
|
||||
|
||||
static int
|
||||
CMSRC2CBCParam_get(hx509_context context, const hx509_crypto crypto,
|
||||
const heim_octet_string *ivec, heim_octet_string *param)
|
||||
{
|
||||
CMSRC2CBCParameter rc2params;
|
||||
const struct _RC2_params *p = crypto->param;
|
||||
int maximum_effective_key = 128;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
memset(&rc2params, 0, sizeof(rc2params));
|
||||
|
||||
if (p)
|
||||
maximum_effective_key = p->maximum_effective_key;
|
||||
|
||||
switch(maximum_effective_key) {
|
||||
case 40:
|
||||
rc2params.rc2ParameterVersion = 160;
|
||||
break;
|
||||
case 64:
|
||||
rc2params.rc2ParameterVersion = 120;
|
||||
break;
|
||||
case 128:
|
||||
rc2params.rc2ParameterVersion = 58;
|
||||
break;
|
||||
}
|
||||
rc2params.iv = *ivec;
|
||||
|
||||
ASN1_MALLOC_ENCODE(CMSRC2CBCParameter, param->data, param->length,
|
||||
&rc2params, &size, ret);
|
||||
if (ret == 0 && size != param->length)
|
||||
_hx509_abort("Internal asn1 encoder failure");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
CMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param,
|
||||
hx509_crypto crypto, heim_octet_string *ivec)
|
||||
{
|
||||
CMSRC2CBCParameter rc2param;
|
||||
struct _RC2_params *p;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
ret = decode_CMSRC2CBCParameter(param->data, param->length,
|
||||
&rc2param, &size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
p = calloc(1, sizeof(*p));
|
||||
if (p == NULL) {
|
||||
free_CMSRC2CBCParameter(&rc2param);
|
||||
return ENOMEM;
|
||||
}
|
||||
switch(rc2param.rc2ParameterVersion) {
|
||||
case 160:
|
||||
crypto->c = EVP_rc2_40_cbc();
|
||||
p->maximum_effective_key = 40;
|
||||
break;
|
||||
case 120:
|
||||
crypto->c = EVP_rc2_64_cbc();
|
||||
p->maximum_effective_key = 64;
|
||||
break;
|
||||
case 58:
|
||||
crypto->c = EVP_rc2_cbc();
|
||||
p->maximum_effective_key = 128;
|
||||
break;
|
||||
default:
|
||||
free_CMSRC2CBCParameter(&rc2param);
|
||||
return HX509_CRYPTO_SIG_INVALID_FORMAT;
|
||||
}
|
||||
if (ivec)
|
||||
ret = copy_octet_string(&rc2param.iv, ivec);
|
||||
free_CMSRC2CBCParameter(&rc2param);
|
||||
if (ret == 0)
|
||||
crypto->param = p;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static const struct hx509cipher ciphers[] = {
|
||||
{
|
||||
oid_id_pkcs3_rc2_cbc,
|
||||
EVP_rc2_cbc,
|
||||
CMSRC2CBCParam_get,
|
||||
CMSRC2CBCParam_set
|
||||
},
|
||||
{
|
||||
oid_id_rsadsi_rc2_cbc,
|
||||
EVP_rc2_cbc,
|
||||
CMSRC2CBCParam_get,
|
||||
CMSRC2CBCParam_set
|
||||
},
|
||||
{
|
||||
oid_private_rc2_40,
|
||||
EVP_rc2_40_cbc,
|
||||
CMSRC2CBCParam_get,
|
||||
CMSRC2CBCParam_set
|
||||
},
|
||||
{
|
||||
oid_id_pkcs3_rc2_cbc,
|
||||
EVP_rc2_cbc,
|
||||
CMSRC2CBCParam_get,
|
||||
CMSRC2CBCParam_set
|
||||
},
|
||||
{
|
||||
oid_id_pkcs3_des_ede3_cbc,
|
||||
EVP_des_ede3_cbc,
|
||||
CMSCBCParam_get,
|
||||
CMSCBCParam_set
|
||||
},
|
||||
{
|
||||
oid_id_rsadsi_des_ede3_cbc,
|
||||
EVP_des_ede3_cbc,
|
||||
CMSCBCParam_get,
|
||||
CMSCBCParam_set
|
||||
},
|
||||
{
|
||||
oid_id_aes_128_cbc,
|
||||
EVP_aes_128_cbc,
|
||||
CMSCBCParam_get,
|
||||
CMSCBCParam_set
|
||||
},
|
||||
{
|
||||
oid_id_aes_192_cbc,
|
||||
EVP_aes_192_cbc,
|
||||
CMSCBCParam_get,
|
||||
CMSCBCParam_set
|
||||
},
|
||||
{
|
||||
oid_id_aes_256_cbc,
|
||||
EVP_aes_256_cbc,
|
||||
CMSCBCParam_get,
|
||||
CMSCBCParam_set
|
||||
}
|
||||
};
|
||||
|
||||
static const struct hx509cipher *
|
||||
find_cipher(const heim_oid *oid)
|
||||
{
|
||||
if (heim_oid_cmp(oid, oid_id_pkcs3_rc2_cbc()) == 0) {
|
||||
return EVP_rc2_cbc();
|
||||
} else if (heim_oid_cmp(oid, oid_id_rsadsi_rc2_cbc()) == 0) {
|
||||
return EVP_rc2_cbc();
|
||||
} else if (heim_oid_cmp(oid, &private_rc2_40_oid) == 0) {
|
||||
return EVP_rc2_40_cbc();
|
||||
} else if (heim_oid_cmp(oid, oid_id_pkcs3_des_ede3_cbc()) == 0) {
|
||||
return EVP_des_ede3_cbc();
|
||||
} else if (heim_oid_cmp(oid, oid_id_rsadsi_des_ede3_cbc()) == 0) {
|
||||
return EVP_des_ede3_cbc();
|
||||
} else if (heim_oid_cmp(oid, oid_id_aes_128_cbc()) == 0) {
|
||||
return EVP_aes_128_cbc();
|
||||
} else if (heim_oid_cmp(oid, oid_id_aes_192_cbc()) == 0) {
|
||||
return EVP_aes_192_cbc();
|
||||
} else if (heim_oid_cmp(oid, oid_id_aes_256_cbc()) == 0) {
|
||||
return EVP_aes_256_cbc();
|
||||
}
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
|
||||
if (heim_oid_cmp(oid, (*ciphers[i].oid_func)()) == 0)
|
||||
return &ciphers[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1107,19 +1296,20 @@ hx509_crypto_init(hx509_context context,
|
||||
const heim_oid *enctype,
|
||||
hx509_crypto *crypto)
|
||||
{
|
||||
const EVP_CIPHER *c;
|
||||
const struct hx509cipher *cipher;
|
||||
|
||||
*crypto = NULL;
|
||||
|
||||
c = find_cipher(enctype);
|
||||
if (c == NULL)
|
||||
cipher = find_cipher(enctype);
|
||||
if (cipher == NULL)
|
||||
return HX509_ALG_NOT_SUPP;
|
||||
|
||||
*crypto = calloc(1, sizeof(**crypto));
|
||||
if (*crypto == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
(*crypto)->c = c;
|
||||
(*crypto)->cipher = cipher;
|
||||
(*crypto)->c = (*cipher->evp_func)();
|
||||
|
||||
if (copy_oid(enctype, &(*crypto)->oid)) {
|
||||
hx509_crypto_destroy(*crypto);
|
||||
@@ -1197,37 +1387,23 @@ hx509_crypto_set_random_key(hx509_crypto crypto, heim_octet_string *key)
|
||||
}
|
||||
|
||||
int
|
||||
hx509_crypto_set_params(hx509_crypto crypto,
|
||||
hx509_crypto_set_params(hx509_context context,
|
||||
hx509_crypto crypto,
|
||||
const heim_octet_string *param,
|
||||
heim_octet_string *ivec)
|
||||
{
|
||||
if (ivec == NULL)
|
||||
return 0;
|
||||
return decode_CMSCBCParameter(param->data, param->length, ivec, NULL);
|
||||
return (*crypto->cipher->set_params)(context, param, crypto, ivec);
|
||||
}
|
||||
|
||||
int
|
||||
hx509_crypto_get_params(hx509_crypto crypto,
|
||||
hx509_crypto_get_params(hx509_context context,
|
||||
hx509_crypto crypto,
|
||||
const heim_octet_string *ivec,
|
||||
heim_octet_string *param)
|
||||
{
|
||||
int ret;
|
||||
size_t size;
|
||||
|
||||
ASN1_MALLOC_ENCODE(CMSCBCParameter,
|
||||
param->data,
|
||||
param->length,
|
||||
ivec,
|
||||
&size,
|
||||
ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (param->length != size)
|
||||
_hx509_abort("internal ASN.1 encoder error");
|
||||
return 0;
|
||||
return (*crypto->cipher->get_params)(context, crypto, ivec, param);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hx509_crypto_encrypt(hx509_crypto crypto,
|
||||
const void *data,
|
||||
@@ -1486,6 +1662,7 @@ find_string2key(const heim_oid *oid,
|
||||
*md = EVP_sha1();
|
||||
*s2k = PBE_string2key;
|
||||
return oid_id_pkcs3_rc2_cbc();
|
||||
#if 0
|
||||
} else if (heim_oid_cmp(oid, oid_id_pbeWithSHAAnd40BitRC4()) == 0) {
|
||||
*c = EVP_rc4_40();
|
||||
*md = EVP_sha1();
|
||||
@@ -1496,6 +1673,7 @@ find_string2key(const heim_oid *oid,
|
||||
*md = EVP_sha1();
|
||||
*s2k = PBE_string2key;
|
||||
return oid_id_pkcs3_rc4();
|
||||
#endif
|
||||
} else if (heim_oid_cmp(oid, oid_id_pbeWithSHAAnd3_KeyTripleDES_CBC()) == 0) {
|
||||
*c = EVP_des_ede3_cbc();
|
||||
*md = EVP_sha1();
|
||||
|
Reference in New Issue
Block a user