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

📄 crypto.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (c) 2004 - 2007 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden).  * 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. Neither the name of the Institute nor the names of its contributors  *    may be used to endorse or promote products derived from this software  *    without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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.  */#include "hx_locl.h"RCSID("$Id: crypto.c 22435 2008-01-14 20:53:56Z lha $");struct hx509_crypto;struct signature_alg;enum crypto_op_type {    COT_SIGN};struct hx509_generate_private_context {    const heim_oid *key_oid;    int isCA;    unsigned long num_bits;};struct hx509_private_key_ops {    const char *pemtype;    const heim_oid *(*key_oid)(void);    int (*get_spki)(hx509_context,		    const hx509_private_key,		    SubjectPublicKeyInfo *);    int (*export)(hx509_context context,		  const hx509_private_key,		  heim_octet_string *);    int (*import)(hx509_context,		  const void *data,		  size_t len,		  hx509_private_key private_key);    int (*generate_private_key)(hx509_context,				struct hx509_generate_private_context *,				hx509_private_key);    BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);    int (*handle_alg)(const hx509_private_key,		      const AlgorithmIdentifier *,		      enum crypto_op_type);    int (*sign)(hx509_context context,		const hx509_private_key,		const AlgorithmIdentifier *,		const heim_octet_string *,		AlgorithmIdentifier *,		heim_octet_string *);#if 0    const AlgorithmIdentifier *(*preferred_sig_alg)	(const hx509_private_key,	 const hx509_peer_info);    int (*unwrap)(hx509_context context,		  const hx509_private_key,		  const AlgorithmIdentifier *,		  const heim_octet_string *,		  heim_octet_string *);#endif};struct hx509_private_key {    unsigned int ref;    const struct signature_alg *md;    const heim_oid *signature_alg;    union {	RSA *rsa;	void *keydata;    } private_key;    /* new crypto layer */    hx509_private_key_ops *ops;};/* * */struct signature_alg {    const char *name;    const heim_oid *(*sig_oid)(void);    const AlgorithmIdentifier *(*sig_alg)(void);    const heim_oid *(*key_oid)(void);    const heim_oid *(*digest_oid)(void);    int flags;#define PROVIDE_CONF 1#define REQUIRE_SIGNER 2#define SIG_DIGEST	0x100#define SIG_PUBLIC_SIG	0x200#define SIG_SECRET	0x400#define RA_RSA_USES_DIGEST_INFO 0x1000000    int (*verify_signature)(hx509_context context,			    const struct signature_alg *,			    const Certificate *,			    const AlgorithmIdentifier *,			    const heim_octet_string *,			    const heim_octet_string *);    int (*create_signature)(hx509_context,			    const struct signature_alg *,			    const hx509_private_key,			    const AlgorithmIdentifier *,			    const heim_octet_string *,			    AlgorithmIdentifier *,			    heim_octet_string *);};/* * */static BIGNUM *heim_int2BN(const heim_integer *i){    BIGNUM *bn;    bn = BN_bin2bn(i->data, i->length, NULL);    BN_set_negative(bn, i->negative);    return bn;}/* * */static intset_digest_alg(DigestAlgorithmIdentifier *id,	       const heim_oid *oid,	       const void *param, size_t length){    int ret;    if (param) {	id->parameters = malloc(sizeof(*id->parameters));	if (id->parameters == NULL)	    return ENOMEM;	id->parameters->data = malloc(length);	if (id->parameters->data == NULL) {	    free(id->parameters);	    id->parameters = NULL;	    return ENOMEM;	}	memcpy(id->parameters->data, param, length);	id->parameters->length = length;    } else	id->parameters = NULL;    ret = der_copy_oid(oid, &id->algorithm);    if (ret) {	if (id->parameters) {	    free(id->parameters->data);	    free(id->parameters);	    id->parameters = NULL;	}	return ret;    }    return 0;}/* * */static intrsa_verify_signature(hx509_context context,		     const struct signature_alg *sig_alg,		     const Certificate *signer,		     const AlgorithmIdentifier *alg,		     const heim_octet_string *data,		     const heim_octet_string *sig){    const SubjectPublicKeyInfo *spi;    DigestInfo di;    unsigned char *to;    int tosize, retsize;    int ret;    RSA *rsa;    RSAPublicKey pk;    size_t size;    memset(&di, 0, sizeof(di));    spi = &signer->tbsCertificate.subjectPublicKeyInfo;    rsa = RSA_new();    if (rsa == NULL) {	hx509_set_error_string(context, 0, ENOMEM, "out of memory");	return ENOMEM;    }    ret = decode_RSAPublicKey(spi->subjectPublicKey.data,			      spi->subjectPublicKey.length / 8,			      &pk, &size);    if (ret) {	hx509_set_error_string(context, 0, ret, "Failed to decode RSAPublicKey");	goto out;    }    rsa->n = heim_int2BN(&pk.modulus);    rsa->e = heim_int2BN(&pk.publicExponent);    free_RSAPublicKey(&pk);    if (rsa->n == NULL || rsa->e == NULL) {	ret = ENOMEM;	hx509_set_error_string(context, 0, ret, "out of memory");	goto out;    }    tosize = RSA_size(rsa);    to = malloc(tosize);    if (to == NULL) {	ret = ENOMEM;	hx509_set_error_string(context, 0, ret, "out of memory");	goto out;    }    retsize = RSA_public_decrypt(sig->length, (unsigned char *)sig->data, 				 to, rsa, RSA_PKCS1_PADDING);    if (retsize <= 0) {	ret = HX509_CRYPTO_SIG_INVALID_FORMAT;	hx509_set_error_string(context, 0, ret, 			       "RSA public decrypt failed: %d", retsize);	free(to);	goto out;    }    if (retsize > tosize)	_hx509_abort("internal rsa decryption failure: ret > tosize");    if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {	ret = decode_DigestInfo(to, retsize, &di, &size);	free(to);	if (ret) {	    goto out;	}		/* Check for extra data inside the sigature */	if (size != retsize) {	    ret = HX509_CRYPTO_SIG_INVALID_FORMAT;	    hx509_set_error_string(context, 0, ret, "size from decryption mismatch");	    goto out;	}		if (sig_alg->digest_oid &&	    der_heim_oid_cmp(&di.digestAlgorithm.algorithm, 			     (*sig_alg->digest_oid)()) != 0) 	{	    ret = HX509_CRYPTO_OID_MISMATCH;	    hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");	    goto out;	}		/* verify that the parameters are NULL or the NULL-type */	if (di.digestAlgorithm.parameters != NULL &&	    (di.digestAlgorithm.parameters->length != 2 ||	     memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))	{	    ret = HX509_CRYPTO_SIG_INVALID_FORMAT;	    hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");	    goto out;	}	ret = _hx509_verify_signature(context,				      NULL,				      &di.digestAlgorithm,				      data,				      &di.digest);    } else {	if (retsize != data->length ||	    memcmp(to, data->data, retsize) != 0)	{	    ret = HX509_CRYPTO_SIG_INVALID_FORMAT;	    hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");	    goto out;	}	free(to);    } out:    free_DigestInfo(&di);    RSA_free(rsa);    return ret;}static intrsa_create_signature(hx509_context context,		     const struct signature_alg *sig_alg,		     const hx509_private_key signer,		     const AlgorithmIdentifier *alg,		     const heim_octet_string *data,		     AlgorithmIdentifier *signatureAlgorithm,		     heim_octet_string *sig){    const AlgorithmIdentifier *digest_alg;    heim_octet_string indata;    const heim_oid *sig_oid;    size_t size;    int ret;        if (alg)	sig_oid = &alg->algorithm;    else	sig_oid = signer->signature_alg;    if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_sha256WithRSAEncryption()) == 0) {	digest_alg = hx509_signature_sha256();    } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_sha1WithRSAEncryption()) == 0) {	digest_alg = hx509_signature_sha1();    } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_md5WithRSAEncryption()) == 0) {	digest_alg = hx509_signature_md5();    } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_md5WithRSAEncryption()) == 0) {	digest_alg = hx509_signature_md5();    } else if (der_heim_oid_cmp(sig_oid, oid_id_dsa_with_sha1()) == 0) {	digest_alg = hx509_signature_sha1();    } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_rsaEncryption()) == 0) {	digest_alg = hx509_signature_sha1();    } else if (der_heim_oid_cmp(sig_oid, oid_id_heim_rsa_pkcs1_x509()) == 0) {	digest_alg = NULL;    } else	return HX509_ALG_NOT_SUPP;    if (signatureAlgorithm) {	ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);	if (ret) {	    hx509_clear_error_string(context);	    return ret;	}    }    if (digest_alg) {	DigestInfo di;	memset(&di, 0, sizeof(di));	ret = _hx509_create_signature(context,				      NULL,				      digest_alg,				      data,				      &di.digestAlgorithm,				      &di.digest);	if (ret)	    return ret;	ASN1_MALLOC_ENCODE(DigestInfo,			   indata.data,			   indata.length,			   &di,			   &size,			   ret);	free_DigestInfo(&di);	if (ret) {	    hx509_set_error_string(context, 0, ret, "out of memory");	    return ret;	}	if (indata.length != size)	    _hx509_abort("internal ASN.1 encoder error");    } else {	indata = *data;    }    sig->length = RSA_size(signer->private_key.rsa);    sig->data = malloc(sig->length);    if (sig->data == NULL) {	der_free_octet_string(&indata);	hx509_set_error_string(context, 0, ENOMEM, "out of memory");	return ENOMEM;    }    ret = RSA_private_encrypt(indata.length, indata.data, 			      sig->data, 			      signer->private_key.rsa,			      RSA_PKCS1_PADDING);    if (indata.data != data->data)	der_free_octet_string(&indata);    if (ret <= 0) {	ret = HX509_CMS_FAILED_CREATE_SIGATURE;	hx509_set_error_string(context, 0, ret,			       "RSA private decrypt failed: %d", ret);	return ret;    }    if (ret > sig->length)	_hx509_abort("RSA signature prelen longer the output len");    sig->length = ret;        return 0;}static intrsa_private_key_import(hx509_context context,		       const void *data,		       size_t len,		       hx509_private_key private_key){    const unsigned char *p = data;    private_key->private_key.rsa = 	d2i_RSAPrivateKey(NULL, &p, len);    if (private_key->private_key.rsa == NULL) {	hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,			       "Failed to parse RSA key");	return HX509_PARSING_KEY_FAILED;    }    private_key->signature_alg = oid_id_pkcs1_sha1WithRSAEncryption();    return 0;}static intrsa_private_key2SPKI(hx509_context context,		     hx509_private_key private_key,		     SubjectPublicKeyInfo *spki){    int len, ret;    memset(spki, 0, sizeof(*spki));    len = i2d_RSAPublicKey(private_key->private_key.rsa, NULL);    spki->subjectPublicKey.data = malloc(len);    if (spki->subjectPublicKey.data == NULL) {	hx509_set_error_string(context, 0, ENOMEM, "malloc - out of memory");	return ENOMEM;    }    spki->subjectPublicKey.length = len * 8;    ret = set_digest_alg(&spki->algorithm,oid_id_pkcs1_rsaEncryption(), 			 "\x05\x00", 2);    if (ret) {	hx509_set_error_string(context, 0, ret, "malloc - out of memory");	free(spki->subjectPublicKey.data);	spki->subjectPublicKey.data = NULL;	spki->subjectPublicKey.length = 0;	return ret;    }    {	unsigned char *pp = spki->subjectPublicKey.data;	i2d_RSAPublicKey(private_key->private_key.rsa, &pp);    }    return 0;}static intrsa_generate_private_key(hx509_context context, 			 struct hx509_generate_private_context *ctx,			 hx509_private_key private_key){    BIGNUM *e;    int ret;    unsigned long bits;    static const int default_rsa_e = 65537;    static const int default_rsa_bits = 1024;    private_key->private_key.rsa = RSA_new();    if (private_key->private_key.rsa == NULL) {	hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,			       "Failed to generate RSA key");	return HX509_PARSING_KEY_FAILED;    }        e = BN_new();    BN_set_word(e, default_rsa_e);    bits = default_rsa_bits;    if (ctx->num_bits)	bits = ctx->num_bits;    else if (ctx->isCA)	bits *= 2;    ret = RSA_generate_key_ex(private_key->private_key.rsa, bits, e, NULL);    BN_free(e);    if (ret != 1) {	hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,			       "Failed to generate RSA key");	return HX509_PARSING_KEY_FAILED;    }    private_key->signature_alg = oid_id_pkcs1_sha1WithRSAEncryption();    return 0;}static int rsa_private_key_export(hx509_context context,

⌨️ 快捷键说明

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