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; }
/* 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); n=i2d_X509(s->session->sess_cert->peer_key->x509,&p); EVP_SignUpdate(&ctx,buf,(unsigned int)n); 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)); }
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) { 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); 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_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); }
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; }
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); }
/** * 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; }
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; if (!(os=M_ASN1_OCTET_STRING_new())) { 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 */ if (!(os=M_ASN1_OCTET_STRING_new())) { 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; } if (si_sk != NULL) { if ((buf=BUF_MEM_new()) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,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; 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); if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,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)) { if (!(sign_time=X509_gmtime_adj(NULL,0))) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } 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); if (!(digest=M_ASN1_OCTET_STRING_new())) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } if (!M_ASN1_OCTET_STRING_set(digest,md_data, md_len)) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } 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 #ifndef OPENSSL_NO_ECDSA if (si->pkey->type == EVP_PKEY_EC) ctx_tmp.digest=EVP_ecdsa(); #endif if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, (unsigned int *)&buf->length,si->pkey)) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB); goto err; } if (!ASN1_STRING_set(si->enc_digest, (unsigned char *)buf->data,buf->length)) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB); goto err; } } } 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)) { 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; } 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 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((ASN1_VALUE*)asn,&buf_in, it); //MS: cast to match signature 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; } EVP_SignInit_ex(&ctx,type, NULL); 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_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 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; unsigned char *p,*pp=NULL; int x; ASN1_OCTET_STRING *os=NULL; 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=p7->d.sign->contents->d.data; /* If detached data then the content is excluded */ if(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,PKCS7_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. */ memcpy(&ctx_tmp,mdc,sizeof(ctx_tmp)); if (!BUF_MEM_grow(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]; unsigned int md_len; ASN1_OCTET_STRING *digest; ASN1_UTCTIME *sign_time; const EVP_MD *md_tmp; /* Add signing time */ 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(&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 mess */ EVP_SignInit(&ctx_tmp,md_tmp); x=i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,NULL, i2d_X509_ATTRIBUTE, V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET); pp=(unsigned char *)OPENSSL_malloc(x); p=pp; i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,&p, i2d_X509_ATTRIBUTE, V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET); EVP_SignUpdate(&ctx_tmp,pp,x); OPENSSL_free(pp); pp=NULL; } #ifndef 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 (!p7->detached) { 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 } if (pp != NULL) OPENSSL_free(pp); pp=NULL; ret=1; err: if (buf != NULL) BUF_MEM_free(buf); return(ret); }
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 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; }
//-------------------------------------------------- // 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; }