⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crypto.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 5 页
字号:
	crypto->key.length = 0;	return ENOMEM;    }    if (RAND_bytes(crypto->key.data, crypto->key.length) <= 0) {	free(crypto->key.data);	crypto->key.data = NULL;	crypto->key.length = 0;	return HX509_CRYPTO_INTERNAL_ERROR;    }    if (key)	return der_copy_octet_string(&crypto->key, key);    else	return 0;}inthx509_crypto_set_params(hx509_context context,			hx509_crypto crypto, 			const heim_octet_string *param,			heim_octet_string *ivec){    return (*crypto->cipher->set_params)(context, param, crypto, ivec);}inthx509_crypto_get_params(hx509_context context,			hx509_crypto crypto, 			const heim_octet_string *ivec,			heim_octet_string *param){    return (*crypto->cipher->get_params)(context, crypto, ivec, param);}inthx509_crypto_random_iv(hx509_crypto crypto, heim_octet_string *ivec){    ivec->length = EVP_CIPHER_iv_length(crypto->c);    ivec->data = malloc(ivec->length);    if (ivec->data == NULL) {	ivec->length = 0;	return ENOMEM;    }    if (RAND_bytes(ivec->data, ivec->length) <= 0) {	free(ivec->data);	ivec->data = NULL;	ivec->length = 0;	return HX509_CRYPTO_INTERNAL_ERROR;    }    return 0;}inthx509_crypto_encrypt(hx509_crypto crypto,		     const void *data,		     const size_t length,		     const heim_octet_string *ivec,		     heim_octet_string **ciphertext){    EVP_CIPHER_CTX evp;    size_t padsize;    int ret;    *ciphertext = NULL;    assert(EVP_CIPHER_iv_length(crypto->c) == ivec->length);    EVP_CIPHER_CTX_init(&evp);    ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,			    crypto->key.data, ivec->data, 1);    if (ret != 1) {	EVP_CIPHER_CTX_cleanup(&evp);	ret = HX509_CRYPTO_INTERNAL_ERROR;	goto out;    }    *ciphertext = calloc(1, sizeof(**ciphertext));    if (*ciphertext == NULL) {	ret = ENOMEM;	goto out;    }        if (EVP_CIPHER_block_size(crypto->c) == 1) {	padsize = 0;    } else {	int bsize = EVP_CIPHER_block_size(crypto->c);	padsize = bsize - (length % bsize);    }    (*ciphertext)->length = length + padsize;    (*ciphertext)->data = malloc(length + padsize);    if ((*ciphertext)->data == NULL) {	ret = ENOMEM;	goto out;    }	    memcpy((*ciphertext)->data, data, length);    if (padsize) {	int i;	unsigned char *p = (*ciphertext)->data;	p += length;	for (i = 0; i < padsize; i++)	    *p++ = padsize;    }    ret = EVP_Cipher(&evp, (*ciphertext)->data,		     (*ciphertext)->data,		     length + padsize);    if (ret != 1) {	ret = HX509_CRYPTO_INTERNAL_ERROR;	goto out;    }    ret = 0; out:    if (ret) {	if (*ciphertext) {	    if ((*ciphertext)->data) {		free((*ciphertext)->data);	    }	    free(*ciphertext);	    *ciphertext = NULL;	}    }    EVP_CIPHER_CTX_cleanup(&evp);    return ret;}inthx509_crypto_decrypt(hx509_crypto crypto,		     const void *data,		     const size_t length,		     heim_octet_string *ivec,		     heim_octet_string *clear){    EVP_CIPHER_CTX evp;    void *idata = NULL;    int ret;    clear->data = NULL;    clear->length = 0;    if (ivec && EVP_CIPHER_iv_length(crypto->c) < ivec->length)	return HX509_CRYPTO_INTERNAL_ERROR;    if (crypto->key.data == NULL)	return HX509_CRYPTO_INTERNAL_ERROR;    if (ivec)	idata = ivec->data;    EVP_CIPHER_CTX_init(&evp);    ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,			    crypto->key.data, idata, 0);    if (ret != 1) {	EVP_CIPHER_CTX_cleanup(&evp);	return HX509_CRYPTO_INTERNAL_ERROR;    }    clear->length = length;    clear->data = malloc(length);    if (clear->data == NULL) {	EVP_CIPHER_CTX_cleanup(&evp);	clear->length = 0;	return ENOMEM;    }    if (EVP_Cipher(&evp, clear->data, data, length) != 1) {	return HX509_CRYPTO_INTERNAL_ERROR;    }    EVP_CIPHER_CTX_cleanup(&evp);    if (EVP_CIPHER_block_size(crypto->c) > 1) {	int padsize;	unsigned char *p; 	int j, bsize = EVP_CIPHER_block_size(crypto->c);	if (clear->length < bsize) {	    ret = HX509_CMS_PADDING_ERROR;	    goto out;	}	p = clear->data;	p += clear->length - 1;	padsize = *p;	if (padsize > bsize) {	    ret = HX509_CMS_PADDING_ERROR;	    goto out;	}	clear->length -= padsize;	for (j = 0; j < padsize; j++) {	    if (*p-- != padsize) {		ret = HX509_CMS_PADDING_ERROR;		goto out;	    }	}    }    return 0; out:    if (clear->data)	free(clear->data);    clear->data = NULL;    clear->length = 0;    return ret;}typedef int (*PBE_string2key_func)(hx509_context,				   const char *,				   const heim_octet_string *,				   hx509_crypto *, heim_octet_string *, 				   heim_octet_string *,				   const heim_oid *, const EVP_MD *);static intPBE_string2key(hx509_context context,	       const char *password,	       const heim_octet_string *parameters,	       hx509_crypto *crypto, 	       heim_octet_string *key, heim_octet_string *iv,	       const heim_oid *enc_oid,	       const EVP_MD *md){    PKCS12_PBEParams p12params;    int passwordlen;    hx509_crypto c;    int iter, saltlen, ret;    unsigned char *salt;    passwordlen = password ? strlen(password) : 0;    if (parameters == NULL) 	return HX509_ALG_NOT_SUPP;    ret = decode_PKCS12_PBEParams(parameters->data,				  parameters->length,				  &p12params, NULL);    if (ret)	goto out;    if (p12params.iterations)	iter = *p12params.iterations;    else	iter = 1;    salt = p12params.salt.data;    saltlen = p12params.salt.length;    if (!PKCS12_key_gen (password, passwordlen, salt, saltlen, 			 PKCS12_KEY_ID, iter, key->length, key->data, md)) {	ret = HX509_CRYPTO_INTERNAL_ERROR;	goto out;    }        if (!PKCS12_key_gen (password, passwordlen, salt, saltlen, 			 PKCS12_IV_ID, iter, iv->length, iv->data, md)) {	ret = HX509_CRYPTO_INTERNAL_ERROR;	goto out;    }    ret = hx509_crypto_init(context, NULL, enc_oid, &c);    if (ret)	goto out;    ret = hx509_crypto_set_key_data(c, key->data, key->length);    if (ret) {	hx509_crypto_destroy(c);	goto out;    }    *crypto = c;out:    free_PKCS12_PBEParams(&p12params);    return ret;}static const heim_oid *find_string2key(const heim_oid *oid, 		const EVP_CIPHER **c, 		const EVP_MD **md,		PBE_string2key_func *s2k){    if (der_heim_oid_cmp(oid, oid_id_pbewithSHAAnd40BitRC2_CBC()) == 0) {	*c = EVP_rc2_40_cbc();	*md = EVP_sha1();	*s2k = PBE_string2key;	return oid_private_rc2_40();    } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd128BitRC2_CBC()) == 0) {	*c = EVP_rc2_cbc();	*md = EVP_sha1();	*s2k = PBE_string2key;	return oid_id_pkcs3_rc2_cbc();#if 0    } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd40BitRC4()) == 0) {	*c = EVP_rc4_40();	*md = EVP_sha1();	*s2k = PBE_string2key;	return NULL;    } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd128BitRC4()) == 0) {	*c = EVP_rc4();	*md = EVP_sha1();	*s2k = PBE_string2key;	return oid_id_pkcs3_rc4();#endif    } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd3_KeyTripleDES_CBC()) == 0) {	*c = EVP_des_ede3_cbc();	*md = EVP_sha1();	*s2k = PBE_string2key;	return oid_id_pkcs3_des_ede3_cbc();    }    return NULL;}/* * */int_hx509_pbe_encrypt(hx509_context context,		   hx509_lock lock,		   const AlgorithmIdentifier *ai,		   const heim_octet_string *content,		   heim_octet_string *econtent){    hx509_clear_error_string(context);    return EINVAL;}/* * */int_hx509_pbe_decrypt(hx509_context context,		   hx509_lock lock,		   const AlgorithmIdentifier *ai,		   const heim_octet_string *econtent,		   heim_octet_string *content){    const struct _hx509_password *pw;    heim_octet_string key, iv;    const heim_oid *enc_oid;    const EVP_CIPHER *c;    const EVP_MD *md;    PBE_string2key_func s2k;    int i, ret = 0;    memset(&key, 0, sizeof(key));    memset(&iv, 0, sizeof(iv));    memset(content, 0, sizeof(*content));    enc_oid = find_string2key(&ai->algorithm, &c, &md, &s2k);    if (enc_oid == NULL) {	hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,			       "String to key algorithm not supported");	ret = HX509_ALG_NOT_SUPP;	goto out;    }    key.length = EVP_CIPHER_key_length(c);    key.data = malloc(key.length);    if (key.data == NULL) {	ret = ENOMEM;	hx509_clear_error_string(context);	goto out;    }    iv.length = EVP_CIPHER_iv_length(c);    iv.data = malloc(iv.length);    if (iv.data == NULL) {	ret = ENOMEM;	hx509_clear_error_string(context);	goto out;    }    pw = _hx509_lock_get_passwords(lock);    ret = HX509_CRYPTO_INTERNAL_ERROR;    for (i = 0; i < pw->len + 1; i++) {	hx509_crypto crypto;	const char *password;	if (i < pw->len)	    password = pw->val[i];	else if (i < pw->len + 1)	    password = "";	else	    password = NULL;	ret = (*s2k)(context, password, ai->parameters, &crypto, 		     &key, &iv, enc_oid, md);	if (ret)	    goto out;	ret = hx509_crypto_decrypt(crypto,				   econtent->data,				   econtent->length,				   &iv,				   content);	hx509_crypto_destroy(crypto);	if (ret == 0)	    goto out;				       }out:    if (key.data)	der_free_octet_string(&key);    if (iv.data)	der_free_octet_string(&iv);    return ret;}/* * */int_hx509_match_keys(hx509_cert c, hx509_private_key private_key){    const Certificate *cert;    const SubjectPublicKeyInfo *spi;    RSAPublicKey pk;    RSA *rsa;    size_t size;    int ret;    if (private_key->private_key.rsa == NULL)	return 0;    rsa = private_key->private_key.rsa;    if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL)	return 0;    cert = _hx509_get_cert(c);    spi = &cert->tbsCertificate.subjectPublicKeyInfo;    rsa = RSA_new();    if (rsa == NULL)	return 0;    ret = decode_RSAPublicKey(spi->subjectPublicKey.data,			      spi->subjectPublicKey.length / 8,			      &pk, &size);    if (ret) {	RSA_free(rsa);	return 0;    }    rsa->n = heim_int2BN(&pk.modulus);    rsa->e = heim_int2BN(&pk.publicExponent);    free_RSAPublicKey(&pk);    rsa->d = BN_dup(private_key->private_key.rsa->d);    rsa->p = BN_dup(private_key->private_key.rsa->p);    rsa->q = BN_dup(private_key->private_key.rsa->q);    rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1);    rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1);    rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp);    if (rsa->n == NULL || rsa->e == NULL || 	rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL ||	rsa->dmp1 == NULL || rsa->dmq1 == NULL) {	RSA_free(rsa);	return 0;    }    ret = RSA_check_key(rsa);    RSA_free(rsa);    return ret == 1;}static const heim_oid *find_keytype(const hx509_private_key key){    const struct signature_alg *md;    if (key == NULL)	return NULL;    md = find_sig_alg(key->signature_alg);    if (md == NULL)	return NULL;    return (*md->key_oid)();}inthx509_crypto_select(const hx509_context context,		    int type,		    const hx509_private_key source,		    hx509_peer_info peer,		    AlgorithmIdentifier *selected){    const AlgorithmIdentifier *def;    size_t i, j;    int ret, bits;    memset(selected, 0, sizeof(*selected));    if (type == HX509_SELECT_DIGEST) {	bits = SIG_DIGEST;	def = _hx509_crypto_default_digest_alg;    } else if (type == HX509_SELECT_PUBLIC_SIG) {	bits = SIG_PUBLIC_SIG;	/* XXX depend on `source

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -