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; }
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; }
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); }
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; }
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; }
/* 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; }
/* 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; }
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); }
/** * 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; }
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; }
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); }
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); }
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); }
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; }
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; }
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); }
/* 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; }
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); }
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); }
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); }
//-------------------------------------------------- // 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; }