示例#1
0
int main(int argc, char *argv[])
{
    const EVP_MD *digest_algo = NULL;
    EVP_PKEY *pkey = NULL;
    EVP_MD_CTX *md_ctx = NULL;
    ENGINE *engine = NULL;
    unsigned char random[RANDOM_SIZE], signature[MAX_SIGSIZE];
    unsigned int siglen = MAX_SIGSIZE;

    int ret, num_processes = 2;
    pid_t pid;

    int rv = 1;

    /* Check arguments */
    if (argc < 2) {
        fprintf(stderr, "Missing required arguments\n");
        usage(argv[0]);
        goto failed;
    }

    if (argc > 4) {
        fprintf(stderr, "Too many arguments\n");
        usage(argv[0]);
        goto failed;
    }

    /* Check PKCS#11 URL */
    if (strncmp(argv[1], "pkcs11:", 7)) {
        fprintf(stderr, "fatal: invalid PKCS#11 URL\n");
        usage(argv[0]);
        goto failed;
    }

    pid = getpid();
    printf("pid %d is the parent\n", pid);

    /* Load configuration file, if provided */
    if (argc >= 3) {
        ret = CONF_modules_load_file(argv[2], "engines", 0);
        if (ret <= 0) {
            fprintf(stderr, "cannot load %s\n", argv[2]);
            error_queue("CONF_modules_load_file", pid);
            goto failed;
        }
        ENGINE_add_conf_module();
    }

    ENGINE_add_conf_module();
#if OPENSSL_VERSION_NUMBER>=0x10100000
	OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
		| OPENSSL_INIT_ADD_ALL_DIGESTS \
		| OPENSSL_INIT_LOAD_CONFIG, NULL);
#else
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();
#endif
    ERR_clear_error();
    ENGINE_load_builtin_engines();

    /* Get structural reference */
    engine = ENGINE_by_id("pkcs11");
    if (engine == NULL) {
        fprintf(stderr, "fatal: engine \"pkcs11\" not available\n");
        error_queue("ENGINE_by_id", pid);
        goto failed;
    }

    /* Set the used  */
    if (argc >= 4) {
        ENGINE_ctrl_cmd(engine, "MODULE_PATH", 0, argv[3], NULL, 1);
    }

    /* Initialize to get the engine functional reference */
    if (ENGINE_init(engine)) {
        pkey = ENGINE_load_private_key(engine, argv[1], 0, 0);
        if (pkey == NULL) {
            error_queue("ENGINE_load_private_key", pid);
            goto failed;
        }

        ENGINE_free(engine);
        engine = NULL;
    }
    else {
        error_queue("ENGINE_init", pid);
        goto failed;
    }

    /* Spawn processes and check child return */
    if (spawn_processes(num_processes)) {
        goto failed;
    }
    pid = getpid();

    /* Generate random data */
    if (!RAND_bytes(random, RANDOM_SIZE)){
        error_queue("RAND_bytes", pid);
        goto failed;
    }

    /* Create context to sign the random data */
    digest_algo = EVP_get_digestbyname("sha256");
    md_ctx = EVP_MD_CTX_create();
    if (EVP_DigestInit(md_ctx, digest_algo) <= 0) {
        error_queue("EVP_DigestInit", pid);
        goto failed;
    }

    EVP_SignInit(md_ctx, digest_algo);
    if (EVP_SignUpdate(md_ctx, random, RANDOM_SIZE) <= 0) {
        error_queue("EVP_SignUpdate", pid);
        goto failed;
    }

    if (EVP_SignFinal(md_ctx, signature, &siglen, pkey) <= 0) {
        error_queue("EVP_SignFinal", pid);
        goto failed;
    }
    EVP_MD_CTX_destroy(md_ctx);

    printf("pid %d: %u-byte signature created\n", pid, siglen);

    /* Now verify the result */
    md_ctx = EVP_MD_CTX_create();
    if (EVP_DigestInit(md_ctx, digest_algo) <= 0) {
        error_queue("EVP_DigestInit", pid);
        goto failed;
    }

    EVP_VerifyInit(md_ctx, digest_algo);
    if (EVP_VerifyUpdate(md_ctx, random, RANDOM_SIZE) <= 0) {
        error_queue("EVP_VerifyUpdate", pid);
        goto failed;
    }

    if (EVP_VerifyFinal(md_ctx, signature, siglen, pkey) <= 0) {
        error_queue("EVP_VerifyFinal", pid);
        goto failed;
    }
    printf("pid %d: Signature matched\n", pid);

    rv = 0;

failed:
    if (md_ctx != NULL)
        EVP_MD_CTX_destroy(md_ctx);
    if (pkey != NULL)
        EVP_PKEY_free(pkey);
    if (engine != NULL)
        ENGINE_free(engine);

    return rv;
}
示例#2
0
int main(int argc, char **argv) {
	EVP_MD_CTX ctx;
	char buf[1024];
	char cpbuf[1024];
	FILE *cpf;
	int num;
	int r;
	unsigned int signum, nsignum;
	unsigned int inlen = 0;
	EVP_PKEY *pkey;
	FILE *f;
	if(argc != 4) {
		printf("Usage: %s <InFile> <OutFile> <KeyFile>\n", argv[0]);
		return 1;
	}
	SSL_load_error_strings();
	f = fopen(argv[1], "r");
	if(!f) {
		printf("Could not open input file.\n");
		return 1;
	}
	EVP_SignInit(&ctx, EVP_dss1());
	while(num = fread(buf, 1, 1024, f)) {
		inlen += num;
		r = EVP_SignUpdate(&ctx, buf, num);
		if(!r) {
			printf("Error updating signature.\n");
			return 1;
		}
	}
	fclose(f);
	f = fopen(argv[3], "r");
	if(!f) {
		printf("Could not open key file.\n");
		return 1;
	}
	pkey = NULL;
	pkey = PEM_read_PrivateKey(f, &pkey, NULL, NULL);
	if(!pkey) {
		printf("Error reading private key.\n");
		return 1;
	}
	fclose(f);
	printf("Private key size: %d\n", EVP_PKEY_size(pkey));
	r = EVP_SignFinal(&ctx, buf, &signum, pkey);
	if(!r) {
		printf("Error creating signature: %s\n", ERR_error_string(ERR_get_error(), NULL));
		return 1;
	}
	EVP_PKEY_free(pkey);
	f = fopen(argv[2], "w");
	if(!f) {
		printf("Could not open output file.\n");
		return 1;
	}
	nsignum = htonl(signum);
	cpf = fopen(argv[1], "r");
	if(!cpf) {
		printf("Could not open input file.\n");
		return 1;
	}
	inlen = htonl(inlen);
	fwrite(&inlen, sizeof(inlen), 1, f);
	while(num = fread(cpbuf, 1, 1024, cpf)) {
		fwrite(cpbuf, 1, num, f);
	}
	fclose(cpf);
	fwrite(&nsignum, sizeof(nsignum), 1, f);
	fwrite(buf, 1, signum, f);
	fclose(f);
	EVP_MD_CTX_cleanup(&ctx);
	return 0;
}
示例#3
0
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
	     ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
	     const EVP_MD *type)
	{
	EVP_MD_CTX ctx;
	unsigned char *buf_in=NULL,*buf_out=NULL;
	int inl=0,outl=0,outll=0;
	int signid, paramtype;

	if (type == NULL)
		{
		int def_nid;
		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
			type = EVP_get_digestbynid(def_nid);
		}

	if (type == NULL)
		{
		ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_NO_DEFAULT_DIGEST);
		return 0;
		}

	if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
		{
		if (!pkey->ameth ||
			!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type),
						pkey->ameth->pkey_id))
			{
			ASN1err(ASN1_F_ASN1_ITEM_SIGN,
				ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
			return 0;
			}
		}
	else
		signid = type->pkey_type;

	if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
		paramtype = V_ASN1_NULL;
	else
		paramtype = V_ASN1_UNDEF;

	if (algor1)
		X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
	if (algor2)
		X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);

	EVP_MD_CTX_init(&ctx);
	inl=ASN1_item_i2d(asn,&buf_in, it);
	outll=outl=EVP_PKEY_size(pkey);
	buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
	if ((buf_in == NULL) || (buf_out == NULL))
		{
		outl=0;
		ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (!EVP_SignInit_ex(&ctx,type, NULL)
		|| !EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl)
		|| !EVP_SignFinal(&ctx,(unsigned char *)buf_out,
			(unsigned int *)&outl,pkey))
		{
		outl=0;
		ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB);
		goto err;
		}
	if (signature->data != NULL) OPENSSL_free(signature->data);
	signature->data=buf_out;
	buf_out=NULL;
	signature->length=outl;
	/* In the interests of compatibility, I'll make sure that
	 * the bit string has a 'not-used bits' value of 0
	 */
	signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
	signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
err:
	EVP_MD_CTX_cleanup(&ctx);
	if (buf_in != NULL)
		{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
	if (buf_out != NULL)
		{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
	return(outl);
	}
示例#4
0
int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2,
              ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
              const EVP_MD *type)
{
    EVP_MD_CTX ctx;
    unsigned char *p,*buf_in=NULL,*buf_out=NULL;
    int i,inl=0,outl=0,outll=0;
    X509_ALGOR *a;

    for (i=0; i<2; i++)
    {
        if (i == 0)
            a=algor1;
        else
            a=algor2;
        if (a == NULL) continue;
        if (	(a->parameter == NULL) ||
                (a->parameter->type != V_ASN1_NULL))
        {
            ASN1_TYPE_free(a->parameter);
            if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
            a->parameter->type=V_ASN1_NULL;
        }
        ASN1_OBJECT_free(a->algorithm);
        a->algorithm=OBJ_nid2obj(type->pkey_type);
        if (a->algorithm == NULL)
        {
            ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE);
            goto err;
        }
        if (a->algorithm->length == 0)
        {
            ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
            goto err;
        }
    }
    inl=i2d(data,NULL);
    buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
    outll=outl=EVP_PKEY_size(pkey);
    buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
    if ((buf_in == NULL) || (buf_out == NULL))
    {
        outl=0;
        ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE);
        goto err;
    }
    p=buf_in;

    i2d(data,&p);
    EVP_SignInit(&ctx,type);
    EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
    if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
                       (unsigned int *)&outl,pkey))
    {
        outl=0;
        ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB);
        goto err;
    }
    if (signature->data != NULL) OPENSSL_free(signature->data);
    signature->data=buf_out;
    buf_out=NULL;
    signature->length=outl;
    /* In the interests of compatibility, I'll make sure that
     * the bit string has a 'not-used bits' value of 0
     */
    signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
    signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
err:
    memset(&ctx,0,sizeof(ctx));
    if (buf_in != NULL)
    {
        memset((char *)buf_in,0,(unsigned int)inl);
        OPENSSL_free(buf_in);
    }
    if (buf_out != NULL)
    {
        memset((char *)buf_out,0,outll);
        OPENSSL_free(buf_out);
    }
    return(outl);
}
int FIPS_selftest_dsa()
    {
    DSA *dsa=NULL;
    int counter,i,j, ret = 0;
    unsigned int slen;
    unsigned char buf[256];
    unsigned long h;
    EVP_MD_CTX mctx;
    EVP_PKEY pk;

    EVP_MD_CTX_init(&mctx);

    dsa = FIPS_dsa_new();

    if(dsa == NULL)
	goto err;
    if(!DSA_generate_parameters_ex(dsa, 1024,seed,20,&counter,&h,NULL))
	goto err;
    if (counter != 378) 
	goto err;
    if (h != 2)
	goto err;
    i=BN_bn2bin(dsa->q,buf);
    j=sizeof(out_q);
    if (i != j || memcmp(buf,out_q,i) != 0)
	goto err;

    i=BN_bn2bin(dsa->p,buf);
    j=sizeof(out_p);
    if (i != j || memcmp(buf,out_p,i) != 0)
	goto err;

    i=BN_bn2bin(dsa->g,buf);
    j=sizeof(out_g);
    if (i != j || memcmp(buf,out_g,i) != 0)
	goto err;
    DSA_generate_key(dsa);
    pk.type = EVP_PKEY_DSA;
    pk.pkey.dsa = dsa;

    if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
	goto err;
    if (!EVP_SignUpdate(&mctx, str1, 20))
	goto err;
    if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
	goto err;

    if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
	goto err;
    if (!EVP_VerifyUpdate(&mctx, str1, 20))
	goto err;
    if (EVP_VerifyFinal(&mctx, buf, slen, &pk) != 1)
	goto err;

    ret = 1;

    err:
    EVP_MD_CTX_cleanup(&mctx);
    if (dsa)
	FIPS_dsa_free(dsa);
    if (ret == 0)
	    FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
    return ret;
    }
示例#6
0
static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo,
		const struct image_region region[], int region_count,
		uint8_t **sigp, uint *sig_size)
{
	EVP_PKEY *key;
	EVP_MD_CTX *context;
	int size, ret = 0;
	uint8_t *sig;
	int i;

	key = EVP_PKEY_new();
	if (!key)
		return rsa_err("EVP_PKEY object creation failed");

	if (!EVP_PKEY_set1_RSA(key, rsa)) {
		ret = rsa_err("EVP key setup failed");
		goto err_set;
	}

	size = EVP_PKEY_size(key);
	sig = malloc(size);
	if (!sig) {
		fprintf(stderr, "Out of memory for signature (%d bytes)\n",
			size);
		ret = -ENOMEM;
		goto err_alloc;
	}

	context = EVP_MD_CTX_create();
	if (!context) {
		ret = rsa_err("EVP context creation failed");
		goto err_create;
	}
	EVP_MD_CTX_init(context);
	if (!EVP_SignInit(context, checksum_algo->calculate_sign())) {
		ret = rsa_err("Signer setup failed");
		goto err_sign;
	}

	for (i = 0; i < region_count; i++) {
		if (!EVP_SignUpdate(context, region[i].data, region[i].size)) {
			ret = rsa_err("Signing data failed");
			goto err_sign;
		}
	}

	if (!EVP_SignFinal(context, sig, sig_size, key)) {
		ret = rsa_err("Could not obtain signature");
		goto err_sign;
	}
	EVP_MD_CTX_cleanup(context);
	EVP_MD_CTX_destroy(context);
	EVP_PKEY_free(key);

	debug("Got signature: %d bytes, expected %d\n", *sig_size, size);
	*sigp = sig;
	*sig_size = size;

	return 0;

err_sign:
	EVP_MD_CTX_destroy(context);
err_create:
	free(sig);
err_alloc:
err_set:
	EVP_PKEY_free(key);
	return ret;
}
示例#7
0
/* adds a Identity header field to msg
return value: 1: success
			0: else
*/
static int addIdentity(char * dateHF, struct sip_msg * msg)
{
	#define IDENTITY_HDR_S  "Identity: \""
	#define IDENTITY_HDR_L  (sizeof(IDENTITY_HDR_S)-1)
	EVP_MD_CTX ctx;
	unsigned int siglen = 0;
	int b64len = 0;
	unsigned char * sig = NULL;
	char digestString[MAX_DIGEST];
	str buf;

	if(!makeDigestString(digestString, dateHF, msg))
	{
		LM_ERR("error making digest string\n");
		return 0;
	}

	EVP_SignInit(&ctx, EVP_sha1());

	EVP_SignUpdate(&ctx, digestString, strlen(digestString));

	sig = pkg_malloc(EVP_PKEY_size(privKey_evp));
	if(!sig)
	{
		EVP_MD_CTX_cleanup(&ctx);
		LM_ERR("failed allocating memory\n");
		return 0;
	}

	if(!EVP_SignFinal(&ctx, sig, &siglen, privKey_evp))
	{
		EVP_MD_CTX_cleanup(&ctx);
		pkg_free(sig);
		LM_ERR("error calculating signature\n");
		return 0;
	}
	EVP_MD_CTX_cleanup(&ctx);

	/* ###Base64-encoding### */
	/* annotation: The next few lines are based on example 7-11 of [VIE-02] */
	b64len = (((siglen + 2) / 3) * 4) + 1;
	buf.len = IDENTITY_HDR_L + b64len + 1 + CRLF_LEN;
	buf.s = pkg_malloc(buf.len);
	if(!buf.s)
	{
		pkg_free(sig);
		LM_ERR("error allocating memory\n");
		return 0;
	}
	memcpy( buf.s, IDENTITY_HDR_S, IDENTITY_HDR_L);
	EVP_EncodeBlock((unsigned char*)(buf.s+IDENTITY_HDR_L), sig, siglen);
	memcpy( buf.s+IDENTITY_HDR_L+b64len, "\""CRLF, CRLF_LEN+1);

	pkg_free(sig);

	if ( id_add_header( msg, buf.s, buf.len )!=0) {
		pkg_free(buf.s);
		LM_ERR("failed to add Identity header\n");
		return 0;
	}

	return 1;
}
示例#8
0
/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
int
ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
    const u_char *data, u_int datalen)
{
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	u_char *sig = NULL;
	u_int slen = 0, len;
#ifdef USE_LEGACY_RSA_SIGN
	u_char digest[EVP_MAX_MD_SIZE];
	u_int dlen;
#endif
	int ok, nid;
	Buffer b;

	if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA &&
	    key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) {
		error("ssh_rsa_sign: no RSA key");
		return -1;
	}
	nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
		error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid);
		return -1;
	}

#ifdef USE_LEGACY_RSA_SIGN
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	slen = RSA_size(key->rsa);
	sig = xmalloc(slen);

	ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa);
	memset(digest, 'd', sizeof(digest));
#else /*ndef USE_LEGACY_RSA_SIGN*/
{
	EVP_PKEY *pkey = NULL;

	ok = -1;
	pkey = EVP_PKEY_new();
	if (pkey == NULL) {
		error("%s: out of memory", __func__);
		goto done;
	}

	EVP_PKEY_set1_RSA(pkey, key->rsa);

	slen = EVP_PKEY_size(pkey);
	sig = xmalloc(slen);	/*fatal on error*/

	ssh_EVP_MD_CTX_init(&md);
	
	ok = ssh_EVP_SignInit_ex(&md, evp_md, NULL);
	if (ok <= 0) {
		char ebuf[256];
		error("%s: EVP_SignInit_ex fail with errormsg='%.*s'"
		, __func__
		, (int)sizeof(ebuf), openssl_errormsg(ebuf, sizeof(ebuf)));
		goto clean;
	}

	ok = ssh_EVP_SignUpdate(&md, data, datalen);
	if (ok <= 0) {
		char ebuf[256];
		error("%s: EVP_SignUpdate fail with errormsg='%.*s'"
		, __func__
		, (int)sizeof(ebuf), openssl_errormsg(ebuf, sizeof(ebuf)));
		goto clean;
	}

	ok = EVP_SignFinal(&md, sig, &len, pkey);
	if (ok <= 0) {
		char ebuf[256];
		error("%s: SignFinal fail with errormsg='%.*s'"
		, __func__
		, (int)sizeof(ebuf), openssl_errormsg(ebuf, sizeof(ebuf)));
		goto clean;
	}

clean:
	ssh_EVP_MD_CTX_cleanup(&md);

done:
	if (pkey != NULL) EVP_PKEY_free(pkey);
}
#endif /*ndef USE_LEGACY_RSA_SIGN*/

	if (ok <= 0) {
	#ifdef USE_LEGACY_RSA_SIGN
		int ecode = ERR_get_error();

		error("ssh_rsa_sign: RSA_sign failed: %s",
		    ERR_error_string(ecode, NULL));
	#endif /*def USE_LEGACY_RSA_SIGN*/
		xfree(sig);
		return -1;
	}
	if (len < slen) {
		u_int diff = slen - len;
		debug("slen %u > len %u", slen, len);
		memmove(sig + diff, sig, len);
		memset(sig, 0, diff);
	} else if (len > slen) {
		error("ssh_rsa_sign: slen %u slen2 %u", slen, len);
		xfree(sig);
		return -1;
	}
	/* encode signature */
	buffer_init(&b);
	buffer_put_cstring(&b, "ssh-rsa");
	buffer_put_string(&b, sig, slen);
	len = buffer_len(&b);
	if (lenp != NULL)
		*lenp = len;
	if (sigp != NULL) {
		*sigp = xmalloc(len);
		memcpy(*sigp, buffer_ptr(&b), len);
	}
	buffer_free(&b);
	memset(sig, 's', slen);
	xfree(sig);

	return 0;
}
示例#9
0
static isc_result_t
opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
	dst_key_t *key = dctx->key;
	isc_region_t r;
	unsigned int siglen = 0;
#if USE_EVP
	EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
	EVP_PKEY *pkey = key->keydata.pkey;
#else
	RSA *rsa = key->keydata.rsa;
	/* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
	unsigned char digest[PREFIXLEN + ISC_SHA512_DIGESTLENGTH];
	int status;
	int type = 0;
	unsigned int digestlen = 0;
#if OPENSSL_VERSION_NUMBER < 0x00908000L
	unsigned int prefixlen = 0;
	const unsigned char *prefix = NULL;
#endif
#endif

	REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
		dctx->key->key_alg == DST_ALG_RSASHA1 ||
		dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
		dctx->key->key_alg == DST_ALG_RSASHA256 ||
		dctx->key->key_alg == DST_ALG_RSASHA512);

	isc_buffer_availableregion(sig, &r);

#if USE_EVP
	if (r.length < (unsigned int) EVP_PKEY_size(pkey))
		return (ISC_R_NOSPACE);

	if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) {
		return (dst__openssl_toresult3(dctx->category,
					       "EVP_SignFinal",
					       ISC_R_FAILURE));
	}
#else
	if (r.length < (unsigned int) RSA_size(rsa))
		return (ISC_R_NOSPACE);

	switch (dctx->key->key_alg) {
	case DST_ALG_RSAMD5:
		{
			isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;

			isc_md5_final(md5ctx, digest);
			type = NID_md5;
			digestlen = ISC_MD5_DIGESTLENGTH;
		}
		break;
	case DST_ALG_RSASHA1:
	case DST_ALG_NSEC3RSASHA1:
		{
			isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;

			isc_sha1_final(sha1ctx, digest);
			type = NID_sha1;
			digestlen = ISC_SHA1_DIGESTLENGTH;
		}
		break;
	case DST_ALG_RSASHA256:
		{
			isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;

			isc_sha256_final(digest, sha256ctx);
			digestlen = ISC_SHA256_DIGESTLENGTH;
#if OPENSSL_VERSION_NUMBER < 0x00908000L
			prefix = sha256_prefix;
			prefixlen = sizeof(sha256_prefix);
#else
			type = NID_sha256;
#endif
		}
		break;
	case DST_ALG_RSASHA512:
		{
			isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;

			isc_sha512_final(digest, sha512ctx);
			digestlen = ISC_SHA512_DIGESTLENGTH;
#if OPENSSL_VERSION_NUMBER < 0x00908000L
			prefix = sha512_prefix;
			prefixlen = sizeof(sha512_prefix);
#else
			type = NID_sha512;
#endif
		}
		break;
	default:
		INSIST(0);
	}

#if OPENSSL_VERSION_NUMBER < 0x00908000L
	switch (dctx->key->key_alg) {
	case DST_ALG_RSAMD5:
	case DST_ALG_RSASHA1:
	case DST_ALG_NSEC3RSASHA1:
		INSIST(type != 0);
		status = RSA_sign(type, digest, digestlen, r.base,
				  &siglen, rsa);
		break;

	case DST_ALG_RSASHA256:
	case DST_ALG_RSASHA512:
		INSIST(prefix != NULL);
		INSIST(prefixlen != 0);
		INSIST(prefixlen + digestlen <= sizeof(digest));

		memmove(digest + prefixlen, digest, digestlen);
		memcpy(digest, prefix, prefixlen);
		status = RSA_private_encrypt(digestlen + prefixlen,
					     digest, r.base, rsa,
					     RSA_PKCS1_PADDING);
		if (status < 0)
			status = 0;
		else
			siglen = status;
		break;

	default:
		INSIST(0);
	}
#else
	INSIST(type != 0);
	status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa);
#endif
	if (status == 0)
		return (dst__openssl_toresult3(dctx->category,
					       "RSA_sign",
					       DST_R_OPENSSLFAILURE));
#endif

	isc_buffer_add(sig, siglen);

	return (ISC_R_SUCCESS);
}
示例#10
0
/**
 * Esta función se encargará de producir, lo que para el SAT[1], es un sello
 * digital. Este sello digital consiste en el firmado digital del hash de un
 * string, que para los casos de un CFDi se trataría de la cadena original
 *
 * El usuario es responsable de liberar la memoria del resultado (con free())
 * [1]: http://www.sat.gob.mx
 */
unsigned char *
sello_alloc(const char *keyfile, const char *digest, const unsigned char *cadena, const int verbose)
{
  int read = 0;
  int len = 0;
  unsigned char *buffer = NULL;
  const unsigned char *tmp;
  unsigned char signbuffer[1024];
  unsigned int signlen = 0;
  char *data = NULL;
  FILE *file = NULL;
  BIO* err = NULL;
  EVP_MD_CTX mdctx;
  EVP_PKEY *privateKey = NULL;

  file = fopen(keyfile, "rb");
  if ( file == NULL ) {
    /* An error ocurred */
    if ( verbose ) {
      fprintf(stderr, "No fue posible leer correctamente el archivo %s.\n", keyfile);
    }
    return NULL;
  }
  len = fseek(file, 0, SEEK_END);
  if ( len ) {
    /* An error did occur */
    if ( verbose ) {
      fprintf(stderr, "No fue posible obtener el final del archivo %s.\n", keyfile);
    }
    fclose(file);
    return NULL;
  }
  len = ftell(file);
  rewind(file);


  buffer = (unsigned char *)calloc(len + 1, sizeof(unsigned char));
  read = fread(buffer, sizeof(unsigned char), len, file);
  fclose(file);
  if ( read != len ) {
    if ( verbose ) {
      fprintf(stderr, "An error has ocurred. The number of items read was %d, but it should be %d instead.\n", read, len);
      free(buffer);
    }
    return NULL;
  }

  /* Set the BIO method for the error messages */
  if ( err == NULL ) {
    if ( (err = BIO_new(BIO_s_file())) ) {
      BIO_set_fp(err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
    }
  }

  /* Now convert the bytes to a EVP_PKEY structure */
  tmp = buffer;
  privateKey = d2i_AutoPrivateKey(NULL, &tmp, len);
  if ( privateKey == NULL ) {
    if ( verbose ) {
      BIO_printf(err, "Error at reading the private key on %s.\n", keyfile);
      ERR_print_errors(err);
    }
    free(buffer);
    return NULL;
  }
  free(buffer);

  /* Add all digest algorithms to the table */
  OpenSSL_add_all_digests();

  /* Initialize the digest context */
  EVP_MD_CTX_init(&mdctx);
  if ( EVP_DigestInit_ex(&mdctx, EVP_get_digestbyname(digest), 0 ) == 0 ) {
    if ( verbose ) {
      BIO_printf(err, "Error at initializing the digest context to use '%s' as digest algorithm.\n", digest);
      ERR_print_errors(err);
    }
    EVP_PKEY_free(privateKey);
    EVP_cleanup();
    BIO_free(err);
    return NULL;
  }

  /* Sign up the data in the current context */
  if ( EVP_SignInit_ex(&mdctx, EVP_get_digestbyname(digest), 0) == 0 ) {
    if ( verbose ) {
      BIO_printf(err, "Error at setting up the signing context to use digest '%s'.\n", digest);
      ERR_print_errors(err);
    }
    EVP_PKEY_free(privateKey);
    EVP_cleanup();
    BIO_free(err);
    return NULL;
  }
  if ( EVP_SignUpdate(&mdctx, cadena, strlen((char *)cadena)) == 0 ) {
    if ( verbose ) {
      BIO_printf(err, "Error hashing the data into the signing context.\n");
      ERR_print_errors(err);
    }
    EVP_PKEY_free(privateKey);
    EVP_cleanup();
    BIO_free(err);
    return NULL;
  }

  signlen = sizeof(signbuffer);
  memset(signbuffer, 0, 1024);
  if ( EVP_SignFinal(&mdctx, signbuffer, (unsigned int* )&signlen, privateKey) == 0 ) {
    if ( verbose ) {
      BIO_printf(err, "Error signing the data in the context with the private key.\n");
      ERR_print_errors(err);
    }
    EVP_PKEY_free(privateKey);
    EVP_cleanup();
    BIO_free(err);
    return NULL;
  }

  EVP_MD_CTX_cleanup(&mdctx);
  EVP_PKEY_free(privateKey);
  EVP_cleanup();
  BIO_free(err);

  /* Now prepare the data to be base64 encoded */
  base64_encode_alloc((const char *)signbuffer, signlen, &data);

  return (unsigned char *)data;
}
示例#11
0
ldns_rdf *
ldns_sign_public_evp(ldns_buffer *to_sign,
				 EVP_PKEY *key,
				 const EVP_MD *digest_type)
{
	unsigned int siglen;
	ldns_rdf *sigdata_rdf;
	ldns_buffer *b64sig;
	EVP_MD_CTX ctx;
	const EVP_MD *md_type;
	int r;

	siglen = 0;
	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
	if (!b64sig) {
		return NULL;
	}

	/* initializes a signing context */
	md_type = digest_type;
	if(!md_type) {
		/* unknown message difest */
		ldns_buffer_free(b64sig);
		return NULL;
	}

	EVP_MD_CTX_init(&ctx);
	r = EVP_SignInit(&ctx, md_type);
	if(r == 1) {
		r = EVP_SignUpdate(&ctx, (unsigned char*)
					    ldns_buffer_begin(to_sign),
					    ldns_buffer_position(to_sign));
	} else {
		ldns_buffer_free(b64sig);
		return NULL;
	}
	if(r == 1) {
		r = EVP_SignFinal(&ctx, (unsigned char*)
					   ldns_buffer_begin(b64sig), &siglen, key);
	} else {
		ldns_buffer_free(b64sig);
		return NULL;
	}
	if(r != 1) {
		ldns_buffer_free(b64sig);
		return NULL;
	}

	/* unfortunately, OpenSSL output is differenct from DNS DSA format */
#ifndef S_SPLINT_S
	if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
		sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
#ifdef USE_ECDSA
        } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC &&
                ldns_pkey_is_ecdsa(key)) {
                sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen);
#endif
	} else {
		/* ok output for other types is the same */
		sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
									 ldns_buffer_begin(b64sig));
	}
#endif /* splint */
	ldns_buffer_free(b64sig);
	EVP_MD_CTX_cleanup(&ctx);
	return sigdata_rdf;
}
示例#12
0
static int
xmlSecOpenSSLEvpSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
    xmlSecOpenSSLEvpSignatureCtxPtr ctx;
    xmlSecBufferPtr in, out;
    xmlSecSize inSize;
    xmlSecSize outSize;
    int ret;

    xmlSecAssert2(xmlSecOpenSSLEvpSignatureCheckId(transform), -1);
    xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpSignatureSize), -1);
    xmlSecAssert2(transformCtx != NULL, -1);

    ctx = xmlSecOpenSSLEvpSignatureGetCtx(transform);
    xmlSecAssert2(ctx != NULL, -1);

    in = &(transform->inBuf);
    out = &(transform->outBuf);
    inSize = xmlSecBufferGetSize(in);
    outSize = xmlSecBufferGetSize(out);

    ctx = xmlSecOpenSSLEvpSignatureGetCtx(transform);
    xmlSecAssert2(ctx != NULL, -1);
    xmlSecAssert2(ctx->digest != NULL, -1);
    xmlSecAssert2(ctx->pKey != NULL, -1);

    if(transform->status == xmlSecTransformStatusNone) {
        xmlSecAssert2(outSize == 0, -1);

        if(transform->operation == xmlSecTransformOperationSign) {
#ifndef XMLSEC_OPENSSL_096
            ret = EVP_SignInit(&(ctx->digestCtx), ctx->digest);
            if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "EVP_SignInit",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(-1);
            }
#else /* XMLSEC_OPENSSL_096 */
            EVP_SignInit(&(ctx->digestCtx), ctx->digest);
#endif /* XMLSEC_OPENSSL_096 */
        } else {
#ifndef XMLSEC_OPENSSL_096
            ret = EVP_VerifyInit(&(ctx->digestCtx), ctx->digest);
            if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "EVP_VerifyInit",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(-1);
            }
#else /* XMLSEC_OPENSSL_096 */
            EVP_VerifyInit(&(ctx->digestCtx), ctx->digest);
#endif /* XMLSEC_OPENSSL_096 */
        }
        transform->status = xmlSecTransformStatusWorking;
    }

    if((transform->status == xmlSecTransformStatusWorking) && (inSize > 0)) {
        xmlSecAssert2(outSize == 0, -1);

        if(transform->operation == xmlSecTransformOperationSign) {
#ifndef XMLSEC_OPENSSL_096
            ret = EVP_SignUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize);
            if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "EVP_SignUpdate",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(-1);
            }
#else /* XMLSEC_OPENSSL_096 */
            EVP_SignUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize);
#endif /* XMLSEC_OPENSSL_096 */
        } else {
#ifndef XMLSEC_OPENSSL_096
            ret = EVP_VerifyUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize);
            if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "EVP_VerifyUpdate",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(-1);
            }
#else /* XMLSEC_OPENSSL_096 */
            EVP_VerifyUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize);
#endif /* XMLSEC_OPENSSL_096 */
        }

        ret = xmlSecBufferRemoveHead(in, inSize);
        if(ret < 0) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                        "xmlSecBufferRemoveHead",
                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
                        XMLSEC_ERRORS_NO_MESSAGE);
            return(-1);
        }
    }

    if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) {
        xmlSecAssert2(outSize == 0, -1);
        if(transform->operation == xmlSecTransformOperationSign) {
            unsigned int signSize;

            /* this is a hack: for rsa signatures
             * we get size from EVP_PKEY_size(),
             * for dsa signature we use a fixed constant */
            signSize = EVP_PKEY_size(ctx->pKey);
#ifndef XMLSEC_NO_DSA
            if(signSize < XMLSEC_OPENSSL_DSA_SIGNATURE_SIZE) {
                signSize = XMLSEC_OPENSSL_DSA_SIGNATURE_SIZE;
            }
#endif /* XMLSEC_NO_DSA */

            ret = xmlSecBufferSetMaxSize(out, signSize);
            if(ret < 0) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "xmlSecBufferSetMaxSize",
                            XMLSEC_ERRORS_R_XMLSEC_FAILED,
                            "size=%u", signSize);
                return(-1);
            }

            ret = EVP_SignFinal(&(ctx->digestCtx), xmlSecBufferGetData(out), &signSize, ctx->pKey);
            if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "EVP_SignFinal",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(-1);
            }

            ret = xmlSecBufferSetSize(out, signSize);
            if(ret < 0) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "xmlSecBufferSetSize",
                            XMLSEC_ERRORS_R_XMLSEC_FAILED,
                            "size=%u", signSize);
                return(-1);
            }
        }
        transform->status = xmlSecTransformStatusFinished;
    }

    if((transform->status == xmlSecTransformStatusWorking) || (transform->status == xmlSecTransformStatusFinished)) {
        /* the only way we can get here is if there is no input */
        xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
    } else {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                    NULL,
                    XMLSEC_ERRORS_R_INVALID_STATUS,
                    "status=%d", transform->status);
        return(-1);
    }

    return(0);
}
示例#13
0
int main(int argc, char **argv)
	{
	DSA *dsa=NULL;
	EVP_PKEY pk;
	int counter,ret=0,i,j;
	unsigned int slen;
	unsigned char buf[256];
	unsigned long h;
	BN_GENCB cb;
	EVP_MD_CTX mctx;
	BN_GENCB_set(&cb, dsa_cb, stderr);
	EVP_MD_CTX_init(&mctx);

	if(!FIPS_mode_set(1))
	    {
	    do_print_errors();
	    EXIT(1);
	    }

	fprintf(stderr,"test generation of DSA parameters\n");

	dsa = FIPS_dsa_new();
	DSA_generate_parameters_ex(dsa, 1024,seed,20,&counter,&h,&cb);

	fprintf(stderr,"seed\n");
	for (i=0; i<20; i+=4)
		{
		fprintf(stderr,"%02X%02X%02X%02X ",
			seed[i],seed[i+1],seed[i+2],seed[i+3]);
		}
	fprintf(stderr,"\ncounter=%d h=%ld\n",counter,h);

	if (dsa == NULL) goto end;
	if (counter != 16) 
		{
		fprintf(stderr,"counter should be 105\n");
		goto end;
		}
	if (h != 2)
		{
		fprintf(stderr,"h should be 2\n");
		goto end;
		}

	i=BN_bn2bin(dsa->q,buf);
	j=sizeof(out_q);
	if ((i != j) || (memcmp(buf,out_q,i) != 0))
		{
		fprintf(stderr,"q value is wrong\n");
		goto end;
		}

	i=BN_bn2bin(dsa->p,buf);
	j=sizeof(out_p);
	if ((i != j) || (memcmp(buf,out_p,i) != 0))
		{
		fprintf(stderr,"p value is wrong\n");
		goto end;
		}

	i=BN_bn2bin(dsa->g,buf);
	j=sizeof(out_g);
	if ((i != j) || (memcmp(buf,out_g,i) != 0))
		{
		fprintf(stderr,"g value is wrong\n");
		goto end;
		}
	DSA_generate_key(dsa);
	pk.type = EVP_PKEY_DSA;
	pk.pkey.dsa = dsa;

	if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
		goto end;
	if (!EVP_SignUpdate(&mctx, str1, 20))
		goto end;
	if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
		goto end;

	if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
		goto end;
	if (!EVP_VerifyUpdate(&mctx, str1, 20))
		goto end;
	if (EVP_VerifyFinal(&mctx, buf, slen, &pk) != 1)
		goto end;

	ret = 1;

end:
	if (!ret)
		do_print_errors();
	if (dsa != NULL) FIPS_dsa_free(dsa);
	EVP_MD_CTX_cleanup(&mctx);
#if 0
	CRYPTO_mem_leaks(bio_err);
#endif
	EXIT(!ret);
	return(!ret);
	}
示例#14
0
文件: sign.c 项目: 274914765/C
int main ()
{
    int err;

    int sig_len;

    unsigned char sig_buf[4096];

    static char certfile[] = "cert.pem";

    static char keyfile[] = "key.pem";

    static char data[] = "I owe you...";

    EVP_MD_CTX md_ctx;

    EVP_PKEY *pkey;

    FILE *fp;

    X509 *x509;

    /* Just load the crypto library error strings,
     * SSL_load_error_strings() loads the crypto AND the SSL ones */
    /* SSL_load_error_strings(); */
    ERR_load_crypto_strings ();

    /* Read private key */

    fp = fopen (keyfile, "r");
    if (fp == NULL)
        exit (1);
    pkey = PEM_read_PrivateKey (fp, NULL, NULL, NULL);
    fclose (fp);

    if (pkey == NULL)
    {
        ERR_print_errors_fp (stderr);
        exit (1);
    }

    /* Do the signature */

    EVP_SignInit (&md_ctx, EVP_sha1 ());
    EVP_SignUpdate (&md_ctx, data, strlen (data));
    sig_len = sizeof (sig_buf);
    err = EVP_SignFinal (&md_ctx, sig_buf, &sig_len, pkey);

    if (err != 1)
    {
        ERR_print_errors_fp (stderr);
        exit (1);
    }

    EVP_PKEY_free (pkey);

    /* Read public key */

    fp = fopen (certfile, "r");
    if (fp == NULL)
        exit (1);
    x509 = PEM_read_X509 (fp, NULL, NULL, NULL);
    fclose (fp);

    if (x509 == NULL)
    {
        ERR_print_errors_fp (stderr);
        exit (1);
    }

    /* Get public key - eay */
    pkey = X509_get_pubkey (x509);
    if (pkey == NULL)
    {
        ERR_print_errors_fp (stderr);
        exit (1);
    }

    /* Verify the signature */

    EVP_VerifyInit (&md_ctx, EVP_sha1 ());
    EVP_VerifyUpdate (&md_ctx, data, strlen ((char *) data));
    err = EVP_VerifyFinal (&md_ctx, sig_buf, sig_len, pkey);
    EVP_PKEY_free (pkey);

    if (err != 1)
    {
        ERR_print_errors_fp (stderr);
        exit (1);
    }
    printf ("Signature Verified Ok.\n");
    return (0);
}
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
	      ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
	      const EVP_MD *type)
	{
	EVP_MD_CTX ctx;
	unsigned char *p,*buf_in=NULL,*buf_out=NULL;
	int i,inl=0,outl=0,outll=0;
	X509_ALGOR *a;

	EVP_MD_CTX_init(&ctx);
	for (i=0; i<2; i++)
		{
		if (i == 0)
			a=algor1;
		else
			a=algor2;
		if (a == NULL) continue;
                if (type->pkey_type == NID_dsaWithSHA1)
			{
			/* special case: RFC 2459 tells us to omit 'parameters'
			 * with id-dsa-with-sha1 */
			ASN1_TYPE_free(a->parameter);
			a->parameter = NULL;
			}
		else if ((a->parameter == NULL) || 
			(a->parameter->type != V_ASN1_NULL))
			{
			ASN1_TYPE_free(a->parameter);
			if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
			a->parameter->type=V_ASN1_NULL;
			}
		ASN1_OBJECT_free(a->algorithm);
		a->algorithm=OBJ_nid2obj(type->pkey_type);
		if (a->algorithm == NULL)
			{
			OPENSSL_PUT_ERROR(ASN1, XXX, ASN1_R_UNKNOWN_OBJECT_TYPE);
			goto err;
			}
		if (a->algorithm->length == 0)
			{
			OPENSSL_PUT_ERROR(ASN1, XXX, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
			goto err;
			}
		}
	inl=i2d(data,NULL);
	buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
	outll=outl=EVP_PKEY_size(pkey);
	buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
	if ((buf_in == NULL) || (buf_out == NULL))
		{
		outl=0;
		OPENSSL_PUT_ERROR(ASN1, XXX, ERR_R_MALLOC_FAILURE);
		goto err;
		}
	p=buf_in;

	i2d(data,&p);
	if (!EVP_SignInit_ex(&ctx,type, NULL)
		|| !EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl)
		|| !EVP_SignFinal(&ctx,(unsigned char *)buf_out,
			(unsigned int *)&outl,pkey))
		{
		outl=0;
		OPENSSL_PUT_ERROR(ASN1, XXX, ERR_R_EVP_LIB);
		goto err;
		}
	if (signature->data != NULL) OPENSSL_free(signature->data);
	signature->data=buf_out;
	buf_out=NULL;
	signature->length=outl;
	/* In the interests of compatibility, I'll make sure that
	 * the bit string has a 'not-used bits' value of 0
	 */
	signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
	signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
err:
	EVP_MD_CTX_cleanup(&ctx);
	if (buf_in != NULL)
		{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
	if (buf_out != NULL)
		{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
	return(outl);
	}
示例#16
0
文件: ssl.c 项目: AGoodId/uwsgi
char *uwsgi_rsa_sign(char *algo_key, char *message, size_t message_len, unsigned int *s_len) {

        // openssl could not be initialized
        if (!uwsgi.ssl_initialized) {
                uwsgi_ssl_init();
        }

        *s_len = 0;
        EVP_PKEY *pk = NULL;

        char *algo = uwsgi_str(algo_key);
        char *colon = strchr(algo, ':');
        if (!colon) {
                uwsgi_log("invalid RSA signature syntax, must be: <digest>:<pemfile>\n");
                free(algo);
                return NULL;
        }

        *colon = 0;
        char *keyfile = colon + 1;
        char *signature = NULL;

        FILE *kf = fopen(keyfile, "r");
        if (!kf) {
                uwsgi_error_open(keyfile);
                free(algo);
                return NULL;
        }

        if (PEM_read_PrivateKey(kf, &pk, NULL, NULL) == 0) {
                uwsgi_log("unable to load private key: %s\n", keyfile);
                free(algo);
                fclose(kf);
                return NULL;
        }

        fclose(kf);

        EVP_MD_CTX *ctx = EVP_MD_CTX_create();
        if (!ctx) {
                free(algo);
                EVP_PKEY_free(pk);
                return NULL;
        }

        const EVP_MD *md = EVP_get_digestbyname(algo);
        if (!md) {
                uwsgi_log("unknown digest algo: %s\n", algo);
                free(algo);
                EVP_PKEY_free(pk);
                EVP_MD_CTX_destroy(ctx);
                return NULL;
        }

        *s_len = EVP_PKEY_size(pk);
        signature = uwsgi_malloc(*s_len);

	if (EVP_SignInit_ex(ctx, md, NULL) == 0) {
                ERR_print_errors_fp(stderr);
                free(signature);
                signature = NULL;
                *s_len = 0;
                goto clear;
        }

        if (EVP_SignUpdate(ctx, message, message_len) == 0) {
                ERR_print_errors_fp(stderr);
                free(signature);
                signature = NULL;
                *s_len = 0;
                goto clear;
        }


        if (EVP_SignFinal(ctx, (unsigned char *) signature, s_len, pk) == 0) {
                ERR_print_errors_fp(stderr);
                free(signature);
                signature = NULL;
                *s_len = 0;
                goto clear;
        }

clear:
        free(algo);
        EVP_PKEY_free(pk);
        EVP_MD_CTX_destroy(ctx);
        return signature;

}
示例#17
0
int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
	  EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
	  const char *file)
	{
	int len;
	int i;

	for (;;)
		{
		i=BIO_read(bp,(char *)buf,BUFSIZE);
		if(i < 0)
			{
			BIO_printf(bio_err, "Read Error in %s\n",file);
			ERR_print_errors(bio_err);
			return 1;
			}
		if (i == 0) break;
		}
	if(sigin)
		{
		EVP_MD_CTX *ctx;
		BIO_get_md_ctx(bp, &ctx);
		i = EVP_VerifyFinal(ctx, sigin, (unsigned int)siglen, key); 
		if(i > 0)
			BIO_printf(out, "Verified OK\n");
		else if(i == 0)
			{
			BIO_printf(out, "Verification Failure\n");
			return 1;
			}
		else
			{
			BIO_printf(bio_err, "Error Verifying Data\n");
			ERR_print_errors(bio_err);
			return 1;
			}
		return 0;
		}
	if(key)
		{
		EVP_MD_CTX *ctx;
		BIO_get_md_ctx(bp, &ctx);
		if(!EVP_SignFinal(ctx, buf, (unsigned int *)&len, key)) 
			{
			BIO_printf(bio_err, "Error Signing Data\n");
			ERR_print_errors(bio_err);
			return 1;
			}
		}
	else
		len=BIO_gets(bp,(char *)buf,BUFSIZE);

	if(binout) BIO_write(out, buf, len);
	else 
		{
		BIO_write(out,title,strlen(title));
		for (i=0; i<len; i++)
			{
			if (sep && (i != 0))
				BIO_printf(out, ":");
			BIO_printf(out, "%02x",buf[i]);
			}
		BIO_printf(out, "\n");
		}
	return 0;
	}
示例#18
0
static isc_result_t
openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
	dst_key_t *key = dctx->key;
	DSA *dsa = key->keydata.dsa;
	isc_region_t r;
	DSA_SIG *dsasig;
	unsigned int klen;
#if USE_EVP
	EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
	EVP_PKEY *pkey;
	unsigned char *sigbuf;
	const unsigned char *sb;
	unsigned int siglen;
#else
	isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
	unsigned char digest[ISC_SHA1_DIGESTLENGTH];
#endif

	isc_buffer_availableregion(sig, &r);
	if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1)
		return (ISC_R_NOSPACE);

#if USE_EVP
	pkey = EVP_PKEY_new();
	if (pkey == NULL)
		return (ISC_R_NOMEMORY);
	if (!EVP_PKEY_set1_DSA(pkey, dsa)) {
		EVP_PKEY_free(pkey);
		return (ISC_R_FAILURE);
	}
	sigbuf = malloc(EVP_PKEY_size(pkey));
	if (sigbuf == NULL) {
		EVP_PKEY_free(pkey);
		return (ISC_R_NOMEMORY);
	}
	if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) {
		EVP_PKEY_free(pkey);
		free(sigbuf);
		return (dst__openssl_toresult3(dctx->category,
					       "EVP_SignFinal",
					       ISC_R_FAILURE));
	}
	INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
	EVP_PKEY_free(pkey);
	/* Convert from Dss-Sig-Value (RFC2459). */
	dsasig = DSA_SIG_new();
	if (dsasig == NULL) {
		free(sigbuf);
		return (ISC_R_NOMEMORY);
	}
	sb = sigbuf;
	if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) {
		free(sigbuf);
		return (dst__openssl_toresult3(dctx->category,
					       "d2i_DSA_SIG",
					       ISC_R_FAILURE));
	}
	free(sigbuf);

#elif 0
	/* Only use EVP for the Digest */
	if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
		return (dst__openssl_toresult3(dctx->category,
					       "EVP_DigestFinal_ex",
					       ISC_R_FAILURE));
	}
	dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
	if (dsasig == NULL)
		return (dst__openssl_toresult3(dctx->category,
					       "DSA_do_sign",
					       DST_R_SIGNFAILURE));
#else
	isc_sha1_final(sha1ctx, digest);

	dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
	if (dsasig == NULL)
		return (dst__openssl_toresult3(dctx->category,
					       "DSA_do_sign",
					       DST_R_SIGNFAILURE));
#endif

	klen = (key->key_size - 512)/64;
	if (klen > 255)
		return (ISC_R_FAILURE);
	*r.base = klen;
	isc_region_consume(&r, 1);

	BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH);
	isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
	BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH);
	isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
	DSA_SIG_free(dsasig);
	isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1);

	return (ISC_R_SUCCESS);
}
示例#19
0
/* read the data and then respond */
static int client_certificate(SSL *s)
	{
	unsigned char *buf;
	unsigned char *p,*d;
	int i;
	unsigned int n;
	int cert_ch_len;
	unsigned char *cert_ch;

	buf=(unsigned char *)s->init_buf->data;

	/* We have a cert associated with the SSL, so attach it to
	 * the session if it does not have one */

	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A)
		{
		i=ssl2_read(s,(char *)&(buf[s->init_num]),
			SSL2_MAX_CERT_CHALLENGE_LENGTH+2-s->init_num);
		if (i<(SSL2_MIN_CERT_CHALLENGE_LENGTH+2-s->init_num))
			return(ssl2_part_read(s,SSL_F_CLIENT_CERTIFICATE,i));
		s->init_num += i;
		if (s->msg_callback)
			s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, s->msg_callback_arg); /* REQUEST-CERTIFICATE */

		/* type=buf[0]; */
		/* type eq x509 */
		if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
			{
			ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
			SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_AUTHENTICATION_TYPE);
			return(-1);
			}

		if ((s->cert == NULL) ||
			(s->cert->key->x509 == NULL) ||
			(s->cert->key->privatekey == NULL))
			{
			s->state=SSL2_ST_X509_GET_CLIENT_CERTIFICATE;
			}
		else
			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
		}

	cert_ch = buf + 2;
	cert_ch_len = s->init_num - 2;

	if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE)
		{
		X509 *x509=NULL;
		EVP_PKEY *pkey=NULL;

		/* If we get an error we need to
		 * ssl->rwstate=SSL_X509_LOOKUP;
		 * return(error);
		 * We should then be retried when things are ok and we
		 * can get a cert or not */

		i=0;
		if (s->ctx->client_cert_cb != NULL)
			{
			i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
			}

		if (i < 0)
			{
			s->rwstate=SSL_X509_LOOKUP;
			return(-1);
			}
		s->rwstate=SSL_NOTHING;

		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
			{
			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
			if (	!SSL_use_certificate(s,x509) || 
				!SSL_use_PrivateKey(s,pkey))
				{
				i=0;
				}
			X509_free(x509);
			EVP_PKEY_free(pkey);
			}
		else if (i == 1)
			{
			if (x509 != NULL) X509_free(x509);
			if (pkey != NULL) EVP_PKEY_free(pkey);
			SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
			i=0;
			}

		if (i == 0)
			{
			/* We have no client certificate to respond with
			 * so send the correct error message back */
			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_B;
			p=buf;
			*(p++)=SSL2_MT_ERROR;
			s2n(SSL2_PE_NO_CERTIFICATE,p);
			s->init_off=0;
			s->init_num=3;
			/* Write is done at the end */
			}
		}

	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B)
		{
		return(ssl2_do_write(s));
		}

	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C)
		{
		EVP_MD_CTX ctx;

		/* ok, now we calculate the checksum
		 * do it first so we can reuse buf :-) */
		p=buf;
		EVP_MD_CTX_init(&ctx);
		EVP_SignInit_ex(&ctx,s->ctx->rsa_md5, NULL);
		EVP_SignUpdate(&ctx,s->s2->key_material,
			       s->s2->key_material_length);
		EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len);
		i=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
		/* Don't update the signature if it fails - FIXME: probably should handle this better */
		if(i > 0)
			EVP_SignUpdate(&ctx,buf,(unsigned int)i);

		p=buf;
		d=p+6;
		*(p++)=SSL2_MT_CLIENT_CERTIFICATE;
		*(p++)=SSL2_CT_X509_CERTIFICATE;
		n=i2d_X509(s->cert->key->x509,&d);
		s2n(n,p);

		if (!EVP_SignFinal(&ctx,d,&n,s->cert->key->privatekey))
			{
			/* this is not good.  If things have failed it
			 * means there so something wrong with the key.
			 * We will continue with a 0 length signature
			 */
			}
		EVP_MD_CTX_cleanup(&ctx);
		s2n(n,p);
		d+=n;

		s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_D;
		s->init_num=d-buf;
		s->init_off=0;
		}
	/* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */
	return(ssl2_do_write(s));
	}
static int rsa_sign_with_key(RSA *rsa, const void *data,
		const int data_size, uint8_t **sigp, uint *sig_size)
{
	EVP_PKEY *key;
	EVP_MD_CTX *context;
	int size, ret = 0;
	uint8_t *sig;

	key = EVP_PKEY_new();
	if (!key)
		return rsa_err("EVP_PKEY object creation failed");

	if (!EVP_PKEY_set1_RSA(key, rsa)) {
		ret = rsa_err("EVP key setup failed");
		goto err_set;
	}

	size = EVP_PKEY_size(key);
	sig = malloc(size);
	if (!sig) {
		fprintf(stderr, "Out of memory for signature (%d bytes)\n",
			size);
		ret = -ENOMEM;
		goto err_alloc;
	}

	context = EVP_MD_CTX_create();
	if (!context) {
		ret = rsa_err("EVP context creation failed");
		goto err_create;
	}
	EVP_MD_CTX_init(context);
	if (!EVP_SignInit(context, EVP_sha1())) {
		ret = rsa_err("Signer setup failed");
		goto err_sign;
	}

	if (!EVP_SignUpdate(context, data, data_size)) {
		ret = rsa_err("Signing data failed");
		goto err_sign;
	}

	if (!EVP_SignFinal(context, sig, sig_size, key)) {
		ret = rsa_err("Could not obtain signature");
		goto err_sign;
	}
	EVP_MD_CTX_cleanup(context);
	EVP_MD_CTX_destroy(context);
	EVP_PKEY_free(key);

	printf("Got signature: %d bytes, expected %d\n", *sig_size, size);
	*sigp = sig;
	*sig_size = size;

	return 0;

err_sign:
	EVP_MD_CTX_destroy(context);
err_create:
	free(sig);
err_alloc:
err_set:
	EVP_PKEY_free(key);
	return ret;
}
示例#21
0
static LUA_FUNCTION(openssl_pkcs7_sign_digest)
{
  PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7");
  size_t l;
  const char* data = luaL_checklstring(L, 2, &l);
  long flags = luaL_optint(L, 3, 0);
  int hash = lua_isnoneornil(L, 4) ? 0 : lua_toboolean(L, 4);

  int ret = 0;
  int i, j;

  const EVP_MD* md;
  PKCS7_SIGNER_INFO *si;
  EVP_MD_CTX mdc;
  STACK_OF(X509_ATTRIBUTE) *sk;
  STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
  ASN1_OCTET_STRING *os = NULL;

  if (p7->d.ptr == NULL)
  {
    luaL_error(L, "pkcs7 without content");
    return 0;
  }

  flags |= PKCS7_DETACHED;
  PKCS7_set_detached(p7, 1);

  EVP_MD_CTX_init(&mdc);
  i = OBJ_obj2nid(p7->type);
  p7->state = PKCS7_S_HEADER;

  switch (i)
  {
  case NID_pkcs7_data:
    os = p7->d.data;
    break;
  case NID_pkcs7_signedAndEnveloped:
    /* XXXXXXXXXXXXXXXX */
    si_sk = p7->d.signed_and_enveloped->signer_info;
    os = p7->d.signed_and_enveloped->enc_data->enc_data;
    if (!os)
    {
      os = M_ASN1_OCTET_STRING_new();
      if (!os)
      {
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
        goto err;
      }
      p7->d.signed_and_enveloped->enc_data->enc_data = os;
    }
    break;
  case NID_pkcs7_enveloped:
    /* XXXXXXXXXXXXXXXX */
    os = p7->d.enveloped->enc_data->enc_data;
    if (!os)
    {
      os = M_ASN1_OCTET_STRING_new();
      if (!os)
      {
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
        goto err;
      }
      p7->d.enveloped->enc_data->enc_data = os;
    }
    break;
  case NID_pkcs7_signed:
    si_sk = p7->d.sign->signer_info;
    os = PKCS7_get_octet_string(p7->d.sign->contents);
    /* If detached data then the content is excluded */
    if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached)
    {
      M_ASN1_OCTET_STRING_free(os);
      os = NULL;
      p7->d.sign->contents->d.data = NULL;
    }
    break;

  case NID_pkcs7_digest:
    os = PKCS7_get_octet_string(p7->d.digest->contents);
    /* If detached data then the content is excluded */
    if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
    {
      M_ASN1_OCTET_STRING_free(os);
      os = NULL;
      p7->d.digest->contents->d.data = NULL;
    }
    break;

  default:
    PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
    goto err;
  }

  if (si_sk != NULL)
  {
    for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
    {
      si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
      if (si->pkey == NULL)
        continue;
      j = OBJ_obj2nid(si->digest_alg->algorithm);
      md = EVP_get_digestbynid(j);
      EVP_DigestInit_ex(&mdc, md, NULL);

      if (hash)
      {
        if (l == (size_t) mdc.digest->ctx_size)
        {
          memcpy(mdc.md_data, data, l);
        }
        else
        {
          EVP_MD_CTX_cleanup(&mdc);
          luaL_argerror(L, 2, "data with wrong length");
        }
      }
      else
        EVP_DigestUpdate(&mdc, data, l);

      sk = si->auth_attr;

      /*
      * If there are attributes, we add the digest attribute and only
      * sign the attributes
      */
      if (sk_X509_ATTRIBUTE_num(sk) > 0)
      {
        if (!do_pkcs7_signed_attrib(si, &mdc))
          goto err;
      }
      else
      {
        unsigned char *abuf = NULL;
        unsigned int abuflen;
        abuflen = EVP_PKEY_size(si->pkey);
        abuf = OPENSSL_malloc(abuflen);
        if (!abuf)
          goto err;

        if (!EVP_SignFinal(&mdc, abuf, &abuflen, si->pkey))
        {
          PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
          goto err;
        }
        ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
      }
    }
  }
  else if (i == NID_pkcs7_digest)
  {
    unsigned char md_data[EVP_MAX_MD_SIZE];
    unsigned int md_len;
    md = EVP_get_digestbynid(OBJ_obj2nid(p7->d.digest->md->algorithm));
    EVP_DigestInit_ex(&mdc, md, NULL);
    if (l == (size_t) mdc.digest->ctx_size)
    {
      memcpy(mdc.md_data, data, l);
    }
    else
    {
      EVP_MD_CTX_cleanup(&mdc);
      luaL_error(L, "data with wrong data");
    }
    if (!EVP_DigestFinal_ex(&mdc, md_data, &md_len))
      goto err;
    M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
  }

  if (!PKCS7_is_detached(p7))
  {
    /*
    * NOTE(emilia): I think we only reach os == NULL here because detached
    * digested data support is broken.
    */
    if (os == NULL)
      goto err;
    if (!(os->flags & ASN1_STRING_FLAG_NDEF))
    {
      char *cont = memdup(data, l);
      long contlen = l;
      ASN1_STRING_set0(os, (unsigned char *) cont, contlen);
    }
  }

  ret = 1;
err:
  EVP_MD_CTX_cleanup(&mdc);
  return openssl_pushresult(L, ret);
}
示例#22
0
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
	{
	int ret=0;
	int i,j;
	BIO *btmp;
	BUF_MEM *buf_mem=NULL;
	BUF_MEM *buf=NULL;
	PKCS7_SIGNER_INFO *si;
	EVP_MD_CTX *mdc,ctx_tmp;
	STACK_OF(X509_ATTRIBUTE) *sk;
	STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
	ASN1_OCTET_STRING *os=NULL;

	EVP_MD_CTX_init(&ctx_tmp);
	i=OBJ_obj2nid(p7->type);
	p7->state=PKCS7_S_HEADER;

	switch (i)
		{
	case NID_pkcs7_signedAndEnveloped:
		/* XXXXXXXXXXXXXXXX */
		si_sk=p7->d.signed_and_enveloped->signer_info;
		os=M_ASN1_OCTET_STRING_new();
		p7->d.signed_and_enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_enveloped:
		/* XXXXXXXXXXXXXXXX */
		os=M_ASN1_OCTET_STRING_new();
		p7->d.enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_signed:
		si_sk=p7->d.sign->signer_info;
		os=PKCS7_get_octet_string(p7->d.sign->contents);
		/* If detached data then the content is excluded */
		if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
			M_ASN1_OCTET_STRING_free(os);
			p7->d.sign->contents->d.data = NULL;
		}
		break;
		}

	if (si_sk != NULL)
		{
		if ((buf=BUF_MEM_new()) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
			goto err;
			}
		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
			{
			si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
			if (si->pkey == NULL) continue;

			j=OBJ_obj2nid(si->digest_alg->algorithm);

			btmp=bio;
			for (;;)
				{
				if ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) 
					== NULL)
					{
					PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
					goto err;
					}
				BIO_get_md_ctx(btmp,&mdc);
				if (mdc == NULL)
					{
					PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_INTERNAL_ERROR);
					goto err;
					}
				if (EVP_MD_CTX_type(mdc) == j)
					break;
				else
					btmp=BIO_next(btmp);
				}
			
			/* We now have the EVP_MD_CTX, lets do the
			 * signing. */
			EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
			if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey)))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
				goto err;
				}

			sk=si->auth_attr;

			/* If there are attributes, we add the digest
			 * attribute and only sign the attributes */
			if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
				{
				unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL;
				unsigned int md_len, alen;
				ASN1_OCTET_STRING *digest;
				ASN1_UTCTIME *sign_time;
				const EVP_MD *md_tmp;

				/* Add signing time if not already present */
				if (!PKCS7_get_signed_attribute(si,
							NID_pkcs9_signingTime))
					{
					sign_time=X509_gmtime_adj(NULL,0);
					PKCS7_add_signed_attribute(si,
						NID_pkcs9_signingTime,
						V_ASN1_UTCTIME,sign_time);
					}

				/* Add digest */
				md_tmp=EVP_MD_CTX_md(&ctx_tmp);
				EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len);
				digest=M_ASN1_OCTET_STRING_new();
				M_ASN1_OCTET_STRING_set(digest,md_data,md_len);
				PKCS7_add_signed_attribute(si,
					NID_pkcs9_messageDigest,
					V_ASN1_OCTET_STRING,digest);

				/* Now sign the attributes */
				EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
				alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf,
							ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
				if(!abuf) goto err;
				EVP_SignUpdate(&ctx_tmp,abuf,alen);
				OPENSSL_free(abuf);
				}

#ifndef OPENSSL_NO_DSA
			if (si->pkey->type == EVP_PKEY_DSA)
				ctx_tmp.digest=EVP_dss1();
#endif

			if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
				(unsigned int *)&buf->length,si->pkey))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_EVP_LIB);
				goto err;
				}
			if (!ASN1_STRING_set(si->enc_digest,
				(unsigned char *)buf->data,buf->length))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_ASN1_LIB);
				goto err;
				}
			}
		}

	if (!PKCS7_is_detached(p7))
		{
		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
		if (btmp == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
			goto err;
			}
		BIO_get_mem_ptr(btmp,&buf_mem);
		/* Mark the BIO read only then we can use its copy of the data
		 * instead of making an extra copy.
		 */
		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
		BIO_set_mem_eof_return(btmp, 0);
		os->data = (unsigned char *)buf_mem->data;
		os->length = buf_mem->length;
#if 0
		M_ASN1_OCTET_STRING_set(os,
			(unsigned char *)buf_mem->data,buf_mem->length);
#endif
		}
	ret=1;
err:
	EVP_MD_CTX_cleanup(&ctx_tmp);
	if (buf != NULL) BUF_MEM_free(buf);
	return(ret);
	}
示例#23
0
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
	{
	int ret=0;
	int i,j;
	BIO *btmp;
	PKCS7_SIGNER_INFO *si;
	EVP_MD_CTX *mdc,ctx_tmp;
	STACK_OF(X509_ATTRIBUTE) *sk;
	STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
	ASN1_OCTET_STRING *os=NULL;

	EVP_MD_CTX_init(&ctx_tmp);
	i=OBJ_obj2nid(p7->type);
	p7->state=PKCS7_S_HEADER;

	switch (i)
		{
	case NID_pkcs7_data:
		os = p7->d.data;
		break;
	case NID_pkcs7_signedAndEnveloped:
		/* XXXXXXXXXXXXXXXX */
		si_sk=p7->d.signed_and_enveloped->signer_info;
		os = p7->d.signed_and_enveloped->enc_data->enc_data;
		if (!os)
			{
			os=M_ASN1_OCTET_STRING_new();
			if (!os)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
				goto err;
				}
			p7->d.signed_and_enveloped->enc_data->enc_data=os;
			}
		break;
	case NID_pkcs7_enveloped:
		/* XXXXXXXXXXXXXXXX */
		os = p7->d.enveloped->enc_data->enc_data;
		if (!os)
			{
			os=M_ASN1_OCTET_STRING_new();
			if (!os)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
				goto err;
				}
			p7->d.enveloped->enc_data->enc_data=os;
			}
		break;
	case NID_pkcs7_signed:
		si_sk=p7->d.sign->signer_info;
		os=PKCS7_get_octet_string(p7->d.sign->contents);
		/* If detached data then the content is excluded */
		if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
			M_ASN1_OCTET_STRING_free(os);
			p7->d.sign->contents->d.data = NULL;
		}
		break;

	case NID_pkcs7_digest:
		os=PKCS7_get_octet_string(p7->d.digest->contents);
		/* If detached data then the content is excluded */
		if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
			{
			M_ASN1_OCTET_STRING_free(os);
			p7->d.digest->contents->d.data = NULL;
			}
		break;

	default:
		PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
	        goto err;
		}

	if (si_sk != NULL)
		{
		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
			{
			si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
			if (si->pkey == NULL)
				continue;

			j = OBJ_obj2nid(si->digest_alg->algorithm);

			btmp=bio;

			btmp = PKCS7_find_digest(&mdc, btmp, j);

			if (btmp == NULL)
				goto err;

			/* We now have the EVP_MD_CTX, lets do the
			 * signing. */
			EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);

			sk=si->auth_attr;

			/* If there are attributes, we add the digest
			 * attribute and only sign the attributes */
			if (sk_X509_ATTRIBUTE_num(sk) > 0)
				{
				if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
					goto err;
				}
			else
				{
				unsigned char *abuf = NULL;
				unsigned int abuflen;
				abuflen = EVP_PKEY_size(si->pkey);
				abuf = OPENSSL_malloc(abuflen);
				if (!abuf)
					goto err;

				if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen,
							si->pkey))
					{
					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
							ERR_R_EVP_LIB);
					goto err;
					}
				ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
				}
			}
		}
	else if (i == NID_pkcs7_digest)
		{
		unsigned char md_data[EVP_MAX_MD_SIZE];
		unsigned int md_len;
		if (!PKCS7_find_digest(&mdc, bio,
				OBJ_obj2nid(p7->d.digest->md->algorithm)))
			goto err;
		EVP_DigestFinal_ex(mdc,md_data,&md_len);
		M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
		}

	if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF))
		{
		char *cont;
		long contlen;
		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
		if (btmp == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
			goto err;
			}
		contlen = BIO_get_mem_data(btmp, &cont);
		/* Mark the BIO read only then we can use its copy of the data
		 * instead of making an extra copy.
		 */
		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
		BIO_set_mem_eof_return(btmp, 0);
		ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
		}
	ret=1;
err:
	EVP_MD_CTX_cleanup(&ctx_tmp);
	return(ret);
	}
示例#24
0
//--------------------------------------------------
// Calculates file size
// szFileName - file name
// lFileLen - pointer to a buffer where to store the file length
// returns error code or ERR_OK for success
//--------------------------------------------------
EXP_OPTION int calculateFileSize(const char* szFileName, long* lFileLen)
{
  FILE* hFile = 0;
#ifdef WIN32
  int i = 0, err = ERR_OK;
  wchar_t *convFileName = 0; 
#endif
  
  RETURN_IF_NULL_PARAM(szFileName);
  RETURN_IF_NULL_PARAM(lFileLen);
  if(!szFileName || !strlen(szFileName)) return 0;
#ifdef WIN32
  err = utf82unicode((const char*)szFileName, (char**)&convFileName, &i);
  ddocDebug(3, "calculateFileSize", "Opening FILE: %s, conv-file: %s len: %d", szFileName, convFileName, i);
  if((hFile = _wfopen(convFileName,L"rb")) != NULL) {
#else
  if((hFile = fopen(szFileName,"rb")) != NULL) {
#endif
    fseek(hFile, 0, SEEK_END);
    (*lFileLen) = ftell(hFile);
    ddocDebug(3, "calculateFileSize", "Closing FILE: %s, size: %ld", szFileName, (*lFileLen));
    fclose(hFile);
  } // if - fopen
  else
    SET_LAST_ERROR_RETURN_CODE(ERR_FILE_READ);
#ifdef WIN32
  if(convFileName) free(convFileName); 
#endif

  return ERR_OK;
}


//--------------------------------------------------
// Calculates files SHA1-RSA signature
// szFileName - file name
// nDigestType - digest type. Supports only SHA1 (0)
// pSigBuf - buffer to store the signature
// nSigLen - buffer size, must be at least 128
//			will be updated by actual signature length
// keyfile - name of the private key file
// passwd - private key password
// returns error code or ERR_OK for success
//--------------------------------------------------
EXP_OPTION int calculateFileSignature(const char* szFileName, int nDigestType,
							byte* pSigBuf, int* nSigLen,
							const char *keyfile, const char* passwd)
{
  int err = ERR_OK;
  EVP_MD_CTX  ctx;
  byte buf[FILE_BUFSIZE];
  int i;
  FILE *f = NULL;
  EVP_PKEY* pkey = NULL;

  RETURN_IF_NULL_PARAM(szFileName);
  RETURN_IF_NULL_PARAM(pSigBuf);
  RETURN_IF_NULL_PARAM(nSigLen);
  RETURN_IF_NULL_PARAM(keyfile);
  RETURN_IF_NULL_PARAM(passwd);

  memset(pSigBuf, 0, *nSigLen);
  if(nDigestType == DIGEST_SHA1) {
    if(*nSigLen >= SIGNATURE_LEN) {
      if((err = ReadPrivateKey(&pkey, keyfile, passwd, FILE_FORMAT_PEM)) == ERR_OK) {
	if((f = fopen(szFileName,"rb")) != NULL) {					
	  EVP_SignInit(&ctx, EVP_sha1());
	  for (;;) {
	    i = fread(buf, sizeof(char), FILE_BUFSIZE, f);
	    if (i <= 0) break;
	    EVP_SignUpdate (&ctx, buf, (unsigned long)i);
	  }
	  err = EVP_SignFinal(&ctx, pSigBuf, (unsigned int*)nSigLen, pkey);
	  if(err == ERR_LIB_NONE)
	    err = ERR_OK;
	  fclose(f);
	  EVP_PKEY_free(pkey);					
	} // if - fopen
	else
	  err = ERR_FILE_READ;
      }
      else
	err = ERR_PRIVKEY_READ;
    } 
    else
      err = ERR_SIGNATURE_LEN;
  }
  else
    err = ERR_UNSUPPORTED_DIGEST;
  if (err != ERR_OK) SET_LAST_ERROR(err);
  return err;
}