コード例 #1
0
ファイル: pk7_doit.c プロジェクト: froggatt/edimax-br-6528n
int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
								X509 *x509)
	{
	ASN1_OCTET_STRING *os;
	EVP_MD_CTX mdc_tmp,*mdc;
	int ret=0,i;
	int md_type;
	STACK_OF(X509_ATTRIBUTE) *sk;
	BIO *btmp;
	EVP_PKEY *pkey;

	EVP_MD_CTX_init(&mdc_tmp);

	if (!PKCS7_type_is_signed(p7) && 
				!PKCS7_type_is_signedAndEnveloped(p7)) {
		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
						PKCS7_R_WRONG_PKCS7_TYPE);
		goto err;
	}

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

	btmp=bio;
	for (;;)
		{
		if ((btmp == NULL) ||
			((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
			{
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
					PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
			goto err;
			}
		BIO_get_md_ctx(btmp,&mdc);
		if (mdc == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
							ERR_R_INTERNAL_ERROR);
			goto err;
			}
		if (EVP_MD_CTX_type(mdc) == md_type)
			break;
		/* Workaround for some broken clients that put the signature
		 * OID instead of the digest OID in digest_alg->algorithm
		 */
		if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
			break;
		btmp=BIO_next(btmp);
		}

	/* mdc is the digest ctx that we want, unless there are attributes,
	 * in which case the digest is the signed attributes */
	EVP_MD_CTX_copy_ex(&mdc_tmp,mdc);

	sk=si->auth_attr;
	if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
		{
		unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
                unsigned int md_len, alen;
		ASN1_OCTET_STRING *message_digest;

		EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len);
		message_digest=PKCS7_digest_from_attributes(sk);
		if (!message_digest)
			{
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
					PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
			goto err;
			}
		if ((message_digest->length != (int)md_len) ||
			(memcmp(message_digest->data,md_dat,md_len)))
			{
#if 0
{
int ii;
for (ii=0; ii<message_digest->length; ii++)
	printf("%02X",message_digest->data[ii]); printf(" sent\n");
for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
}
#endif
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
							PKCS7_R_DIGEST_FAILURE);
			ret= -1;
			goto err;
			}

		EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL);

		alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
						ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
		EVP_VerifyUpdate(&mdc_tmp, abuf, alen);

		OPENSSL_free(abuf);
		}

	os=si->enc_digest;
	pkey = X509_get_pubkey(x509);
	if (!pkey)
		{
		ret = -1;
		goto err;
		}
#ifndef OPENSSL_NO_DSA
	if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
#endif

	i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
	EVP_PKEY_free(pkey);
	if (i <= 0)
		{
		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
						PKCS7_R_SIGNATURE_FAILURE);
		ret= -1;
		goto err;
		}
	else
		ret=1;
err:
	EVP_MD_CTX_cleanup(&mdc_tmp);
	return(ret);
	}
コード例 #2
0
ファイル: signfile.c プロジェクト: cluenet/cluevpn
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
/**
 * Setup key and digest for verification. Adjust sig if necessary.
 *
 * @param algo: key algorithm
 * @param evp_key: EVP PKEY public key to create.
 * @param digest_type: digest type to use
 * @param key: key to setup for.
 * @param keylen: length of key.
 * @return false on failure.
 */
static int
setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, 
	unsigned char* key, size_t keylen)
{
	DSA* dsa;
	RSA* rsa;

	switch(algo) {
		case LDNS_DSA:
		case LDNS_DSA_NSEC3:
			*evp_key = EVP_PKEY_new();
			if(!*evp_key) {
				log_err("verify: malloc failure in crypto");
				return 0;
			}
			dsa = ldns_key_buf2dsa_raw(key, keylen);
			if(!dsa) {
				verbose(VERB_QUERY, "verify: "
					"ldns_key_buf2dsa_raw failed");
				return 0;
			}
			if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) {
				verbose(VERB_QUERY, "verify: "
					"EVP_PKEY_assign_DSA failed");
				return 0;
			}
			*digest_type = EVP_dss1();

			break;
		case LDNS_RSASHA1:
		case LDNS_RSASHA1_NSEC3:
#if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
		case LDNS_RSASHA256:
#endif
#if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
		case LDNS_RSASHA512:
#endif
			*evp_key = EVP_PKEY_new();
			if(!*evp_key) {
				log_err("verify: malloc failure in crypto");
				return 0;
			}
			rsa = ldns_key_buf2rsa_raw(key, keylen);
			if(!rsa) {
				verbose(VERB_QUERY, "verify: "
					"ldns_key_buf2rsa_raw SHA failed");
				return 0;
			}
			if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
				verbose(VERB_QUERY, "verify: "
					"EVP_PKEY_assign_RSA SHA failed");
				return 0;
			}

			/* select SHA version */
#if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
			if(algo == LDNS_RSASHA256)
				*digest_type = EVP_sha256();
			else
#endif
#if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
				if(algo == LDNS_RSASHA512)
				*digest_type = EVP_sha512();
			else
#endif
				*digest_type = EVP_sha1();

			break;
		case LDNS_RSAMD5:
			*evp_key = EVP_PKEY_new();
			if(!*evp_key) {
				log_err("verify: malloc failure in crypto");
				return 0;
			}
			rsa = ldns_key_buf2rsa_raw(key, keylen);
			if(!rsa) {
				verbose(VERB_QUERY, "verify: "
					"ldns_key_buf2rsa_raw MD5 failed");
				return 0;
			}
			if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
				verbose(VERB_QUERY, "verify: "
					"EVP_PKEY_assign_RSA MD5 failed");
				return 0;
			}
			*digest_type = EVP_md5();

			break;
#ifdef USE_GOST
		case LDNS_ECC_GOST:
			*evp_key = ldns_gost2pkey_raw(key, keylen);
			if(!*evp_key) {
				verbose(VERB_QUERY, "verify: "
					"ldns_gost2pkey_raw failed");
				return 0;
			}
			*digest_type = EVP_get_digestbyname("md_gost94");
			if(!*digest_type) {
				verbose(VERB_QUERY, "verify: "
					"EVP_getdigest md_gost94 failed");
				return 0;
			}
			break;
#endif
#ifdef USE_ECDSA
		case LDNS_ECDSAP256SHA256:
			*evp_key = ldns_ecdsa2pkey_raw(key, keylen,
				LDNS_ECDSAP256SHA256);
			if(!*evp_key) {
				verbose(VERB_QUERY, "verify: "
					"ldns_ecdsa2pkey_raw failed");
				return 0;
			}
#ifdef USE_ECDSA_EVP_WORKAROUND
			/* openssl before 1.0.0 fixes RSA with the SHA256
			 * hash in EVP.  We create one for ecdsa_sha256 */
			{
				static int md_ecdsa_256_done = 0;
				static EVP_MD md;
				if(!md_ecdsa_256_done) {
					EVP_MD m = *EVP_sha256();
					md_ecdsa_256_done = 1;
					m.required_pkey_type[0] = (*evp_key)->type;
					m.verify = (void*)ECDSA_verify;
					md = m;
				}
				*digest_type = &md;
			}
#else
			*digest_type = EVP_sha256();
#endif
			break;
		case LDNS_ECDSAP384SHA384:
			*evp_key = ldns_ecdsa2pkey_raw(key, keylen,
				LDNS_ECDSAP384SHA384);
			if(!*evp_key) {
				verbose(VERB_QUERY, "verify: "
					"ldns_ecdsa2pkey_raw failed");
				return 0;
			}
#ifdef USE_ECDSA_EVP_WORKAROUND
			/* openssl before 1.0.0 fixes RSA with the SHA384
			 * hash in EVP.  We create one for ecdsa_sha384 */
			{
				static int md_ecdsa_384_done = 0;
				static EVP_MD md;
				if(!md_ecdsa_384_done) {
					EVP_MD m = *EVP_sha384();
					md_ecdsa_384_done = 1;
					m.required_pkey_type[0] = (*evp_key)->type;
					m.verify = (void*)ECDSA_verify;
					md = m;
				}
				*digest_type = &md;
			}
#else
			*digest_type = EVP_sha384();
#endif
			break;
#endif /* USE_ECDSA */
		default:
			verbose(VERB_QUERY, "verify: unknown algorithm %d", 
				algo);
			return 0;
	}
	return 1;
}
コード例 #4
0
ファイル: pk7_doit.c プロジェクト: froggatt/edimax-br-6528n
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);
	}
コード例 #5
0
ファイル: signutils.cpp プロジェクト: AliSayed/MoSync
SISSignature* makeSignature(SISField* controller, const char* keyData, const char* passphrase, SigType type, EVP_PKEY* publicKey) {
	if (type == SigAuto) {
		if (strstr(keyData, " DSA "))
			type = SigDsa;
		else
			type = SigRsa;
	}
	BIO* io = BIO_new_mem_buf((void*) keyData, -1);
	EVP_PKEY* key = PEM_read_bio_PrivateKey(io, NULL, password_cb, (void*) passphrase);
	if (!key) {
		ERR_print_errors_fp(stderr);
		fprintf(stderr, "Unable to load key\n");
		throw SignBadKey;
	}
	BIO_free_all(io);
	uint8_t* buffer = new uint8_t[controller->Length()];
	uint8_t* ptr = buffer;
	controller->CopyFieldData(ptr);

	EVP_MD_CTX ctx, verify;
	EVP_MD_CTX_init(&ctx);
	EVP_MD_CTX_init(&verify);
	const EVP_MD* md = NULL;
	if (type == SigDsa)
		md = EVP_dss1();
	else
		md = EVP_sha1();
	if (EVP_SignInit_ex(&ctx, md, NULL) == 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	if (EVP_VerifyInit(&verify, md) < 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	if (EVP_SignUpdate(&ctx, buffer, controller->Length()) == 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	if (EVP_VerifyUpdate(&verify, buffer, controller->Length()) == 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	delete [] buffer;
	unsigned int siglen = EVP_PKEY_size(key);
	uint8_t* signature = new uint8_t[siglen];
	if (EVP_SignFinal(&ctx, signature, &siglen, key) == 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	EVP_MD_CTX_cleanup(&ctx);
	int ret = EVP_VerifyFinal(&verify, signature, siglen, publicKey);
	if (ret < 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	if (ret == 0) {
		fprintf(stderr, "Could not verify signature with certificate\n");
		throw SignBadKey;
	}
	EVP_MD_CTX_cleanup(&verify);
	EVP_PKEY_free(key);


	SISString* algorithm = NULL;
	if (type == SigDsa)
		algorithm = new SISString(L"1.2.840.10040.4.3");
	else
		algorithm = new SISString(L"1.2.840.113549.1.1.5");
	SISSignatureAlgorithm* signatureAlgorithm = new SISSignatureAlgorithm(algorithm);
	SISBlob* blob = new SISBlob(signature, siglen);
	delete [] signature;

	return new SISSignature(signatureAlgorithm, blob);
}
コード例 #6
0
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;
    }
コード例 #7
0
int CCertificateRequestGenerator::Generate()
//Generate certificate request and write into a file
	{
	FILE*		  fp			= NULL;
	char*		  pbPassword	= NULL;
	EVP_PKEY* 	  pKey			= NULL;
	X509_REQ*	  pReq			= NULL;
	X509_NAME*	  pSubj			= NULL;
	const EVP_MD* pDigest		= NULL;
	DWORD		  bytesWritten;
	struct entry_pack* pEntPack = NULL;

	int retFunc	= FAIL;

	//Get command prompt handle
	HANDLE hndl = GetStdHandle(STD_OUTPUT_HANDLE);
	
	OPENSSL_add_all_algorithms_conf();
	ERR_load_crypto_strings();

	//First read private key from key file
	if(!(fp = _tfopen(m_privateKeyFile, _T("r"))))
		{
		PrintErrorInfo("Error reading key file!", EGeneric, constparams);
		WriteConsole(hndl, m_privateKeyFile, wcslen(m_privateKeyFile), &bytesWritten, 0);
		return retFunc;
		}

	if(m_password[0] != 0)
		{
		DWORD len = 0;
		len = _tcslen(m_password);
		pbPassword = MakeMBCSString(m_password, CP_UTF8, len);
		pKey = PEM_read_PrivateKey(fp, NULL, NULL, pbPassword);
		delete pbPassword;
		}
	else
		{
		pKey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
		}
			
	fclose(fp); fp = NULL;

	if(!pKey)
		{
		PrintErrorInfo("Error reading private key in key file!", EOPENSSL, constparams);
		return retFunc;
		}
	try
		{
		//Create a new cert request and add the public key into it
		if(!(pReq = X509_REQ_new()))
			{
			PrintErrorInfo("Error creating X509 request object!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

		X509_REQ_set_pubkey(pReq, pKey);

		//Now create DN name entries and assign them to request
		if(!(pSubj = X509_NAME_new()))
			{
			PrintErrorInfo("Error creating X509 name object!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

		//Format DN string
		DoFormatted(m_dname, &pEntPack);

		if(pEntPack->num == 0)
			{
			PrintErrorInfo("Error formatting Distinguished Name!", EGeneric, constparams);
			throw EGeneric;
			}

		for (int i = 0; i < pEntPack->num; i++)
			{
			int nid = 0;
			DWORD lent = 0;
			X509_NAME_ENTRY *pEnt = NULL;
			LPSTR pbMBSTRUTF8 = NULL;

			if((pEntPack->entries[i].value == NULL) || (pEntPack->entries[i].key == NULL))
				{
				PrintErrorInfo("Error in Distinguished Name construction!", EGeneric, constparams);
				throw EGeneric;
				}

			if((nid = OBJ_txt2nid(pEntPack->entries[i].key)) == NID_undef)
				{
				PrintErrorInfo("Error finding NID for a DN entry!", EOPENSSL, constparams);
				throw EOPENSSL;
				}
			lent = _tcslen(pEntPack->entries[i].value);
			pbMBSTRUTF8 = MakeMBCSString(pEntPack->entries[i].value, CP_UTF8, lent);

			if(lent > 64) //OpenSSL does not accept a string longer than 64 
				{
				if(!(pEnt = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_UTF8, (unsigned char *)"dummy", 5)))
					{
					PrintErrorInfo("Error creating name entry from NID!", EOPENSSL, constparams);
					throw EOPENSSL;
					}
				
				pEnt->value->data = (unsigned char *)malloc(lent+1);
				
				for(DWORD j=0; j<lent; j++ )
					{
					pEnt->value->data[j] = pbMBSTRUTF8[j];
					}
				
				pEnt->value->length = lent;

				} 
			else if(!(pEnt = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_UTF8, (unsigned char *)pbMBSTRUTF8, lent)))
				{
				PrintErrorInfo("Error creating name entry from NID!", EOPENSSL, constparams);
				throw EOPENSSL;
				}

			if(X509_NAME_add_entry(pSubj, pEnt, -1, 0) != 1)
				{
				PrintErrorInfo("Error adding entry to X509 Name!", EOPENSSL, constparams);
				throw EOPENSSL;
				}
			delete pbMBSTRUTF8;
			}//for
		
		SYMBIAN_FREE_MEM(pEntPack);

		if(X509_REQ_set_subject_name(pReq, pSubj) != 1)
			{
			PrintErrorInfo("Error adding subject to request!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

			//Find the correct digest and sign the request

		if(EVP_PKEY_type(pKey->type) == EVP_PKEY_DSA)
			{
			pDigest = EVP_dss1();
			}
		else if(EVP_PKEY_type(pKey->type) == EVP_PKEY_RSA)
			{
			pDigest = EVP_sha1();
			}
		else
			{
			PrintErrorInfo("Error checking private key type!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

		if(!(X509_REQ_sign(pReq, pKey, pDigest)))
			{
			PrintErrorInfo("Error signing request!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

		if(!(fp = _tfopen(m_RequestFile, _T("w"))))
			{
			PrintErrorInfo("Error writing to request file!",EGeneric,constparams);
			throw EGeneric;
			}
	
		if(PEM_write_X509_REQ(fp, pReq) != 1)
			{
			PrintErrorInfo("Error while writing to request file!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

		//Free variables
		EVP_PKEY_free(pKey);
		X509_NAME_free(pSubj);
		X509_REQ_free(pReq);
		fclose(fp);

		_tprintf(_T("\nCreated request: "));
		WriteConsole(hndl, m_RequestFile, wcslen(m_RequestFile), &bytesWritten, 0);

		retFunc = SUCCESS;

		}
	catch (...)
		{
		if(pKey)
			{
			EVP_PKEY_free(pKey);
			}
		
		if(pSubj)
			{
			X509_NAME_free(pSubj);
			}

		if(pReq)
			{
			X509_REQ_free(pReq);
			}

		SYMBIAN_FREE_MEM(pEntPack);
		}

	return retFunc;
	}
コード例 #8
0
static void siggen()
{
    char buf[1024];
    char lbuf[1024];
    char *keyword, *value;
    int nmod = 0;
    DSA *dsa = NULL;

    while (fgets(buf, sizeof buf, stdin) != NULL) {
        if (!parse_line(&keyword, &value, lbuf, buf)) {
            fputs(buf, stdout);
            continue;
        }
        if (!strcmp(keyword, "[mod")) {
            nmod = atoi(value);
            printf("[mod = %d]\n\n", nmod);
            if (dsa)
                FIPS_dsa_free(dsa);
            dsa = FIPS_dsa_new();
            if (!DSA_generate_parameters_ex
                    (dsa, nmod, NULL, 0, NULL, NULL, NULL)) {
                do_print_errors();
                exit(1);
            }
            pbn("P", dsa->p);
            pbn("Q", dsa->q);
            pbn("G", dsa->g);
            putc('\n', stdout);
        } else if (!strcmp(keyword, "Msg")) {
            unsigned char msg[1024];
            unsigned char sbuf[60];
            unsigned int slen;
            int n;
            EVP_PKEY pk;
            EVP_MD_CTX mctx;
            DSA_SIG *sig;
            EVP_MD_CTX_init(&mctx);

            n = hex2bin(value, msg);
            pv("Msg", msg, n);

            if (!DSA_generate_key(dsa)) {
                do_print_errors();
                exit(1);
            }
            pk.type = EVP_PKEY_DSA;
            pk.pkey.dsa = dsa;
            pbn("Y", dsa->pub_key);

            EVP_SignInit_ex(&mctx, EVP_dss1(), NULL);
            EVP_SignUpdate(&mctx, msg, n);
            EVP_SignFinal(&mctx, sbuf, &slen, &pk);

            sig = DSA_SIG_new();
            FIPS_dsa_sig_decode(sig, sbuf, slen);

            pbn("R", sig->r);
            pbn("S", sig->s);
            putc('\n', stdout);
            DSA_SIG_free(sig);
            EVP_MD_CTX_cleanup(&mctx);
        }
    }
    if (dsa)
        FIPS_dsa_free(dsa);
}
コード例 #9
0
int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
								X509 *x509)
	{
	ASN1_OCTET_STRING *os;
	EVP_MD_CTX mdc_tmp,*mdc;
	unsigned char *pp,*p;
	int ret=0,i;
	int md_type;
	STACK_OF(X509_ATTRIBUTE) *sk;
	BIO *btmp;
	EVP_PKEY *pkey;

	if (!PKCS7_type_is_signed(p7) && 
				!PKCS7_type_is_signedAndEnveloped(p7)) {
		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
						PKCS7_R_WRONG_PKCS7_TYPE);
		goto err;
	}

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

	btmp=bio;
	for (;;)
		{
		if ((btmp == NULL) ||
			((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
			{
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
					PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
			goto err;
			}
		BIO_get_md_ctx(btmp,&mdc);
		if (mdc == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
							PKCS7_R_INTERNAL_ERROR);
			goto err;
			}
		if (EVP_MD_CTX_type(mdc) == md_type)
			break;
		btmp=BIO_next(btmp);
		}

	/* mdc is the digest ctx that we want, unless there are attributes,
	 * in which case the digest is the signed attributes */
	memcpy(&mdc_tmp,mdc,sizeof(mdc_tmp));

	sk=si->auth_attr;
	if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
		{
		unsigned char md_dat[EVP_MAX_MD_SIZE];
                unsigned int md_len;
		ASN1_OCTET_STRING *message_digest;

		EVP_DigestFinal(&mdc_tmp,md_dat,&md_len);
		message_digest=PKCS7_digest_from_attributes(sk);
		if (!message_digest)
			{
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
					PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
			goto err;
			}
		if ((message_digest->length != (int)md_len) ||
			(memcmp(message_digest->data,md_dat,md_len)))
			{
#if 0
{
int ii;
for (ii=0; ii<message_digest->length; ii++)
	printf("%02X",message_digest->data[ii]); printf(" sent\n");
for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
}
#endif
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
							PKCS7_R_DIGEST_FAILURE);
			ret= -1;
			goto err;
			}

		EVP_VerifyInit(&mdc_tmp,EVP_get_digestbynid(md_type));
		/* Note: when forming the encoding of the attributes we
		 * shouldn't reorder them or this will break the signature.
		 * This is done by using the IS_SEQUENCE flag.
		 */
		i=i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,NULL,i2d_X509_ATTRIBUTE,
			V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
		pp=OPENSSL_malloc(i);
		p=pp;
		i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,&p,i2d_X509_ATTRIBUTE,
			V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
		EVP_VerifyUpdate(&mdc_tmp,pp,i);

		OPENSSL_free(pp);
		}

	os=si->enc_digest;
	pkey = X509_get_pubkey(x509);
	if (!pkey)
		{
		ret = -1;
		goto err;
		}
#ifndef NO_DSA
	if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
#endif

	i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
	EVP_PKEY_free(pkey);
	if (i <= 0)
		{
		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
						PKCS7_R_SIGNATURE_FAILURE);
		ret= -1;
		goto err;
		}
	else
		ret=1;
err:
	return(ret);
	}
コード例 #10
0
ファイル: ndn_signing.c プロジェクト: cawka/ndnd-tlv
static const EVP_MD *
md_from_digest_and_pkey(const char *digest, const struct ndn_pkey *pkey)
{
    int md_nid;
    int pkey_type;

    /* This encapsulates knowledge that the default digest algorithm for
     * signing is SHA256.  See also NDN_SIGNING_DEFAULT_DIGEST_ALGORITHM
     * in ndn-tlv/ndn.h.  We could call OBJ_txt2nid(), but this would be rather
     * inefficient.  If there were a place to stand for overall signing
     * initialization then that would be an appropriate place to do so.
     */
    if (digest == NULL) {
        md_nid = NID_sha256;
    }
    else {
        /* figure out what algorithm the OID represents */
        md_nid = OBJ_txt2nid(digest);
        if (md_nid == NID_undef) {
            fprintf(stderr, "not a DigestAlgorithm I understand right now: %s\n", digest);
            return (NULL);
        }
    }
    pkey_type = EVP_PKEY_type(((EVP_PKEY *)pkey)->type);
    switch (pkey_type) {
        case EVP_PKEY_RSA:
        case EVP_PKEY_DSA:
#if !defined(OPENSSL_NO_EC)
        case EVP_PKEY_EC:
#endif
            break;
        default:
            fprintf(stderr, "not a Key type I understand right now: NID %d\n", pkey_type);
            return(NULL);
    }
    /*
     * In OpenSSL 0.9.8 the digest algorithm and key type determine the
     * digest and signature methods that are in the staticly defined
     * EVP_MD structures, so we need to get the correct predefined one, or
     * create our own.
     * In OpenSSL 1.0.0 the EVP_MD structure allows for the key that is passed
     * in the signature finalization step to determine the signature algorithm
     * applied to the digest, so we would be able to use a single SHA256 context
     * independent of the key type (assuming size compatability).
     * At the point that 1.0.0 or later is the default provider we could simplify
     * this code.   The Java code (OIDLookup.java) uses a much more elaborate
     * set of hash maps to perform a similar function.
     */
    switch (md_nid) {
#ifndef OPENSSL_NO_SHA
        case NID_sha1:      // supported for RSA/DSA/EC key types
            switch (pkey_type) {
                case EVP_PKEY_RSA:
                    return(EVP_sha1());
                case EVP_PKEY_DSA:
                    return(EVP_dss1());
#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA)
                case EVP_PKEY_EC:
                    return(EVP_ecdsa());
#endif
            }
            break;
#endif
        case NID_sha256:    // supported for RSA/EC key types
            if (pkey_type == EVP_PKEY_RSA)
                return(EVP_sha256());
#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) && defined(NID_ecdsa_with_SHA256)
            else if (pkey_type == EVP_PKEY_EC) {
                return(&sha256ec_md);
            } /* our own md */
#endif
            break;
        case NID_sha512:     // supported for RSA
            if (pkey_type == EVP_PKEY_RSA)
                return(EVP_sha512());
        default:
            break;
    }
    fprintf(stderr, "not a Digest+Signature algorithm I understand right now: %s with NID %d\n",
            digest, pkey_type);
    return (NULL);
}
コード例 #11
0
ファイル: sigcomp.c プロジェクト: jijianwen/linux-v6eval
int
main(int argc, char **argv, char **envp)
{
#if 0
	const char *algorithm	= NULL;
#else
	const char *algorithm	= "md5";
#endif
	const char *key		= NULL;
	const char *msg		= NULL;
	const char *signature	= NULL;
#if 0
	const char *type	= NULL;
#else
	const char *type	= "rsa";
#endif

	xxxflag	= false;

	if(!(prog = basename(argv[0]))) {
		fprintf(stderr, "err: basename: %s -- %s\n",
			strerror(errno), argv[0]);

		return(-1);
		/* NOTREACHED */
	}

	{
		int ch = 0;
#if 0
		while((ch = getopt(argc, argv, "a:k:m:s:t:@")) != -1) {
#else
		while((ch = getopt(argc, argv, "k:m:s:@")) != -1) {
#endif
			switch (ch) {
#if 0
				case 'a':
					algorithm	= optarg;
					break;
#endif
				case 'k':
					key		= optarg;
					break;
				case 'm':
					msg		= optarg;
					break;
				case 's':
					signature	= optarg;
					break;
#if 0
				case 't':
					type		= optarg;
					break;
#endif
				case '@':
					xxxflag		= true;
					break;
				default:
					usage();
					/* NOTREACHED */

					break;
			}
		}

		argc -= optind;
		argv += optind;
	}

	if(argc || !algorithm || !key || !msg || !type) {
		usage();
		/* NOTREACHED */
	}

	return(sigcomp_main(algorithm, key, msg, signature, type)? 0: -1);
	/* NOTREACHED */
}



static bool
sigcomp_main(const char *const algorithm, const char *const key,
	const char *const msg, const char *const signature,
	const char *const type)
{
	const EVP_MD *evp_md	= NULL;
	BIGNUM *bn_key		= NULL;
	BIGNUM *bn_msg		= NULL;
	BIGNUM *bn_signature	= NULL;

	ERR_load_crypto_strings();

	if(!(evp_md = evp_md_with_algorithm(type, algorithm))) {
		fprintf(stderr, "err: algorithm: %s -- "
			"unknown algorithm for %s\n", algorithm, type);

		return(sigcomp_return(false, bn_key, bn_msg, bn_signature));
	}

	/* key -> bn_key */
	if(!(bn_key = BN_new())) {
		openssl_strerror("BN_new");
		return(sigcomp_return(false, bn_key, bn_msg, bn_signature));
	}

	if(!BN_hex2bn(&bn_key, (const char *)key)) {
		openssl_strerror("BN_hex2bn");
		return(sigcomp_return(false, bn_key, bn_msg, bn_signature));
	}

	/* msg -> bn_msg */
	if(!(bn_msg = BN_new())) {
		openssl_strerror("BN_new");
		return(sigcomp_return(false, bn_key, bn_msg, bn_signature));
	}

	if(!BN_hex2bn(&bn_msg, (const char *)msg)) {
		openssl_strerror("BN_hex2bn");
		return(sigcomp_return(false, bn_key, bn_msg, bn_signature));
	}

	if(signature) {
		/* signature -> bn_signature */
		if(!(bn_signature = BN_new())) {
			openssl_strerror("BN_new");
			return(sigcomp_return(false,
				bn_key, bn_msg, bn_signature));
		}

		if(!BN_hex2bn(&bn_signature, (const char *)signature)) {
			openssl_strerror("BN_hex2bn");
			return(sigcomp_return(false,
				bn_key, bn_msg, bn_signature));
		}

		if(!sigcomp_vrfy(evp_md, bn_key, bn_msg, bn_signature, type)) {
			return(sigcomp_return(false,
				bn_key, bn_msg, bn_signature));
		}
	} else {
		if(!sigcomp_sign(evp_md, bn_key, bn_msg, type)) {
			return(sigcomp_return(false,
				bn_key, bn_msg, bn_signature));
		}
	}

	return(sigcomp_return(true, bn_key, bn_msg, bn_signature));
}



static bool
sigcomp_return(const bool code,
	BIGNUM *bn_key, BIGNUM *bn_msg, BIGNUM *bn_signature)
{
	if(bn_signature) {
		BN_free(bn_signature); bn_signature = NULL;
	}

	if(bn_msg) {
		BN_free(bn_msg); bn_msg = NULL;
	}

	if(bn_key) {
		BN_free(bn_key); bn_key = NULL;
	}

	return(code);
}



static bool
sigcomp_sign(const EVP_MD *const evp_md, const BIGNUM *const bn_key,
	const BIGNUM *const bn_msg, const char *const type)
{
	EVP_PKEY *pkey			= NULL;
	unsigned char *key		= NULL;
	unsigned char *msg		= NULL;
	unsigned char *signature	= NULL;
	unsigned char *ptr = NULL;

	int keylen		= 0;
	int msglen		= 0;
	int signaturelen	= 0;
	int padding		= 0;

	/* bn_key -> key */
	if(!(keylen = BN_num_bytes(bn_key))) {
		openssl_strerror("BN_num_bytes");
		return(sigcomp_sign_return(false, key, msg, signature, pkey));
	}

	if(!(key = (unsigned char *)malloc(keylen))) {
		fprintf(stderr, "err: malloc: %s\n", strerror(errno));
		return(sigcomp_sign_return(false, key, msg, signature, pkey));
	}

	if(BN_bn2bin(bn_key, key) != keylen) {
		openssl_strerror("BN_bn2bin");
		return(sigcomp_sign_return(false, key, msg, signature, pkey));
	}
#ifdef DEBUG
	dmp(stderr, "key", key, keylen);
#endif	// DEBUG
	/* bn_msg -> msg */
	if(!(msglen = BN_num_bytes(bn_msg))) {
		openssl_strerror("BN_num_bytes");
		return(sigcomp_sign_return(false, key, msg, signature, pkey));
	}

	if(!(msg = (unsigned char *)malloc(msglen))) {
		fprintf(stderr, "err: malloc: %s\n", strerror(errno));
		return(sigcomp_sign_return(false, key, msg, signature, pkey));
	}

	if(BN_bn2bin(bn_msg, msg) != msglen) {
		openssl_strerror("BN_bn2bin");
		return(sigcomp_sign_return(false, key, msg, signature, pkey));
	}
#ifdef DEBUG
	dmp(stderr, "msg", msg, msglen);
#endif	// DEBUG
	ptr = key;

	for( ; ; ) {
		if(!strcmp(type, "rsa")) {
#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
			if(!(pkey = d2i_PrivateKey(EVP_PKEY_RSA,
				NULL, (const unsigned char **)&ptr, keylen))) {
#else
			if(!(pkey = d2i_PrivateKey(EVP_PKEY_RSA,
				NULL, &ptr, keylen))) {
#endif
				openssl_strerror("d2i_PrivateKey");
				return(sigcomp_sign_return(false,
					key, msg, signature, pkey));
			}

			signaturelen	= RSA_size(pkey->pkey.rsa);
			padding		= RSA_PKCS1_PADDING;

			break;
		}

		if(!strcmp(type, "dsa")) {
#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
			if(!(pkey = d2i_PrivateKey(EVP_PKEY_DSA,
				NULL, (const unsigned char **)&ptr, keylen))) {
#else
			if(!(pkey = d2i_PrivateKey(EVP_PKEY_DSA,
				NULL, &ptr, keylen))) {
#endif

				openssl_strerror("d2i_PrivateKey");
				return(sigcomp_sign_return(false,
					key, msg, signature, pkey));
			}

			fprintf(stderr, "err: type: %s -- not implemented\n",
				type);

			return(sigcomp_sign_return(false,
				key, msg, signature, pkey));

			break;
		}

		fprintf(stderr, "err: type: %s -- unknown type\n",
			type);

		return(sigcomp_sign_return(false, key, msg, signature, pkey));
		/* NOTREACHED */
	}

	if(!(signature = (unsigned char *)malloc(signaturelen))) {
		fprintf(stderr, "err: malloc: %s\n", strerror(errno));
		return(sigcomp_sign_return(false, key, msg, signature, pkey));
	}

	RSA_private_encrypt(msglen, msg, signature, pkey->pkey.rsa, padding);
#ifdef DEBUG
	dmp(stderr, "signature", signature, signaturelen);
#endif	// DEBUG
	sigcomp_sign_dump(key, keylen, msg, msglen, signature, signaturelen);

	return(sigcomp_sign_return(true, key, msg, signature, pkey));
}



static void
sigcomp_sign_dump(const unsigned char *const key, int keylen,
	const unsigned char *const msg, int msglen,
	const unsigned char *const signature, int signaturelen)
{
	int d = 0;

	if(xxxflag) {
#if 0	/* needless */
		for(d = 0; d < msglen; d ++) {
			printf("%02x", msg[d]);
		}
#endif
		for(d = 0; d < signaturelen; d ++) {
			printf("%02x", signature[d]);
		}

		printf("\n");

		return;
	}

	printf("log:SigCompSign_Results             (length:%d)\n",
		keylen + msglen + signaturelen);

	printf("log:| PrivateKey                      (length:%d)\n", keylen);
	printf("log:| | data                             = ");

	for(d = 0; d < keylen; d ++) {
		printf("%02x", key[d]);
	}

	printf("\n");

	printf("log:| Message                         (length:%d)\n", msglen);
	printf("log:| | data                             = ");

	for(d = 0; d < msglen; d ++) {
		printf("%02x", msg[d]);
	}

	printf("\n");

	printf("log:| Signature                       (length:%d)\n",
		signaturelen);

	printf("log:| | data                             = ");

	for(d = 0; d < signaturelen; d ++) {
		printf("%02x", signature[d]);
	}

	printf("\n");

	return;
}



static bool
sigcomp_sign_return(const bool code,
	unsigned char *key, unsigned char *msg, unsigned char *signature,
	EVP_PKEY *pkey)
{
	if(pkey) {
		EVP_PKEY_free(pkey); pkey = NULL;
	}

	if(signature) {
		free(signature); signature = NULL;
	}

	if(msg) {
		free(msg); msg = NULL;
	}

	if(key) {
		free(key); key = NULL;
	}

	return(code);
}



static bool
sigcomp_vrfy(const EVP_MD *const evp_md, const BIGNUM *const bn_key,
	const BIGNUM *const bn_msg,
	const BIGNUM *const bn_signature, const char *const type)
{
	EVP_PKEY *pkey  = NULL;

	unsigned char *key		= NULL;
	unsigned char *msg		= NULL;
	unsigned char *signature	= NULL;
	unsigned char *to		= NULL;
	unsigned char *ptr		= NULL;

	int keylen		= 0;
	int msglen		= 0;
	int signaturelen	= 0;
	int tolen		= 0;
	int padding		= 0;

	bool compare		= true;

	/* bn_key -> key */
	if(!(keylen = BN_num_bytes(bn_key))) {
		openssl_strerror("BN_num_bytes");
		return(sigcomp_vrfy_return(false,
			key, msg, signature, to, pkey));
	}

	if(!(key = (unsigned char *)malloc(keylen))) {
		fprintf(stderr, "err: malloc: %s\n", strerror(errno));
		return(sigcomp_vrfy_return(false,
			key, msg, signature, to, pkey));
	}

	if(BN_bn2bin(bn_key, key) != keylen) {
		openssl_strerror("BN_bn2bin");
		return(sigcomp_vrfy_return(false,
			key, msg, signature, to, pkey));
	}
#ifdef DEBUG
	dmp(stderr, "key", key, keylen);
#endif  // DEBUG
	/* bn_msg -> msg */
        if(!(msglen = BN_num_bytes(bn_msg))) {
		openssl_strerror("BN_num_bytes");
		return(sigcomp_vrfy_return(false,
			key, msg, signature, to, pkey));
        }

	if(!(msg = (unsigned char *)malloc(msglen))) {
		fprintf(stderr, "err: malloc: %s\n", strerror(errno));
		return(sigcomp_vrfy_return(false,
			key, msg, signature, to, pkey));
	}

	if(BN_bn2bin(bn_msg, msg) != msglen) {
		openssl_strerror("BN_bn2bin");
		return(sigcomp_vrfy_return(false,
			key, msg, signature, to, pkey));
	}
#ifdef DEBUG
	dmp(stderr, "msg", msg, msglen);
#endif  // DEBUG
	/* bn_signature -> signature */
        if(!(signaturelen = BN_num_bytes(bn_signature))) {
		openssl_strerror("BN_num_bytes");
		return(sigcomp_vrfy_return(false,
			key, msg, signature, to, pkey));
        }

	if(!(signature = (unsigned char *)malloc(signaturelen))) {
		fprintf(stderr, "err: malloc: %s\n", strerror(errno));
		return(sigcomp_vrfy_return(false,
			key, msg, signature, to, pkey));
	}

	if(BN_bn2bin(bn_signature, signature) != signaturelen) {
		openssl_strerror("BN_bn2bin");
		return(sigcomp_vrfy_return(false,
			key, msg, signature, to, pkey));
	}
#ifdef DEBUG
	dmp(stderr, "signature", signature, signaturelen);
#endif  // DEBUG
        ptr = key;

	for( ; ; ) {
		if(!strcmp(type, "rsa")) {
#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
			if(!(pkey = d2i_PublicKey(EVP_PKEY_RSA,
				NULL, (const unsigned char **)&ptr, keylen))) {
#else
			if(!(pkey = d2i_PublicKey(EVP_PKEY_RSA,
				NULL, &ptr, keylen))) {
#endif

				openssl_strerror("d2i_PublicKey");
				return(sigcomp_vrfy_return(false,
					key, msg, signature, to, pkey));
			}

			tolen		= RSA_size(pkey->pkey.rsa);
			padding		= RSA_PKCS1_PADDING;

			break;
		}

		if(!strcmp(type, "dsa")) {
#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
			if(!(pkey = d2i_PublicKey(EVP_PKEY_DSA,
				NULL, (const unsigned char **)&ptr, keylen))) {
#else
			if(!(pkey = d2i_PublicKey(EVP_PKEY_DSA,
				NULL, &ptr, keylen))) {
#endif

				openssl_strerror("d2i_PublicKey");
				return(sigcomp_vrfy_return(false,
					key, msg, signature, to, pkey));
			}

			fprintf(stderr, "err: type: %s -- not implemented\n",
				type);

			return(sigcomp_vrfy_return(false,
				key, msg, signature, to, pkey));
			/* NOTREACHED */

			break;
		}

		fprintf(stderr, "err: type: %s -- unknown type\n",
			type);

		return(sigcomp_vrfy_return(false,
			key, msg, signature, to, pkey));
		/* NOTREACHED */
	}

	if(!(to = (unsigned char *)malloc(tolen))) {
		fprintf(stderr, "err: malloc: %s\n", strerror(errno));
		return(sigcomp_vrfy_return(false,
			key, msg, signature, to, pkey));
	}

	if(RSA_public_decrypt(signaturelen,
		signature, to, pkey->pkey.rsa, padding) < 0) {

		openssl_strerror("RSA_public_decrypt");
		return(sigcomp_vrfy_return(true,
			key, msg, signature, to, pkey));
	}

	if(memcmp(msg, to, msglen)) {
		compare	= false;
	}

	sigcomp_vrfy_dump(compare, key, keylen,
		msg, msglen, signature, signaturelen, to, tolen);

	return(sigcomp_vrfy_return(true, key, msg, signature, to, pkey));
}



static void
sigcomp_vrfy_dump(const bool code, const unsigned char *const key, int keylen,
	const unsigned char *const msg, int msglen,
	const unsigned char *const signature, int signaturelen,
	const unsigned char *const to, int tolen)
{
	int d = 0;

	printf("log:SigCompVrfy_Results             (length:%d)\n",
		keylen + msglen + signaturelen + tolen);

	printf("log:| PublicKey                       (length:%d)\n", keylen);
	printf("log:| | data                             = ");

	for(d = 0; d < keylen; d ++) {
		printf("%02x", key[d]);
	}

	printf("\n");

	printf("log:| Message                         (length:%d)\n", msglen);
	printf("log:| | data                             = ");

	for(d = 0; d < msglen; d ++) {
		printf("%02x", msg[d]);
	}

	printf("\n");

	printf("log:| Signature                       (length:%d)\n",
		signaturelen + tolen);

	printf("log:| | status                           = %s\n",
		code? "true": "false");

	printf("log:| | Encrypted                       (length:%d)\n",
		signaturelen);

	printf("log:| | | data                             = ");

	for(d = 0; d < signaturelen; d ++) {
		printf("%02x", signature[d]);
	}

	printf("\n");

	printf("log:| | Decrypted                       (length:%d)\n", tolen);
	printf("log:| | | data                             = ");

	for(d = 0; d < tolen; d ++) {
		printf("%02x", to[d]);
	}

	printf("\n");

	return;
}



static bool
sigcomp_vrfy_return(const bool code,
	unsigned char *key, unsigned char *msg, unsigned char *signature,
	unsigned char *to, EVP_PKEY *pkey)
{
	if(pkey) {
		EVP_PKEY_free(pkey); pkey = NULL;
	}

	if(to) {
		free(to); to = NULL;
	}

	if(signature) {
		free(signature); signature = NULL;
	}

	if(msg) {
		free(msg); msg = NULL;
	}

	if(key) {
		free(key); key = NULL;
	}

	return(code);
}



static const EVP_MD *
evp_md_with_algorithm(const char *const type, const char *const algorithm)
{
	const EVP_MD *evp_md	= NULL;
	bool dsa	= false;
	bool rsa	= false;

	for( ; ; ) {
		if(!strcmp(type, "dsa")) {
			dsa = true;
			break;
		}

		if(!strcmp(type, "rsa")) {
			rsa = true;
			break;
		}

		break;
	}

	for( ; ; ) {
		if(dsa && !strcmp(algorithm, "dss1")) {
			evp_md = EVP_dss1();
			break;
		}

		if(rsa && !strcmp(algorithm, "md2")) {
			evp_md = EVP_md2();
			break;
		}

		if(rsa && !strcmp(algorithm, "md4")) {
			evp_md = EVP_md4();
			break;
		}

		if(rsa && !strcmp(algorithm, "md5")) {
			evp_md = EVP_md5();
			break;
		}

#if ! defined(__linux__)
		if(rsa && !strcmp(algorithm, "mdc2")) {
			evp_md = EVP_mdc2();
			break;
		}
#endif

		if(rsa && !strcmp(algorithm, "ripemd160")) {
			evp_md = EVP_ripemd160();
			break;
		}

		if(rsa && !strcmp(algorithm, "sha1")) {
			evp_md = EVP_sha1();
			break;
		}

		break;
	}

	return(evp_md);
}



static void
openssl_strerror(const char *const label)
{
	unsigned long code = 0;

	while((code = ERR_get_error())) {
		fprintf(stderr, "err: %s: %s\n",
			label, ERR_error_string(code, NULL));
	}

	return;
}
コード例 #12
0
ファイル: fips_dsatest.c プロジェクト: peterlingoal/openssl
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);
	}
コード例 #13
0
ファイル: val_secalgo.c プロジェクト: jaredmcneill/freebsd
/**
 * Setup key and digest for verification. Adjust sig if necessary.
 *
 * @param algo: key algorithm
 * @param evp_key: EVP PKEY public key to create.
 * @param digest_type: digest type to use
 * @param key: key to setup for.
 * @param keylen: length of key.
 * @return false on failure.
 */
static int
setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
                 unsigned char* key, size_t keylen)
{
#ifdef USE_DSA
    DSA* dsa;
#endif
    RSA* rsa;

    switch(algo) {
#ifdef USE_DSA
    case LDNS_DSA:
    case LDNS_DSA_NSEC3:
        *evp_key = EVP_PKEY_new();
        if(!*evp_key) {
            log_err("verify: malloc failure in crypto");
            return 0;
        }
        dsa = sldns_key_buf2dsa_raw(key, keylen);
        if(!dsa) {
            verbose(VERB_QUERY, "verify: "
                    "sldns_key_buf2dsa_raw failed");
            return 0;
        }
        if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) {
            verbose(VERB_QUERY, "verify: "
                    "EVP_PKEY_assign_DSA failed");
            return 0;
        }
        *digest_type = EVP_dss1();

        break;
#endif /* USE_DSA */
    case LDNS_RSASHA1:
    case LDNS_RSASHA1_NSEC3:
#if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
    case LDNS_RSASHA256:
#endif
#if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
    case LDNS_RSASHA512:
#endif
        *evp_key = EVP_PKEY_new();
        if(!*evp_key) {
            log_err("verify: malloc failure in crypto");
            return 0;
        }
        rsa = sldns_key_buf2rsa_raw(key, keylen);
        if(!rsa) {
            verbose(VERB_QUERY, "verify: "
                    "sldns_key_buf2rsa_raw SHA failed");
            return 0;
        }
        if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
            verbose(VERB_QUERY, "verify: "
                    "EVP_PKEY_assign_RSA SHA failed");
            return 0;
        }

        /* select SHA version */
#if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
        if(algo == LDNS_RSASHA256)
            *digest_type = EVP_sha256();
        else
#endif
#if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
            if(algo == LDNS_RSASHA512)
                *digest_type = EVP_sha512();
            else
#endif
                *digest_type = EVP_sha1();

        break;
    case LDNS_RSAMD5:
        *evp_key = EVP_PKEY_new();
        if(!*evp_key) {
            log_err("verify: malloc failure in crypto");
            return 0;
        }
        rsa = sldns_key_buf2rsa_raw(key, keylen);
        if(!rsa) {
            verbose(VERB_QUERY, "verify: "
                    "sldns_key_buf2rsa_raw MD5 failed");
            return 0;
        }
        if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
            verbose(VERB_QUERY, "verify: "
                    "EVP_PKEY_assign_RSA MD5 failed");
            return 0;
        }
        *digest_type = EVP_md5();

        break;
#ifdef USE_GOST
    case LDNS_ECC_GOST:
        *evp_key = sldns_gost2pkey_raw(key, keylen);
        if(!*evp_key) {
            verbose(VERB_QUERY, "verify: "
                    "sldns_gost2pkey_raw failed");
            return 0;
        }
        *digest_type = EVP_get_digestbyname("md_gost94");
        if(!*digest_type) {
            verbose(VERB_QUERY, "verify: "
                    "EVP_getdigest md_gost94 failed");
            return 0;
        }
        break;
#endif
#ifdef USE_ECDSA
    case LDNS_ECDSAP256SHA256:
        *evp_key = sldns_ecdsa2pkey_raw(key, keylen,
                                        LDNS_ECDSAP256SHA256);
        if(!*evp_key) {
            verbose(VERB_QUERY, "verify: "
                    "sldns_ecdsa2pkey_raw failed");
            return 0;
        }
#ifdef USE_ECDSA_EVP_WORKAROUND
        *digest_type = &ecdsa_evp_256_md;
#else
        *digest_type = EVP_sha256();
#endif
        break;
    case LDNS_ECDSAP384SHA384:
        *evp_key = sldns_ecdsa2pkey_raw(key, keylen,
                                        LDNS_ECDSAP384SHA384);
        if(!*evp_key) {
            verbose(VERB_QUERY, "verify: "
                    "sldns_ecdsa2pkey_raw failed");
            return 0;
        }
#ifdef USE_ECDSA_EVP_WORKAROUND
        *digest_type = &ecdsa_evp_384_md;
#else
        *digest_type = EVP_sha384();
#endif
        break;
#endif /* USE_ECDSA */
    default:
        verbose(VERB_QUERY, "verify: unknown algorithm %d",
                algo);
        return 0;
    }
    return 1;
}
コード例 #14
0
// reads the request req_filename and creates a modified creq_filename with the commitment extension added
void writeCommitmentCSR(BIGNUM *commitment_c, char *privkey_filename, char *req_filename, char *creq_filename) {
	FILE *fp;

	/* read in the request */
	X509_REQ *req;
	if (!(fp = fopen(req_filename, "r")))
		critical_error("Error reading request file");
	if (!(req = PEM_read_X509_REQ(fp, NULL, NULL, NULL)))
		critical_error("Error reading request in file");
	fclose(fp);

	/*  read in the private key */
	EVP_PKEY *pkey;
	if (!(fp = fopen(privkey_filename, "r")))
		critical_error("Error reading private key file");
	if (!(pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)))
		critical_error("Error reading private key in file");
	fclose(fp);

	/* create the new request */
	X509_REQ *creq;
	if (!(creq = X509_REQ_new()))
		critical_error("Failed to create X509_REQ object");

	X509_REQ_set_pubkey(creq, pkey);

	// gets subj from initial requests and adds it to new one
	X509_NAME *subj = X509_REQ_get_subject_name(req);
	if (X509_REQ_set_subject_name(creq, subj) != 1)
			critical_error("Error adding subject to request");

	// enable the commitment extension handling (retrieve/print as string)
	int nid = _commitmentExt_start();

	// get extensions stack of original request
	STACK_OF(X509_EXTENSION) *extlist = X509_REQ_get_extensions(req);

	// if no extensions, create new stack
	if (extlist==NULL) {
		extlist = sk_X509_EXTENSION_new_null();
	} else { // else check that the extension isn't already there (error!)
		X509_EXTENSION *tmp = (X509_EXTENSION*) X509V3_get_d2i(extlist, nid, NULL, NULL);
		if (tmp!=NULL)
			critical_error("Aborting process: CSR already contains commitment extension!\n");		
	}

	// create commitment extension storing C value as a hex string
	X509_EXTENSION *exCommitment = (X509_EXTENSION*) X509V3_EXT_conf_nid(NULL, NULL, nid, BN_bn2hex(commitment_c));
	if (!exCommitment)
		critical_error("error creating commitment extension");

	// push commitment extension into stack
	sk_X509_EXTENSION_push(extlist, exCommitment);

	// assign extensions to the new request
	if (!X509_REQ_add_extensions(creq, extlist))
		critical_error("Error adding extensions to the request");

	sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
	/////////////////////////////////////////////////////////////////////

	/* pick the correct digest and sign the new request */
	EVP_MD *digest;
	if (EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA)
		digest = (EVP_MD*) EVP_dss1();
	else if (EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA)
		digest = (EVP_MD*) EVP_sha1();
	else
		critical_error("Error checking public key for a valid digest");

	if (!(X509_REQ_sign(creq, pkey, digest)))
		critical_error("Error signing request");

	/* write the modified request */
	if (!(fp = fopen(creq_filename, "w")))
		critical_error("Error writing to request file");
	if (PEM_write_X509_REQ(fp, creq) != 1)
		critical_error("Error while writing request");
	fclose(fp);

	// cleanup
	_commitmentExt_end();
	EVP_PKEY_free(pkey);
	X509_REQ_free(req);
	X509_REQ_free(creq);
}
コード例 #15
0
ファイル: dnssec_sign.c プロジェクト: mbuij/ldns-cga-tsig
ldns_rdf *
ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
{
	ldns_rdf *b64rdf = NULL;

	switch(ldns_key_algorithm(current_key)) {
	case LDNS_SIGN_DSA:
	case LDNS_SIGN_DSA_NSEC3:
		b64rdf = ldns_sign_public_evp(
				   sign_buf,
				   ldns_key_evp_key(current_key),
				   EVP_dss1());
		break;
	case LDNS_SIGN_RSASHA1:
	case LDNS_SIGN_RSASHA1_NSEC3:
		b64rdf = ldns_sign_public_evp(
				   sign_buf,
				   ldns_key_evp_key(current_key),
				   EVP_sha1());
		break;
#ifdef USE_SHA2
	case LDNS_SIGN_RSASHA256:
		b64rdf = ldns_sign_public_evp(
				   sign_buf,
				   ldns_key_evp_key(current_key),
				   EVP_sha256());
		break;
	case LDNS_SIGN_RSASHA512:
		b64rdf = ldns_sign_public_evp(
				   sign_buf,
				   ldns_key_evp_key(current_key),
				   EVP_sha512());
		break;
#endif /* USE_SHA2 */
#ifdef USE_GOST
	case LDNS_SIGN_ECC_GOST:
		b64rdf = ldns_sign_public_evp(
				   sign_buf,
				   ldns_key_evp_key(current_key),
				   EVP_get_digestbyname("md_gost94"));
		break;
#endif /* USE_GOST */
#ifdef USE_ECDSA
        case LDNS_SIGN_ECDSAP256SHA256:
       		b64rdf = ldns_sign_public_evp(
				   sign_buf,
				   ldns_key_evp_key(current_key),
				   EVP_sha256());
                break;
        case LDNS_SIGN_ECDSAP384SHA384:
       		b64rdf = ldns_sign_public_evp(
				   sign_buf,
				   ldns_key_evp_key(current_key),
				   EVP_sha384());
                break;
#endif
	case LDNS_SIGN_RSAMD5:
		b64rdf = ldns_sign_public_evp(
				   sign_buf,
				   ldns_key_evp_key(current_key),
				   EVP_md5());
		break;
	default:
		/* do _you_ know this alg? */
		printf("unknown algorithm, ");
		printf("is the one used available on this system?\n");
		break;
	}

	return b64rdf;
}
コード例 #16
0
ファイル: x509.c プロジェクト: xyzy/mips-openssl_0.9.7
int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	int ret=1;
	X509_REQ *req=NULL;
	X509 *x=NULL,*xca=NULL;
	ASN1_OBJECT *objtmp;
	EVP_PKEY *Upkey=NULL,*CApkey=NULL;
	ASN1_INTEGER *sno = NULL;
	int i,num,badops=0;
	BIO *out=NULL;
	BIO *STDout=NULL;
	STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
	int informat,outformat,keyformat,CAformat,CAkeyformat;
	char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
	char *CAkeyfile=NULL,*CAserial=NULL;
	char *alias=NULL;
	int text=0,serial=0,hash=0,subject=0,issuer=0,startdate=0,enddate=0;
	int ocspid=0;
	int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
	int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
	int C=0;
	int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
	int pprint = 0;
	char **pp;
	X509_STORE *ctx=NULL;
	X509_REQ *rq=NULL;
	int fingerprint=0;
	char buf[256];
	const EVP_MD *md_alg,*digest=EVP_md5();
	CONF *extconf = NULL;
	char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
	int need_rand = 0;
	int checkend=0,checkoffset=0;
	unsigned long nmflag = 0, certflag = 0;
	char *engine=NULL;

	reqfile=0;

	apps_startup();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;
	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	STDout = BIO_push(tmpbio, STDout);
	}
#endif

	informat=FORMAT_PEM;
	outformat=FORMAT_PEM;
	keyformat=FORMAT_PEM;
	CAformat=FORMAT_PEM;
	CAkeyformat=FORMAT_PEM;

	ctx=X509_STORE_new();
	if (ctx == NULL) goto end;
	X509_STORE_set_verify_cb_func(ctx,callb);

	argc--;
	argv++;
	num=0;
	while (argc >= 1)
		{
		if 	(strcmp(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-outform") == 0)
			{
			if (--argc < 1) goto bad;
			outformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-keyform") == 0)
			{
			if (--argc < 1) goto bad;
			keyformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-req") == 0)
			{
			reqfile=1;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CAform") == 0)
			{
			if (--argc < 1) goto bad;
			CAformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-CAkeyform") == 0)
			{
			if (--argc < 1) goto bad;
			CAkeyformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-days") == 0)
			{
			if (--argc < 1) goto bad;
			days=atoi(*(++argv));
			if (days == 0)
				{
				BIO_printf(STDout,"bad number of days\n");
				goto bad;
				}
			}
		else if (strcmp(*argv,"-passin") == 0)
			{
			if (--argc < 1) goto bad;
			passargin= *(++argv);
			}
		else if (strcmp(*argv,"-extfile") == 0)
			{
			if (--argc < 1) goto bad;
			extfile= *(++argv);
			}
		else if (strcmp(*argv,"-extensions") == 0)
			{
			if (--argc < 1) goto bad;
			extsect= *(++argv);
			}
		else if (strcmp(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (strcmp(*argv,"-signkey") == 0)
			{
			if (--argc < 1) goto bad;
			keyfile= *(++argv);
			sign_flag= ++num;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CA") == 0)
			{
			if (--argc < 1) goto bad;
			CAfile= *(++argv);
			CA_flag= ++num;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CAkey") == 0)
			{
			if (--argc < 1) goto bad;
			CAkeyfile= *(++argv);
			}
		else if (strcmp(*argv,"-CAserial") == 0)
			{
			if (--argc < 1) goto bad;
			CAserial= *(++argv);
			}
		else if (strcmp(*argv,"-set_serial") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
				goto bad;
			}
		else if (strcmp(*argv,"-addtrust") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
				{
				BIO_printf(bio_err,
					"Invalid trust object value %s\n", *argv);
				goto bad;
				}
			if (!trust) trust = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(trust, objtmp);
			trustout = 1;
			}
		else if (strcmp(*argv,"-addreject") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
				{
				BIO_printf(bio_err,
					"Invalid reject object value %s\n", *argv);
				goto bad;
				}
			if (!reject) reject = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(reject, objtmp);
			trustout = 1;
			}
		else if (strcmp(*argv,"-setalias") == 0)
			{
			if (--argc < 1) goto bad;
			alias= *(++argv);
			trustout = 1;
			}
		else if (strcmp(*argv,"-certopt") == 0)
			{
			if (--argc < 1) goto bad;
			if (!set_cert_ex(&certflag, *(++argv))) goto bad;
			}
		else if (strcmp(*argv,"-nameopt") == 0)
			{
			if (--argc < 1) goto bad;
			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
			}
		else if (strcmp(*argv,"-setalias") == 0)
			{
			if (--argc < 1) goto bad;
			alias= *(++argv);
			trustout = 1;
			}
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
		else if (strcmp(*argv,"-C") == 0)
			C= ++num;
		else if (strcmp(*argv,"-email") == 0)
			email= ++num;
		else if (strcmp(*argv,"-serial") == 0)
			serial= ++num;
		else if (strcmp(*argv,"-modulus") == 0)
			modulus= ++num;
		else if (strcmp(*argv,"-pubkey") == 0)
			pubkey= ++num;
		else if (strcmp(*argv,"-x509toreq") == 0)
			x509req= ++num;
		else if (strcmp(*argv,"-text") == 0)
			text= ++num;
		else if (strcmp(*argv,"-hash") == 0)
			hash= ++num;
		else if (strcmp(*argv,"-subject") == 0)
			subject= ++num;
		else if (strcmp(*argv,"-issuer") == 0)
			issuer= ++num;
		else if (strcmp(*argv,"-fingerprint") == 0)
			fingerprint= ++num;
		else if (strcmp(*argv,"-dates") == 0)
			{
			startdate= ++num;
			enddate= ++num;
			}
		else if (strcmp(*argv,"-purpose") == 0)
			pprint= ++num;
		else if (strcmp(*argv,"-startdate") == 0)
			startdate= ++num;
		else if (strcmp(*argv,"-enddate") == 0)
			enddate= ++num;
		else if (strcmp(*argv,"-checkend") == 0)
			{
			if (--argc < 1) goto bad;
			checkoffset=atoi(*(++argv));
			checkend=1;
			}
		else if (strcmp(*argv,"-noout") == 0)
			noout= ++num;
		else if (strcmp(*argv,"-trustout") == 0)
			trustout= 1;
		else if (strcmp(*argv,"-clrtrust") == 0)
			clrtrust= ++num;
		else if (strcmp(*argv,"-clrreject") == 0)
			clrreject= ++num;
		else if (strcmp(*argv,"-alias") == 0)
			aliasout= ++num;
		else if (strcmp(*argv,"-CAcreateserial") == 0)
			CA_createserial= ++num;
		else if (strcmp(*argv,"-clrext") == 0)
			clrext = 1;
#if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */
		else if (strcmp(*argv,"-crlext") == 0)
			{
			BIO_printf(bio_err,"use -clrext instead of -crlext\n");
			clrext = 1;
			}
#endif
		else if (strcmp(*argv,"-ocspid") == 0)
			ocspid= ++num;
		else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
			{
			/* ok */
			digest=md_alg;
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		for (pp=x509_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,"%s",*pp);
		goto end;
		}

        e = setup_engine(bio_err, engine, 0);

	if (need_rand)
		app_RAND_load_file(NULL, bio_err, 0);

	ERR_load_crypto_strings();

	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
		{
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
		}

	if (!X509_STORE_set_default_paths(ctx))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM))
		{ CAkeyfile=CAfile; }
	else if ((CA_flag) && (CAkeyfile == NULL))
		{
		BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n");
		goto end;
		}

	if (extfile)
		{
		long errorline = -1;
		X509V3_CTX ctx2;
		extconf = NCONF_new(NULL);
		if (!NCONF_load(extconf, extfile,&errorline))
			{
			if (errorline <= 0)
				BIO_printf(bio_err,
					"error loading the config file '%s'\n",
								extfile);
                	else
                        	BIO_printf(bio_err,
				       "error on line %ld of config file '%s'\n"
							,errorline,extfile);
			goto end;
			}
		if (!extsect)
			{
			extsect = NCONF_get_string(extconf, "default", "extensions");
			if (!extsect)
				{
				ERR_clear_error();
				extsect = "default";
				}
			}
		X509V3_set_ctx_test(&ctx2);
		X509V3_set_nconf(&ctx2, extconf);
		if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL))
			{
			BIO_printf(bio_err,
				"Error Loading extension section %s\n",
								 extsect);
			ERR_print_errors(bio_err);
			goto end;
			}
		}


	if (reqfile)
		{
		EVP_PKEY *pkey;
		X509_CINF *ci;
		BIO *in;

		if (!sign_flag && !CA_flag)
			{
			BIO_printf(bio_err,"We need a private key to sign with\n");
			goto end;
			}
		in=BIO_new(BIO_s_file());
		if (in == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}

		if (infile == NULL)
			BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
		else
			{
			if (BIO_read_filename(in,infile) <= 0)
				{
				perror(infile);
				BIO_free(in);
				goto end;
				}
			}
		req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
		BIO_free(in);

		if (req == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}

		if (	(req->req_info == NULL) ||
			(req->req_info->pubkey == NULL) ||
			(req->req_info->pubkey->public_key == NULL) ||
			(req->req_info->pubkey->public_key->data == NULL))
			{
			BIO_printf(bio_err,"The certificate request appears to corrupted\n");
			BIO_printf(bio_err,"It does not contain a public key\n");
			goto end;
			}
		if ((pkey=X509_REQ_get_pubkey(req)) == NULL)
	                {
	                BIO_printf(bio_err,"error unpacking public key\n");
	                goto end;
	                }
		i=X509_REQ_verify(req,pkey);
		EVP_PKEY_free(pkey);
		if (i < 0)
			{
			BIO_printf(bio_err,"Signature verification error\n");
			ERR_print_errors(bio_err);
			goto end;
			}
	        if (i == 0)
			{
			BIO_printf(bio_err,"Signature did not match the certificate request\n");
			goto end;
			}
		else
			BIO_printf(bio_err,"Signature ok\n");

		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag);

		if ((x=X509_new()) == NULL) goto end;
		ci=x->cert_info;

		if (sno)
			{
			if (!X509_set_serialNumber(x, sno))
				goto end;
			}
		else if (!ASN1_INTEGER_set(X509_get_serialNumber(x),0)) goto end;
		if (!X509_set_issuer_name(x,req->req_info->subject)) goto end;
		if (!X509_set_subject_name(x,req->req_info->subject)) goto end;

		X509_gmtime_adj(X509_get_notBefore(x),0);
	        X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);

		pkey = X509_REQ_get_pubkey(req);
		X509_set_pubkey(x,pkey);
		EVP_PKEY_free(pkey);
		}
	else
		x=load_cert(bio_err,infile,informat,NULL,e,"Certificate");

	if (x == NULL) goto end;
	if (CA_flag)
		{
		xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate");
		if (xca == NULL) goto end;
		}

	if (!noout || text)
		{
		OBJ_create("2.99999.3",
			"SET.ex3","SET x509v3 extension 3");

		out=BIO_new(BIO_s_file());
		if (out == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		if (outfile == NULL)
			{
			BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
			{
			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
			out = BIO_push(tmpbio, out);
			}
#endif
			}
		else
			{
			if (BIO_write_filename(out,outfile) <= 0)
				{
				perror(outfile);
				goto end;
				}
			}
		}

	if (alias) X509_alias_set1(x, (unsigned char *)alias, -1);

	if (clrtrust) X509_trust_clear(x);
	if (clrreject) X509_reject_clear(x);

	if (trust)
		{
		for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++)
			{
			objtmp = sk_ASN1_OBJECT_value(trust, i);
			X509_add1_trust_object(x, objtmp);
			}
		}

	if (reject)
		{
		for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++)
			{
			objtmp = sk_ASN1_OBJECT_value(reject, i);
			X509_add1_reject_object(x, objtmp);
			}
		}

	if (num)
		{
		for (i=1; i<=num; i++)
			{
			if (issuer == i)
				{
				print_name(STDout, "issuer= ",
					X509_get_issuer_name(x), nmflag);
				}
			else if (subject == i) 
				{
				print_name(STDout, "subject= ",
					X509_get_subject_name(x), nmflag);
				}
			else if (serial == i)
				{
				BIO_printf(STDout,"serial=");
				i2a_ASN1_INTEGER(STDout,x->cert_info->serialNumber);
				BIO_printf(STDout,"\n");
				}
			else if (email == i) 
				{
				int j;
				STACK *emlst;
				emlst = X509_get1_email(x);
				for (j = 0; j < sk_num(emlst); j++)
					BIO_printf(STDout, "%s\n", sk_value(emlst, j));
				X509_email_free(emlst);
				}
			else if (aliasout == i)
				{
				unsigned char *alstr;
				alstr = X509_alias_get0(x, NULL);
				if (alstr) BIO_printf(STDout,"%s\n", alstr);
				else BIO_puts(STDout,"<No Alias>\n");
				}
			else if (hash == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
				}
			else if (pprint == i)
				{
				X509_PURPOSE *ptmp;
				int j;
				BIO_printf(STDout, "Certificate purposes:\n");
				for (j = 0; j < X509_PURPOSE_get_count(); j++)
					{
					ptmp = X509_PURPOSE_get0(j);
					purpose_print(STDout, x, ptmp);
					}
				}
			else
				if (modulus == i)
				{
				EVP_PKEY *pkey;

				pkey=X509_get_pubkey(x);
				if (pkey == NULL)
					{
					BIO_printf(bio_err,"Modulus=unavailable\n");
					ERR_print_errors(bio_err);
					goto end;
					}
				BIO_printf(STDout,"Modulus=");
#ifndef OPENSSL_NO_RSA
				if (pkey->type == EVP_PKEY_RSA)
					BN_print(STDout,pkey->pkey.rsa->n);
				else
#endif
#ifndef OPENSSL_NO_DSA
				if (pkey->type == EVP_PKEY_DSA)
					BN_print(STDout,pkey->pkey.dsa->pub_key);
				else
#endif
					BIO_printf(STDout,"Wrong Algorithm type");
				BIO_printf(STDout,"\n");
				EVP_PKEY_free(pkey);
				}
			else
				if (pubkey == i)
				{
				EVP_PKEY *pkey;

				pkey=X509_get_pubkey(x);
				if (pkey == NULL)
					{
					BIO_printf(bio_err,"Error getting public key\n");
					ERR_print_errors(bio_err);
					goto end;
					}
				PEM_write_bio_PUBKEY(STDout, pkey);
				EVP_PKEY_free(pkey);
				}
			else
				if (C == i)
				{
				unsigned char *d;
				char *m;
				int y,z;

				X509_NAME_oneline(X509_get_subject_name(x),
					buf,sizeof buf);
				BIO_printf(STDout,"/* subject:%s */\n",buf);
				m=X509_NAME_oneline(
					X509_get_issuer_name(x),buf,
					sizeof buf);
				BIO_printf(STDout,"/* issuer :%s */\n",buf);

				z=i2d_X509(x,NULL);
				m=OPENSSL_malloc(z);

				d=(unsigned char *)m;
				z=i2d_X509_NAME(X509_get_subject_name(x),&d);
				BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d);
				BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f)
						BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				z=i2d_X509(x,&d);
				BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f)
						BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				OPENSSL_free(m);
				}
			else if (text == i)
				{
				X509_print_ex(out,x,nmflag, certflag);
				}
			else if (startdate == i)
				{
				BIO_puts(STDout,"notBefore=");
				ASN1_TIME_print(STDout,X509_get_notBefore(x));
				BIO_puts(STDout,"\n");
				}
			else if (enddate == i)
				{
				BIO_puts(STDout,"notAfter=");
				ASN1_TIME_print(STDout,X509_get_notAfter(x));
				BIO_puts(STDout,"\n");
				}
			else if (fingerprint == i)
				{
				int j;
				unsigned int n;
				unsigned char md[EVP_MAX_MD_SIZE];

				if (!X509_digest(x,digest,md,&n))
					{
					BIO_printf(bio_err,"out of memory\n");
					goto end;
					}
				BIO_printf(STDout,"%s Fingerprint=",
						OBJ_nid2sn(EVP_MD_type(digest)));
				for (j=0; j<(int)n; j++)
					{
					BIO_printf(STDout,"%02X%c",md[j],
						(j+1 == (int)n)
						?'\n':':');
					}
				}

			/* should be in the library */
			else if ((sign_flag == i) && (x509req == 0))
				{
				BIO_printf(bio_err,"Getting Private key\n");
				if (Upkey == NULL)
					{
					Upkey=load_key(bio_err,
						keyfile, keyformat, 0,
						passin, e, "Private key");
					if (Upkey == NULL) goto end;
					}
#ifndef OPENSSL_NO_DSA
		                if (Upkey->type == EVP_PKEY_DSA)
		                        digest=EVP_dss1();
#endif

				assert(need_rand);
				if (!sign(x,Upkey,days,clrext,digest,
						 extconf, extsect)) goto end;
				}
			else if (CA_flag == i)
				{
				BIO_printf(bio_err,"Getting CA Private Key\n");
				if (CAkeyfile != NULL)
					{
					CApkey=load_key(bio_err,
						CAkeyfile, CAkeyformat,
						0, passin, e,
						"CA Private Key");
					if (CApkey == NULL) goto end;
					}
#ifndef OPENSSL_NO_DSA
		                if (CApkey->type == EVP_PKEY_DSA)
		                        digest=EVP_dss1();
#endif
				
				assert(need_rand);
				if (!x509_certify(ctx,CAfile,digest,x,xca,
					CApkey, CAserial,CA_createserial,days, clrext,
					extconf, extsect, sno))
					goto end;
				}
			else if (x509req == i)
				{
				EVP_PKEY *pk;

				BIO_printf(bio_err,"Getting request Private Key\n");
				if (keyfile == NULL)
					{
					BIO_printf(bio_err,"no request key file specified\n");
					goto end;
					}
				else
					{
					pk=load_key(bio_err,
						keyfile, FORMAT_PEM, 0,
						passin, e, "request key");
					if (pk == NULL) goto end;
					}

				BIO_printf(bio_err,"Generating certificate request\n");

#ifndef OPENSSL_NO_DSA
		                if (pk->type == EVP_PKEY_DSA)
		                        digest=EVP_dss1();
#endif

				rq=X509_to_X509_REQ(x,pk,digest);
				EVP_PKEY_free(pk);
				if (rq == NULL)
					{
					ERR_print_errors(bio_err);
					goto end;
					}
				if (!noout)
					{
					X509_REQ_print(out,rq);
					PEM_write_bio_X509_REQ(out,rq);
					}
				noout=1;
				}
			else if (ocspid == i)
				{
				X509_ocspid_print(out, x);
				}
			}
		}

	if (checkend)
		{
		time_t tnow=time(NULL);

		if (ASN1_UTCTIME_cmp_time_t(X509_get_notAfter(x), tnow+checkoffset) == -1)
			{
			BIO_printf(out,"Certificate will expire\n");
			ret=1;
			}
		else
			{
			BIO_printf(out,"Certificate will not expire\n");
			ret=0;
			}
		goto end;
		}

	if (noout)
		{
		ret=0;
		goto end;
		}

	if 	(outformat == FORMAT_ASN1)
		i=i2d_X509_bio(out,x);
	else if (outformat == FORMAT_PEM)
		{
		if (trustout) i=PEM_write_bio_X509_AUX(out,x);
		else i=PEM_write_bio_X509(out,x);
		}
	else if (outformat == FORMAT_NETSCAPE)
		{
		ASN1_HEADER ah;
		ASN1_OCTET_STRING os;

		os.data=(unsigned char *)NETSCAPE_CERT_HDR;
		os.length=strlen(NETSCAPE_CERT_HDR);
		ah.header= &os;
		ah.data=(char *)x;
		ah.meth=X509_asn1_meth();

		/* no macro for this one yet */
		i=ASN1_i2d_bio(i2d_ASN1_HEADER,out,(unsigned char *)&ah);
		}
	else	{
		BIO_printf(bio_err,"bad output format specified for outfile\n");
		goto end;
		}
	if (!i)
		{
		BIO_printf(bio_err,"unable to write certificate\n");
		ERR_print_errors(bio_err);
		goto end;
		}
	ret=0;
end:
	if (need_rand)
		app_RAND_write_file(NULL, bio_err);
	OBJ_cleanup();
	NCONF_free(extconf);
	BIO_free_all(out);
	BIO_free_all(STDout);
	X509_STORE_free(ctx);
	X509_REQ_free(req);
	X509_free(x);
	X509_free(xca);
	EVP_PKEY_free(Upkey);
	EVP_PKEY_free(CApkey);
	X509_REQ_free(rq);
	ASN1_INTEGER_free(sno);
	sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
	sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
	if (passin) OPENSSL_free(passin);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
コード例 #17
0
ファイル: ssl.c プロジェクト: caidongyun/backup
/*
 * Create a fake X509v3 certificate, signed by the provided CA,
 * based on the original certificate retrieved from the real server.
 * The returned certificate is created using X509_new() and thus must
 * be freed by the caller using X509_free().
 * The optional argument extraname is added to subjectAltNames if provided.
 */
X509 *
ssl_x509_forge(X509 *cacrt, EVP_PKEY *cakey, X509 *origcrt,
               const char *extraname, EVP_PKEY *key)
{
	X509_NAME *subject, *issuer;
	GENERAL_NAMES *names;
	GENERAL_NAME *gn;
	X509 *crt;

	subject = X509_get_subject_name(origcrt);
	issuer = X509_get_subject_name(cacrt);
	if (!subject || !issuer)
		return NULL;

	crt = X509_new();
	if (!crt)
		return NULL;

	if (!X509_set_version(crt, 0x02) ||
	    !X509_set_subject_name(crt, subject) ||
	    !X509_set_issuer_name(crt, issuer) ||
	    ssl_x509_serial_copyrand(crt, origcrt) == -1 ||
	    !X509_gmtime_adj(X509_get_notBefore(crt), (long)-60*60*24) ||
	    !X509_gmtime_adj(X509_get_notAfter(crt), (long)60*60*24*364) ||
	    !X509_set_pubkey(crt, key))
		goto errout;

	/* add standard v3 extensions; cf. RFC 2459 */
	X509V3_CTX ctx;
	X509V3_set_ctx(&ctx, cacrt, crt, NULL, NULL, 0);
	if (ssl_x509_v3ext_add(&ctx, crt, "basicConstraints",
	                                  "CA:FALSE") == -1 ||
	    ssl_x509_v3ext_add(&ctx, crt, "keyUsage",
	                                  "digitalSignature,"
	                                  "keyEncipherment") == -1 ||
	    ssl_x509_v3ext_add(&ctx, crt, "extendedKeyUsage",
	                                  "serverAuth") == -1 ||
	    ssl_x509_v3ext_add(&ctx, crt, "subjectKeyIdentifier",
	                                  "hash") == -1 ||
	    ssl_x509_v3ext_add(&ctx, crt, "authorityKeyIdentifier",
	                                  "keyid,issuer:always") == -1)
		goto errout;

	if (!extraname) {
		/* no extraname provided: copy original subjectAltName ext */
		if (ssl_x509_v3ext_copy_by_nid(crt, origcrt,
		                               NID_subject_alt_name) == -1)
			goto errout;
	} else {
		names = X509_get_ext_d2i(origcrt, NID_subject_alt_name, 0, 0);
		if (!names) {
			/* no subjectAltName present: add new one */
			char *cfval;
			if (asprintf(&cfval, "DNS:%s", extraname) < 0)
				goto errout;
			if (ssl_x509_v3ext_add(&ctx, crt, "subjectAltName",
			                       cfval) == -1) {
				free(cfval);
				goto errout;
			}
			free(cfval);
		} else {
			/* add extraname to original subjectAltName
			 * and add it to the new certificate */
			gn = GENERAL_NAME_new();
			if (!gn)
				goto errout2;
			gn->type = GEN_DNS;
			gn->d.dNSName = M_ASN1_IA5STRING_new();
			if (!gn->d.dNSName)
				goto errout3;
			ASN1_STRING_set(gn->d.dNSName,
			                (unsigned char *)extraname,
			                strlen(extraname));
			sk_GENERAL_NAME_push(names, gn);
			X509_EXTENSION *ext = X509V3_EXT_i2d(
			                      NID_subject_alt_name, 0, names);
			if (!X509_add_ext(crt, ext, -1)) {
				if (ext) {
					X509_EXTENSION_free(ext);
				}
				goto errout3;
			}
			X509_EXTENSION_free(ext);
			sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
		}
	}
#ifdef DEBUG_CERTIFICATE
	ssl_x509_v3ext_add(&ctx, crt, "nsComment", "Generated by " PNAME);
#endif /* DEBUG_CERTIFICATE */

	const EVP_MD *md;
	switch (EVP_PKEY_type(cakey->type)) {
#ifndef OPENSSL_NO_RSA
		case EVP_PKEY_RSA:
			md = EVP_sha1();
			break;
#endif /* !OPENSSL_NO_RSA */
#ifndef OPENSSL_NO_DSA
		case EVP_PKEY_DSA:
			md = EVP_dss1();
			break;
#endif /* !OPENSSL_NO_DSA */
#ifndef OPENSSL_NO_ECDSA
		case EVP_PKEY_EC:
			md = EVP_ecdsa();
			break;
#endif /* !OPENSSL_NO_ECDSA */
		default:
			goto errout;
	}
	if (!X509_sign(crt, cakey, md))
		goto errout;

	return crt;

errout3:
	GENERAL_NAME_free(gn);
errout2:
	sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
errout:
	X509_free(crt);
	return NULL;
}
コード例 #18
0
static void sigver()
{
    DSA *dsa = NULL;
    char buf[1024];
    char lbuf[1024];
    unsigned char msg[1024];
    char *keyword, *value;
    int nmod = 0, n = 0;
    DSA_SIG sg, *sig = &sg;

    sig->r = NULL;
    sig->s = NULL;

    while (fgets(buf, sizeof buf, stdin) != NULL) {
        if (!parse_line(&keyword, &value, lbuf, buf)) {
            fputs(buf, stdout);
            continue;
        }
        if (!strcmp(keyword, "[mod")) {
            nmod = atoi(value);
            if (dsa)
                FIPS_dsa_free(dsa);
            dsa = FIPS_dsa_new();
        } else if (!strcmp(keyword, "P"))
            dsa->p = hex2bn(value);
        else if (!strcmp(keyword, "Q"))
            dsa->q = hex2bn(value);
        else if (!strcmp(keyword, "G")) {
            dsa->g = hex2bn(value);

            printf("[mod = %d]\n\n", nmod);
            pbn("P", dsa->p);
            pbn("Q", dsa->q);
            pbn("G", dsa->g);
            putc('\n', stdout);
        } else if (!strcmp(keyword, "Msg")) {
            n = hex2bin(value, msg);
            pv("Msg", msg, n);
        } else if (!strcmp(keyword, "Y"))
            dsa->pub_key = hex2bn(value);
        else if (!strcmp(keyword, "R"))
            sig->r = hex2bn(value);
        else if (!strcmp(keyword, "S")) {
            EVP_MD_CTX mctx;
            EVP_PKEY pk;
            unsigned char sigbuf[60];
            unsigned int slen;
            int r;
            EVP_MD_CTX_init(&mctx);
            pk.type = EVP_PKEY_DSA;
            pk.pkey.dsa = dsa;
            sig->s = hex2bn(value);

            pbn("Y", dsa->pub_key);
            pbn("R", sig->r);
            pbn("S", sig->s);

            slen = FIPS_dsa_sig_encode(sigbuf, sig);
            EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL);
            EVP_VerifyUpdate(&mctx, msg, n);
            r = EVP_VerifyFinal(&mctx, sigbuf, slen, &pk);
            EVP_MD_CTX_cleanup(&mctx);

            printf("Result = %c\n", r == 1 ? 'P' : 'F');
            putc('\n', stdout);
        }
    }
}
コード例 #19
0
KSSLCertificate*
KSSLCertificateFactory::generateSelfSigned(KSSLKeyType /*keytype*/) {
#if 0
  //#ifdef KSSL_HAVE_SSL
  X509_NAME *x509name = X509_NAME_new();
  X509      *x509;
  ASN1_UTCTIME *beforeafter;
  KSSLCertificate *newcert;
  int rc;

  // FIXME: generate the private key
  if (keytype == KEYTYPE_UNKNOWN || (key=EVP_PKEY_new()) == NULL) {
    X509_NAME_free(x509name);
    return NULL;
  }

  switch(keytype) {
  case KEYTYPE_RSA:
    if (!EVP_PKEY_assign_RSA(key, RSA_generate_key(newkey,0x10001,
						   req_cb,bio_err))) {
      
    } 
    break;
  case KEYTYPE_DSA:
    if (!DSA_generate_key(dsa_params)) goto end;
    if (!EVP_PKEY_assign_DSA(pkey,dsa_params)) goto end;
    dsa_params=NULL; 
    if (pkey->type == EVP_PKEY_DSA)
      digest=EVP_dss1();
    break;
  }

  // FIXME: dn doesn't exist
  // FIXME: allow the notAfter value to be parameterized
  // FIXME: allow a password to lock the key with

  // Fill in the certificate
  X509_NAME_add_entry_by_NID(x509name, OBJ_txt2nid("CN"), 0x1001,
                             (unsigned char *) dn, -1, -1, 0);

  x509 = X509_new();
  rc = X509_set_issuer_name(x509, x509name);
  if (rc != 0) {
    X509_free(x509);
    X509_NAME_free(x509name);
    return NULL;
  }
  rc = X509_set_subject_name(x509, x509name);
  if (rc != 0) {
    X509_free(x509);
    X509_NAME_free(x509name);
    return NULL;
  }
  ASN1_INTEGER_set(X509_get_serialNumber(*x509), 0);

  X509_NAME_free(x509name);

  // Make it a 1 year certificate
  beforeafter = ASN1_UTCTIME_new();
  if (!X509_gmtime_adj(beforeafter, -60*60*24)) {     // yesterday
    X509_free(x509);
    return NULL;
  }
  if (!X509_set_notBefore(x509, beforeafter)) {
    X509_free(x509);
    return NULL;
  }
  if (!X509_gmtime_adj(beforeafter, 60*60*24*364)) {  // a year from yesterday
    X509_free(x509);
    return NULL;
  }
  if (!X509_set_notAfter(x509, beforeafter)) {
    X509_free(x509);
    return NULL;
  }
  ASN1_UTCTIME_free(beforeafter);

  if (!X509_set_pubkey(x509, key)) {
    X509_free(x509);
    return NULL;
  }

  rc = X509_sign(x509, key, EVP_sha1());
  if (rc != 0) {
    X509_free(x509);
    return NULL;
  }

  newCert = new KSSLCertificate;
  newCert->setCert(x509);
  return newCert;  
#else
  return NULL;
#endif
}
コード例 #20
0
ファイル: ssl_algs.c プロジェクト: 0culus/openssl
int SSL_library_init(void)
	{

#ifndef OPENSSL_NO_DES
	EVP_add_cipher(EVP_des_cbc());
	EVP_add_cipher(EVP_des_ede3_cbc());
#endif
#ifndef OPENSSL_NO_IDEA
	EVP_add_cipher(EVP_idea_cbc());
#endif
#ifndef OPENSSL_NO_RC4
	EVP_add_cipher(EVP_rc4());
#ifndef OPENSSL_NO_MD5
	EVP_add_cipher(EVP_rc4_hmac_md5());
#endif
#endif  
#ifndef OPENSSL_NO_RC2
	EVP_add_cipher(EVP_rc2_cbc());
	/* Not actually used for SSL/TLS but this makes PKCS#12 work
	 * if an application only calls SSL_library_init().
	 */
	EVP_add_cipher(EVP_rc2_40_cbc());
#endif
#ifndef OPENSSL_NO_AES
	EVP_add_cipher(EVP_aes_128_cbc());
	EVP_add_cipher(EVP_aes_192_cbc());
	EVP_add_cipher(EVP_aes_256_cbc());
	EVP_add_cipher(EVP_aes_128_gcm());
	EVP_add_cipher(EVP_aes_256_gcm());
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
	EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
	EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
#endif
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256)
	EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
	EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
#endif
#endif
#ifndef OPENSSL_NO_CAMELLIA
	EVP_add_cipher(EVP_camellia_128_cbc());
	EVP_add_cipher(EVP_camellia_256_cbc());
#endif

#ifndef OPENSSL_NO_SEED
	EVP_add_cipher(EVP_seed_cbc());
#endif
  
#ifndef OPENSSL_NO_MD5
	EVP_add_digest(EVP_md5());
	EVP_add_digest_alias(SN_md5,"ssl2-md5");
	EVP_add_digest_alias(SN_md5,"ssl3-md5");
#endif
#ifndef OPENSSL_NO_SHA
	EVP_add_digest(EVP_sha1()); /* RSA with sha1 */
	EVP_add_digest_alias(SN_sha1,"ssl3-sha1");
	EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA);
#endif
#ifndef OPENSSL_NO_SHA256
	EVP_add_digest(EVP_sha224());
	EVP_add_digest(EVP_sha256());
#endif
#ifndef OPENSSL_NO_SHA512
	EVP_add_digest(EVP_sha384());
	EVP_add_digest(EVP_sha512());
#endif
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA)
	EVP_add_digest(EVP_dss1()); /* DSA with sha1 */
	EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2);
	EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1");
	EVP_add_digest_alias(SN_dsaWithSHA1,"dss1");
#endif
#ifndef OPENSSL_NO_ECDSA
	EVP_add_digest(EVP_ecdsa());
#endif
	/* If you want support for phased out ciphers, add the following */
#if 0
	EVP_add_digest(EVP_sha());
	EVP_add_digest(EVP_dss());
#endif
#ifndef OPENSSL_NO_COMP
	/* This will initialise the built-in compression algorithms.
	   The value returned is a STACK_OF(SSL_COMP), but that can
	   be discarded safely */
	(void)SSL_COMP_get_compression_methods();
#endif
	/* initialize cipher/digest methods table */
	ssl_load_ciphers();
	return(1);
	}
コード例 #21
0
ファイル: crypto.c プロジェクト: xcllnt/openiked
struct iked_dsa *
dsa_new(uint16_t id, struct iked_hash *prf, int sign)
{
	struct iked_dsa		*dsap = NULL, dsa;

	bzero(&dsa, sizeof(dsa));

	switch (id) {
	case IKEV2_AUTH_SIG:
		if (sign)
			dsa.dsa_priv = EVP_sha256(); /* XXX should be passed */
		else
			dsa.dsa_priv = NULL; /* set later by dsa_init() */
		break;
	case IKEV2_AUTH_RSA_SIG:
		/* RFC5996 says we SHOULD use SHA1 here */
		dsa.dsa_priv = EVP_sha1();
		break;
	case IKEV2_AUTH_SHARED_KEY_MIC:
		if (prf == NULL || prf->hash_priv == NULL)
			fatalx("dsa_new: invalid PRF");
		dsa.dsa_priv = prf->hash_priv;
		dsa.dsa_hmac = 1;
		break;
	case IKEV2_AUTH_DSS_SIG:
		dsa.dsa_priv = EVP_dss1();
		break;
	case IKEV2_AUTH_ECDSA_256:
		dsa.dsa_priv = EVP_sha256();
		break;
	case IKEV2_AUTH_ECDSA_384:
		dsa.dsa_priv = EVP_sha384();
		break;
	case IKEV2_AUTH_ECDSA_521:
		dsa.dsa_priv = EVP_sha512();
		break;
	default:
		log_debug("%s: auth method %s not supported", __func__,
		    print_map(id, ikev2_auth_map));
		break;
	}

	if ((dsap = calloc(1, sizeof(*dsap))) == NULL) {
		log_debug("%s: alloc dsa ctx", __func__);

		return (NULL);
	}
	memcpy(dsap, &dsa, sizeof(*dsap));

	dsap->dsa_method = id;
	dsap->dsa_sign = sign;

	if (dsap->dsa_hmac) {
		if ((dsap->dsa_ctx = calloc(1, sizeof(HMAC_CTX))) == NULL) {
			log_debug("%s: alloc hash ctx", __func__);
			dsa_free(dsap);
			return (NULL);
		}
		HMAC_CTX_init((HMAC_CTX *)dsap->dsa_ctx);
	} else {
		if ((dsap->dsa_ctx = EVP_MD_CTX_create()) == NULL) {
			log_debug("%s: alloc digest ctx", __func__);
			dsa_free(dsap);
			return (NULL);
		}
	}

	return (dsap);
}