Changeset View
Changeset View
Standalone View
Standalone View
projects/openssl111/crypto/heimdal/lib/hx509/crypto.c
Show First 20 Lines • Show All 220 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
static BIGNUM * | static BIGNUM * | ||||
heim_int2BN(const heim_integer *i) | heim_int2BN(const heim_integer *i) | ||||
{ | { | ||||
BIGNUM *bn; | BIGNUM *bn; | ||||
bn = BN_bin2bn(i->data, i->length, NULL); | bn = BN_bin2bn(i->data, i->length, NULL); | ||||
if (bn != NULL) | |||||
BN_set_negative(bn, i->negative); | BN_set_negative(bn, i->negative); | ||||
return bn; | return bn; | ||||
} | } | ||||
/* | /* | ||||
* | * | ||||
*/ | */ | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 656 Lines • ▼ Show 20 Lines | return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED; | ||||
return 0; | return 0; | ||||
} | } | ||||
static BIGNUM * | static BIGNUM * | ||||
rsa_get_internal(hx509_context context, | rsa_get_internal(hx509_context context, | ||||
hx509_private_key key, | hx509_private_key key, | ||||
const char *type) | const char *type) | ||||
{ | { | ||||
const BIGNUM *n; | |||||
if (strcasecmp(type, "rsa-modulus") == 0) { | if (strcasecmp(type, "rsa-modulus") == 0) { | ||||
return BN_dup(key->private_key.rsa->n); | RSA_get0_key(key->private_key.rsa, &n, NULL, NULL); | ||||
} else if (strcasecmp(type, "rsa-exponent") == 0) { | } else if (strcasecmp(type, "rsa-exponent") == 0) { | ||||
return BN_dup(key->private_key.rsa->e); | RSA_get0_key(key->private_key.rsa, NULL, &n, NULL); | ||||
} else | } else | ||||
return NULL; | return NULL; | ||||
return BN_dup(n); | |||||
} | } | ||||
static hx509_private_key_ops rsa_private_key_ops = { | static hx509_private_key_ops rsa_private_key_ops = { | ||||
"RSA PRIVATE KEY", | "RSA PRIVATE KEY", | ||||
ASN1_OID_ID_PKCS1_RSAENCRYPTION, | ASN1_OID_ID_PKCS1_RSAENCRYPTION, | ||||
NULL, | NULL, | ||||
▲ Show 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | dsa_verify_signature(hx509_context context, | ||||
const AlgorithmIdentifier *alg, | const AlgorithmIdentifier *alg, | ||||
const heim_octet_string *data, | const heim_octet_string *data, | ||||
const heim_octet_string *sig) | const heim_octet_string *sig) | ||||
{ | { | ||||
const SubjectPublicKeyInfo *spi; | const SubjectPublicKeyInfo *spi; | ||||
DSAPublicKey pk; | DSAPublicKey pk; | ||||
DSAParams param; | DSAParams param; | ||||
size_t size; | size_t size; | ||||
BIGNUM *key, *p, *q, *g; | |||||
DSA *dsa; | DSA *dsa; | ||||
int ret; | int ret; | ||||
spi = &signer->tbsCertificate.subjectPublicKeyInfo; | spi = &signer->tbsCertificate.subjectPublicKeyInfo; | ||||
dsa = DSA_new(); | dsa = DSA_new(); | ||||
if (dsa == NULL) { | if (dsa == NULL) { | ||||
hx509_set_error_string(context, 0, ENOMEM, "out of memory"); | hx509_set_error_string(context, 0, ENOMEM, "out of memory"); | ||||
return ENOMEM; | return ENOMEM; | ||||
} | } | ||||
ret = decode_DSAPublicKey(spi->subjectPublicKey.data, | ret = decode_DSAPublicKey(spi->subjectPublicKey.data, | ||||
spi->subjectPublicKey.length / 8, | spi->subjectPublicKey.length / 8, | ||||
&pk, &size); | &pk, &size); | ||||
if (ret) | if (ret) | ||||
goto out; | goto out; | ||||
dsa->pub_key = heim_int2BN(&pk); | key = heim_int2BN(&pk); | ||||
free_DSAPublicKey(&pk); | free_DSAPublicKey(&pk); | ||||
if (dsa->pub_key == NULL) { | if (key == NULL) { | ||||
ret = ENOMEM; | ret = ENOMEM; | ||||
hx509_set_error_string(context, 0, ret, "out of memory"); | hx509_set_error_string(context, 0, ret, "out of memory"); | ||||
goto out; | goto out; | ||||
} | } | ||||
ret = DSA_set0_key(dsa, key, NULL); | |||||
if (ret != 1) { | |||||
BN_free(key); | |||||
ret = EINVAL; | |||||
hx509_set_error_string(context, 0, ret, "failed to set DSA key"); | |||||
goto out; | |||||
} | |||||
if (spi->algorithm.parameters == NULL) { | if (spi->algorithm.parameters == NULL) { | ||||
ret = HX509_CRYPTO_SIG_INVALID_FORMAT; | ret = HX509_CRYPTO_SIG_INVALID_FORMAT; | ||||
hx509_set_error_string(context, 0, ret, "DSA parameters missing"); | hx509_set_error_string(context, 0, ret, "DSA parameters missing"); | ||||
goto out; | goto out; | ||||
} | } | ||||
ret = decode_DSAParams(spi->algorithm.parameters->data, | ret = decode_DSAParams(spi->algorithm.parameters->data, | ||||
spi->algorithm.parameters->length, | spi->algorithm.parameters->length, | ||||
¶m, | ¶m, | ||||
&size); | &size); | ||||
if (ret) { | if (ret) { | ||||
hx509_set_error_string(context, 0, ret, "DSA parameters failed to decode"); | hx509_set_error_string(context, 0, ret, "DSA parameters failed to decode"); | ||||
goto out; | goto out; | ||||
} | } | ||||
dsa->p = heim_int2BN(¶m.p); | p = heim_int2BN(¶m.p); | ||||
dsa->q = heim_int2BN(¶m.q); | q = heim_int2BN(¶m.q); | ||||
dsa->g = heim_int2BN(¶m.g); | g = heim_int2BN(¶m.g); | ||||
free_DSAParams(¶m); | free_DSAParams(¶m); | ||||
if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { | if (p == NULL || q == NULL || g == NULL) { | ||||
BN_free(p); | |||||
BN_free(q); | |||||
BN_free(g); | |||||
ret = ENOMEM; | ret = ENOMEM; | ||||
hx509_set_error_string(context, 0, ret, "out of memory"); | hx509_set_error_string(context, 0, ret, "out of memory"); | ||||
goto out; | goto out; | ||||
} | } | ||||
ret = DSA_set0_pqg(dsa, p, q, g); | |||||
if (ret != 1) { | |||||
BN_free(p); | |||||
BN_free(q); | |||||
BN_free(g); | |||||
ret = EINVAL; | |||||
hx509_set_error_string(context, 0, ret, "failed to set DSA parameters"); | |||||
goto out; | |||||
} | |||||
ret = DSA_verify(-1, data->data, data->length, | ret = DSA_verify(-1, data->data, data->length, | ||||
(unsigned char*)sig->data, sig->length, | (unsigned char*)sig->data, sig->length, | ||||
dsa); | dsa); | ||||
if (ret == 1) | if (ret == 1) | ||||
ret = 0; | ret = 0; | ||||
else if (ret == 0 || ret == -1) { | else if (ret == 0 || ret == -1) { | ||||
ret = HX509_CRYPTO_BAD_SIGNATURE; | ret = HX509_CRYPTO_BAD_SIGNATURE; | ||||
hx509_set_error_string(context, 0, ret, "BAD DSA sigature"); | hx509_set_error_string(context, 0, ret, "BAD DSA sigature"); | ||||
▲ Show 20 Lines • Show All 1,447 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
hx509_crypto_encrypt(hx509_crypto crypto, | hx509_crypto_encrypt(hx509_crypto crypto, | ||||
const void *data, | const void *data, | ||||
const size_t length, | const size_t length, | ||||
const heim_octet_string *ivec, | const heim_octet_string *ivec, | ||||
heim_octet_string **ciphertext) | heim_octet_string **ciphertext) | ||||
{ | { | ||||
EVP_CIPHER_CTX evp; | EVP_CIPHER_CTX *evp; | ||||
size_t padsize, bsize; | size_t padsize, bsize; | ||||
int ret; | int ret; | ||||
*ciphertext = NULL; | *ciphertext = NULL; | ||||
if ((crypto->cipher->flags & CIPHER_WEAK) && | if ((crypto->cipher->flags & CIPHER_WEAK) && | ||||
(crypto->flags & ALLOW_WEAK) == 0) | (crypto->flags & ALLOW_WEAK) == 0) | ||||
return HX509_CRYPTO_ALGORITHM_BEST_BEFORE; | return HX509_CRYPTO_ALGORITHM_BEST_BEFORE; | ||||
assert(EVP_CIPHER_iv_length(crypto->c) == (int)ivec->length); | assert(EVP_CIPHER_iv_length(crypto->c) == (int)ivec->length); | ||||
EVP_CIPHER_CTX_init(&evp); | evp = EVP_CIPHER_CTX_new(); | ||||
if (evp == NULL) | |||||
return ENOMEM; | |||||
ret = EVP_CipherInit_ex(&evp, crypto->c, NULL, | ret = EVP_CipherInit_ex(evp, crypto->c, NULL, | ||||
crypto->key.data, ivec->data, 1); | crypto->key.data, ivec->data, 1); | ||||
if (ret != 1) { | if (ret != 1) { | ||||
EVP_CIPHER_CTX_cleanup(&evp); | |||||
ret = HX509_CRYPTO_INTERNAL_ERROR; | ret = HX509_CRYPTO_INTERNAL_ERROR; | ||||
goto out; | goto out; | ||||
} | } | ||||
*ciphertext = calloc(1, sizeof(**ciphertext)); | *ciphertext = calloc(1, sizeof(**ciphertext)); | ||||
if (*ciphertext == NULL) { | if (*ciphertext == NULL) { | ||||
ret = ENOMEM; | ret = ENOMEM; | ||||
goto out; | goto out; | ||||
Show All 23 Lines | goto out; | ||||
if (padsize) { | if (padsize) { | ||||
size_t i; | size_t i; | ||||
unsigned char *p = (*ciphertext)->data; | unsigned char *p = (*ciphertext)->data; | ||||
p += length; | p += length; | ||||
for (i = 0; i < padsize; i++) | for (i = 0; i < padsize; i++) | ||||
*p++ = padsize; | *p++ = padsize; | ||||
} | } | ||||
ret = EVP_Cipher(&evp, (*ciphertext)->data, | ret = EVP_Cipher(evp, (*ciphertext)->data, | ||||
(*ciphertext)->data, | (*ciphertext)->data, | ||||
length + padsize); | length + padsize); | ||||
if (ret != 1) { | if (ret != 1) { | ||||
ret = HX509_CRYPTO_INTERNAL_ERROR; | ret = HX509_CRYPTO_INTERNAL_ERROR; | ||||
goto out; | goto out; | ||||
} | } | ||||
ret = 0; | ret = 0; | ||||
out: | out: | ||||
if (ret) { | if (ret) { | ||||
if (*ciphertext) { | if (*ciphertext) { | ||||
if ((*ciphertext)->data) { | if ((*ciphertext)->data) { | ||||
free((*ciphertext)->data); | free((*ciphertext)->data); | ||||
} | } | ||||
free(*ciphertext); | free(*ciphertext); | ||||
*ciphertext = NULL; | *ciphertext = NULL; | ||||
} | } | ||||
} | } | ||||
EVP_CIPHER_CTX_cleanup(&evp); | EVP_CIPHER_CTX_free(evp); | ||||
return ret; | return ret; | ||||
} | } | ||||
int | int | ||||
hx509_crypto_decrypt(hx509_crypto crypto, | hx509_crypto_decrypt(hx509_crypto crypto, | ||||
const void *data, | const void *data, | ||||
const size_t length, | const size_t length, | ||||
heim_octet_string *ivec, | heim_octet_string *ivec, | ||||
heim_octet_string *clear) | heim_octet_string *clear) | ||||
{ | { | ||||
EVP_CIPHER_CTX evp; | EVP_CIPHER_CTX *evp; | ||||
void *idata = NULL; | void *idata = NULL; | ||||
int ret; | int ret; | ||||
clear->data = NULL; | clear->data = NULL; | ||||
clear->length = 0; | clear->length = 0; | ||||
if ((crypto->cipher->flags & CIPHER_WEAK) && | if ((crypto->cipher->flags & CIPHER_WEAK) && | ||||
(crypto->flags & ALLOW_WEAK) == 0) | (crypto->flags & ALLOW_WEAK) == 0) | ||||
return HX509_CRYPTO_ALGORITHM_BEST_BEFORE; | return HX509_CRYPTO_ALGORITHM_BEST_BEFORE; | ||||
if (ivec && EVP_CIPHER_iv_length(crypto->c) < (int)ivec->length) | if (ivec && EVP_CIPHER_iv_length(crypto->c) < (int)ivec->length) | ||||
return HX509_CRYPTO_INTERNAL_ERROR; | return HX509_CRYPTO_INTERNAL_ERROR; | ||||
if (crypto->key.data == NULL) | if (crypto->key.data == NULL) | ||||
return HX509_CRYPTO_INTERNAL_ERROR; | return HX509_CRYPTO_INTERNAL_ERROR; | ||||
if (ivec) | if (ivec) | ||||
idata = ivec->data; | idata = ivec->data; | ||||
EVP_CIPHER_CTX_init(&evp); | evp = EVP_CIPHER_CTX_new(); | ||||
if (evp == NULL) | |||||
return ENOMEM; | |||||
ret = EVP_CipherInit_ex(&evp, crypto->c, NULL, | ret = EVP_CipherInit_ex(evp, crypto->c, NULL, | ||||
crypto->key.data, idata, 0); | crypto->key.data, idata, 0); | ||||
if (ret != 1) { | if (ret != 1) { | ||||
EVP_CIPHER_CTX_cleanup(&evp); | EVP_CIPHER_CTX_free(evp); | ||||
return HX509_CRYPTO_INTERNAL_ERROR; | return HX509_CRYPTO_INTERNAL_ERROR; | ||||
} | } | ||||
clear->length = length; | clear->length = length; | ||||
clear->data = malloc(length); | clear->data = malloc(length); | ||||
if (clear->data == NULL) { | if (clear->data == NULL) { | ||||
EVP_CIPHER_CTX_cleanup(&evp); | EVP_CIPHER_CTX_free(evp); | ||||
clear->length = 0; | clear->length = 0; | ||||
return ENOMEM; | return ENOMEM; | ||||
} | } | ||||
if (EVP_Cipher(&evp, clear->data, data, length) != 1) { | if (EVP_Cipher(evp, clear->data, data, length) != 1) { | ||||
EVP_CIPHER_CTX_free(evp); | |||||
return HX509_CRYPTO_INTERNAL_ERROR; | return HX509_CRYPTO_INTERNAL_ERROR; | ||||
} | } | ||||
EVP_CIPHER_CTX_cleanup(&evp); | EVP_CIPHER_CTX_free(evp); | ||||
if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) { | if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) { | ||||
int padsize; | int padsize; | ||||
unsigned char *p; | unsigned char *p; | ||||
int j, bsize = EVP_CIPHER_block_size(crypto->c); | int j, bsize = EVP_CIPHER_block_size(crypto->c); | ||||
if ((int)clear->length < bsize) { | if ((int)clear->length < bsize) { | ||||
ret = HX509_CMS_PADDING_ERROR; | ret = HX509_CMS_PADDING_ERROR; | ||||
▲ Show 20 Lines • Show All 242 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
match_keys_rsa(hx509_cert c, hx509_private_key private_key) | match_keys_rsa(hx509_cert c, hx509_private_key private_key) | ||||
{ | { | ||||
const Certificate *cert; | const Certificate *cert; | ||||
const SubjectPublicKeyInfo *spi; | const SubjectPublicKeyInfo *spi; | ||||
RSAPublicKey pk; | RSAPublicKey pk; | ||||
RSA *rsa; | RSA *rsa; | ||||
const BIGNUM *d, *p, *q, *dmp1, *dmq1, *iqmp; | |||||
BIGNUM *new_d, *new_p, *new_q, *new_dmp1, *new_dmq1, *new_iqmp, *n, *e; | |||||
size_t size; | size_t size; | ||||
int ret; | int ret; | ||||
if (private_key->private_key.rsa == NULL) | if (private_key->private_key.rsa == NULL) | ||||
return 0; | return 0; | ||||
rsa = private_key->private_key.rsa; | rsa = private_key->private_key.rsa; | ||||
if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL) | RSA_get0_key(rsa, NULL, NULL, &d); | ||||
RSA_get0_factors(rsa, &p, &q); | |||||
RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); | |||||
if (d == NULL || p == NULL || q == NULL) | |||||
return 0; | return 0; | ||||
cert = _hx509_get_cert(c); | cert = _hx509_get_cert(c); | ||||
spi = &cert->tbsCertificate.subjectPublicKeyInfo; | spi = &cert->tbsCertificate.subjectPublicKeyInfo; | ||||
rsa = RSA_new(); | rsa = RSA_new(); | ||||
if (rsa == NULL) | if (rsa == NULL) | ||||
return 0; | return 0; | ||||
ret = decode_RSAPublicKey(spi->subjectPublicKey.data, | ret = decode_RSAPublicKey(spi->subjectPublicKey.data, | ||||
spi->subjectPublicKey.length / 8, | spi->subjectPublicKey.length / 8, | ||||
&pk, &size); | &pk, &size); | ||||
if (ret) { | if (ret) { | ||||
RSA_free(rsa); | RSA_free(rsa); | ||||
return 0; | return 0; | ||||
} | } | ||||
rsa->n = heim_int2BN(&pk.modulus); | n = heim_int2BN(&pk.modulus); | ||||
rsa->e = heim_int2BN(&pk.publicExponent); | e = heim_int2BN(&pk.publicExponent); | ||||
free_RSAPublicKey(&pk); | free_RSAPublicKey(&pk); | ||||
rsa->d = BN_dup(private_key->private_key.rsa->d); | new_d = BN_dup(d); | ||||
rsa->p = BN_dup(private_key->private_key.rsa->p); | new_p = BN_dup(p); | ||||
rsa->q = BN_dup(private_key->private_key.rsa->q); | new_q = BN_dup(q); | ||||
rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1); | new_dmp1 = BN_dup(dmp1); | ||||
rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1); | new_dmq1 = BN_dup(dmq1); | ||||
rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp); | new_iqmp = BN_dup(iqmp); | ||||
if (rsa->n == NULL || rsa->e == NULL || | if (n == NULL || e == NULL || | ||||
rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL || | new_d == NULL || new_p == NULL|| new_q == NULL || | ||||
rsa->dmp1 == NULL || rsa->dmq1 == NULL) { | new_dmp1 == NULL || new_dmq1 == NULL || new_iqmp == NULL) { | ||||
BN_free(n); | |||||
BN_free(e); | |||||
BN_free(new_d); | |||||
BN_free(new_p); | |||||
BN_free(new_q); | |||||
BN_free(new_dmp1); | |||||
BN_free(new_dmq1); | |||||
BN_free(new_iqmp); | |||||
RSA_free(rsa); | |||||
return 0; | |||||
} | |||||
ret = RSA_set0_key(rsa, new_d, n, e); | |||||
if (ret != 1) { | |||||
BN_free(n); | |||||
BN_free(e); | |||||
BN_free(new_d); | |||||
BN_free(new_p); | |||||
BN_free(new_q); | |||||
BN_free(new_dmp1); | |||||
BN_free(new_dmq1); | |||||
BN_free(new_iqmp); | |||||
RSA_free(rsa); | |||||
return 0; | |||||
} | |||||
ret = RSA_set0_factors(rsa, new_p, new_q); | |||||
if (ret != 1) { | |||||
BN_free(new_p); | |||||
BN_free(new_q); | |||||
BN_free(new_dmp1); | |||||
BN_free(new_dmq1); | |||||
BN_free(new_iqmp); | |||||
RSA_free(rsa); | |||||
return 0; | |||||
} | |||||
ret = RSA_set0_crt_params(rsa, new_dmp1, new_dmq1, new_iqmp); | |||||
if (ret != 1) { | |||||
BN_free(new_dmp1); | |||||
BN_free(new_dmq1); | |||||
BN_free(new_iqmp); | |||||
RSA_free(rsa); | RSA_free(rsa); | ||||
return 0; | return 0; | ||||
} | } | ||||
ret = RSA_check_key(rsa); | ret = RSA_check_key(rsa); | ||||
RSA_free(rsa); | RSA_free(rsa); | ||||
return ret == 1; | return ret == 1; | ||||
▲ Show 20 Lines • Show All 209 Lines • Show Last 20 Lines |