/** @fn int soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen) @brief Initiates a (signed) digest computation. @param soap context @param[in,out] data smdevp engine context @param[in] alg is algorithm to use @param[in] key is key to use or NULL for digests @param[in] keylen is length of HMAC key (when provided) @return SOAP_OK or SOAP_SSL_ERROR */ int soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen) { static int done = 0; int err = 1; #ifdef WITH_OPENSSL /* OpenSSL: make sure we have the digest algorithms, need to call just once */ if (!done) { done = 1; OpenSSL_add_all_digests(); OpenSSL_add_all_algorithms(); } #endif /* the algorithm to use */ data->alg = alg; /* the key to use */ data->key = key; /* allocate and init the OpenSSL HMAC or EVP_MD context */ if ((alg & (SOAP_SMD_PASSTHRU-1)) == SOAP_SMD_HMAC_SHA1) { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(HMAC_CTX)); HMAC_CTX_init((HMAC_CTX*)data->ctx); } else { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(EVP_MD_CTX)); EVP_MD_CTX_init((EVP_MD_CTX*)data->ctx); } DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Init alg=%d (%p) --\n", alg, data->ctx)); /* init the digest or signature computations */ switch (alg & (SOAP_SMD_PASSTHRU-1)) { case SOAP_SMD_DGST_MD5: EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_md5()); break; case SOAP_SMD_DGST_SHA1: EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_sha1()); break; case SOAP_SMD_DGST_SHA256: EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_sha256()); break; case SOAP_SMD_HMAC_SHA1: HMAC_Init((HMAC_CTX*)data->ctx, key, keylen, EVP_sha1()); break; case SOAP_SMD_SIGN_DSA_SHA1: err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_dss1()); break; case SOAP_SMD_SIGN_RSA_SHA1: err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_sha1()); break; case SOAP_SMD_SIGN_RSA_SHA256: err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_sha256()); break; case SOAP_SMD_VRFY_DSA_SHA1: err = EVP_VerifyInit((EVP_MD_CTX*)data->ctx, EVP_dss1()); break; case SOAP_SMD_VRFY_RSA_SHA1: err = EVP_VerifyInit((EVP_MD_CTX*)data->ctx, EVP_sha1()); break; } /* check and return */ return soap_smd_check(soap, data, err, "soap_smd_init() failed"); }
void rsatest() { const EVP_MD *sha256 = EVP_get_digestbyname("sha256"); if(!sha256){ fprintf(stderr,"SHA256 not available\n"); return; } printf("Now try signing with X.509 certificates and EVP\n"); char ptext[16]; memset(ptext,0,sizeof(ptext)); strcpy(ptext,"Simson"); unsigned char sig[1024]; uint32_t siglen = sizeof(sig); BIO *bp = BIO_new_file("signing_key.pem","r"); EVP_MD_CTX md; EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bp,0,0,0); EVP_SignInit(&md,sha256); EVP_SignUpdate(&md,ptext,sizeof(ptext)); EVP_SignFinal(&md,sig,&siglen,pkey); /* let's try to verify it */ bp = BIO_new_file("signing_cert.pem","r"); X509 *x = 0; PEM_read_bio_X509(bp,&x,0,0); EVP_PKEY *pubkey = X509_get_pubkey(x); printf("pubkey=%p\n",pubkey); EVP_VerifyInit(&md,sha256); EVP_VerifyUpdate(&md,ptext,sizeof(ptext)); int r = EVP_VerifyFinal(&md,sig,siglen,pubkey); printf("r=%d\n",r); printf("do it again...\n"); EVP_VerifyInit(&md,sha256); EVP_VerifyUpdate(&md,ptext,sizeof(ptext)); r = EVP_VerifyFinal(&md,sig,siglen,pubkey); printf("r=%d\n",r); printf("make a tiny change...\n"); ptext[0]='f'; EVP_VerifyInit(&md,sha256); EVP_VerifyUpdate(&md,ptext,sizeof(ptext)); r = EVP_VerifyFinal(&md,sig,siglen,pubkey); printf("r=%d\n",r); }
int COsslKey::VerifyBin( sqbind::CSqBinary *pData, sqbind::CSqBinary *sig ) {_STT(); if ( !pData || !sig || !getPublicKeyPtr() ) return 0; EVP_MD_CTX md_ctx; if ( !EVP_VerifyInit( &md_ctx, EVP_sha1() ) ) { oexERROR( 0, oexT( "EVP_VerifyInit() failed" ) ); return 0; } // end if if ( !EVP_VerifyUpdate( &md_ctx, pData->Ptr(), pData->getUsed() ) ) { oexERROR( 0, oexT( "EVP_VerifyUpdate() failed" ) ); return 0; } // end if int err = EVP_VerifyFinal( &md_ctx, (unsigned char*)sig->Ptr(), sig->getUsed(), getPublicKeyPtr() ); if ( err != 1 ) { oexERROR( err, oexT( "EVP_VerifyFinal() failed" ) ); return 0; } // end if return 1; }
int oauth_verify_rsa_sha1 (const char *m, const char *c, const char *s) { EVP_MD_CTX md_ctx; EVP_PKEY *pkey; BIO *in; X509 *cert = NULL; unsigned char *b64d; int slen, err; in = BIO_new_mem_buf((unsigned char*)c, strlen(c)); cert = PEM_read_bio_X509(in, NULL, 0, NULL); if (cert) { pkey = (EVP_PKEY *) X509_get_pubkey(cert); X509_free(cert); } else { pkey = PEM_read_bio_PUBKEY(in, NULL, 0, NULL); } BIO_free(in); if (pkey == NULL) { //fprintf(stderr, "could not read cert/pubkey.\n"); return -2; } b64d= (unsigned char*) xmalloc(sizeof(char)*strlen(s)); slen = oauth_decode_base64(b64d, s); EVP_VerifyInit(&md_ctx, EVP_sha1()); EVP_VerifyUpdate(&md_ctx, m, strlen(m)); err = EVP_VerifyFinal(&md_ctx, b64d, slen, pkey); EVP_MD_CTX_cleanup(&md_ctx); EVP_PKEY_free(pkey); free(b64d); return (err); }
/** Low-level signature verification. * \param key_count Number of keys in the \a keys array * and number fo signatures in the \a sigs array. * \param keys Array of keys. The keys must include public key data. * \param sigs Array of signatures, as returned from gale_crypto_sign_raw(). * \param data Data to verify against signatures. * \return Nonzero iff the all signatures are valid. */ int gale_crypto_verify_raw(int key_count, const struct gale_group *keys, const struct gale_data *sigs, struct gale_data data) { int i,is_valid = 1; EVP_MD_CTX *context = EVP_MD_CTX_new(); RSA *rsa; EVP_VerifyInit(context,EVP_md5()); EVP_VerifyUpdate(context,data.p,data.l); for (i = 0; is_valid && i < key_count; ++i) { EVP_PKEY *key = EVP_PKEY_new(); EVP_PKEY_assign_RSA(key,RSA_new()); rsa = EVP_PKEY_get0_RSA(key); crypto_i_rsa(keys[i],rsa); if (!crypto_i_public_valid(rsa)) { gale_alert(GALE_WARNING,G_("invalid public key"),0); is_valid = 0; goto cleanup; } if (!EVP_VerifyFinal(context,sigs[i].p,sigs[i].l,key)) { crypto_i_error(); is_valid = 0; goto cleanup; } cleanup: EVP_PKEY_free(key); } return is_valid; }
static bool verifyRSASignature(const unsigned char *originalMessage, unsigned int messageLength, const unsigned char *signature, unsigned int sigLength) { if(nullptr == originalMessage) { return errorMessage(_("Message is empty")); } if(nullptr == signature) { return errorMessage(_("Signature is empty")); } const char *settingsPath = CPLGetConfigOption("NGS_SETTINGS_PATH", nullptr); std::string keyFilePath = File::formFileName(settingsPath, KEY_FILE, ""); FILE *file = VSIFOpen( keyFilePath.c_str(), "r" ); if( file == nullptr ) { return errorMessage(_("Failed open file %s"), keyFilePath.c_str()); } EVP_PKEY *evp_pubkey = PEM_read_PUBKEY(file, nullptr, nullptr, nullptr); VSIFClose( file ); if (!evp_pubkey) { return errorMessage(_("Failed PEM_read_PUBKEY")); } EVP_MD_CTX *ctx = EVP_MD_CTX_create(); if (!ctx) { EVP_PKEY_free(evp_pubkey); return errorMessage(_("Failed PEM_read_PUBKEY")); } if(!EVP_VerifyInit(ctx, EVP_sha256())) { EVP_MD_CTX_destroy(ctx); EVP_PKEY_free(evp_pubkey); return errorMessage(_("Failed EVP_VerifyInit")); } if(!EVP_VerifyUpdate(ctx, originalMessage, messageLength)) { EVP_MD_CTX_destroy(ctx); EVP_PKEY_free(evp_pubkey); return errorMessage(_("Failed EVP_VerifyUpdate")); } int result = EVP_VerifyFinal(ctx, signature, sigLength, evp_pubkey); EVP_MD_CTX_destroy(ctx); EVP_PKEY_free(evp_pubkey); outMessage(result == 1 ? COD_SUCCESS : COD_UNEXPECTED_ERROR, "Signature is %s", result == 1 ? "valid" : "invalid"); return result == 1; }
int verify_sig( EVP_PKEY * pkey, const EVP_MD * htype, char * data, int data_len, unsigned char * sig, int sig_len ) { EVP_MD_CTX md_ctx; EVP_VerifyInit (&md_ctx, htype); EVP_VerifyUpdate (&md_ctx, data, data_len); if ( EVP_VerifyFinal (&md_ctx, sig, sig_len, pkey) != 1) { ERR_print_errors_fp (stderr); return 0; } return 1; }
bool verifySignature(int message, unsigned char* signature, char* certfile) { int err; unsigned int sig_len; //unsigned char sig_buf[4096]; static char data[100]; EVP_MD_CTX md_ctx; EVP_PKEY* pkey; FILE * fp; X509 * x509; memset(&data, '\0', sizeof(data)); sprintf(data, "%d", message); ERR_load_crypto_strings(); fp = fopen(certfile, "r"); if (fp == NULL) { printf("certfile not found\n"); exit(1); } x509 = PEM_read_X509(fp, NULL, NULL, NULL); fclose(fp); if (x509 == NULL) { printf("Error in certificate file x509\n"); ERR_print_errors_fp (stderr); exit(1); } /* Get public key - eay */ pkey = X509_get_pubkey(x509); if (pkey == NULL) { printf("Error in claiming the public key\n"); ERR_print_errors_fp (stderr); exit(1); } sig_len = 128; /* Verify the signature */ EVP_VerifyInit(&md_ctx, EVP_sha1()); EVP_VerifyUpdate(&md_ctx, data, strlen((char*) data)); err = EVP_VerifyFinal(&md_ctx, signature, sig_len, pkey); EVP_PKEY_free(pkey); if (err != 1) { ERR_print_errors_fp (stderr); return 0; } return 1; }
static bool EVP_verify(RSA *rsa, const char *sign, size_t sigl, const char *data, size_t l) { EVP_MD_CTX ctx; EVP_PKEY *pkey; bool ret = false; pkey = EVP_PKEY_new(); if (!pkey) return ret; if (!EVP_PKEY_set1_RSA(pkey, rsa)) goto _fail; EVP_VerifyInit(&ctx, EVP_sha256()); if (!EVP_VerifyUpdate(&ctx, data, l)) goto _fail; if (EVP_VerifyFinal(&ctx, sign, sigl, pkey) == 1) ret = true; _fail: EVP_PKEY_free(pkey); return ret; }
int isns_dsasig_verify(isns_security_t *ctx, isns_principal_t *peer, buf_t *pdu, const struct isns_authblk *blk) { EVP_MD_CTX *md_ctx; EVP_PKEY *pkey; int err; if ((pkey = peer->is_key) == NULL) return 0; if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) { isns_debug_message( "Incompatible public key (spi=%s)\n", peer->is_name); return 0; } md_ctx = EVP_MD_CTX_new(); EVP_VerifyInit(md_ctx, EVP_dss1()); isns_message_digest(md_ctx, pdu, blk); err = EVP_VerifyFinal(md_ctx, blk->iab_sig, blk->iab_sig_len, pkey); EVP_MD_CTX_free(md_ctx); if (err == 0) { isns_debug_auth("*** Incorrect signature ***\n"); return 0; } if (err < 0) { isns_dsasig_report_errors("EVP_VerifyFinal failed", isns_error); return 0; } isns_debug_message("Good signature from %s\n", peer->is_name?: "<server>"); return 1; }
/* * call-seq: * pkey.verify(digest, signature, data) -> String * * To verify the +String+ +signature+, +digest+, an instance of * OpenSSL::Digest, must be provided to re-compute the message digest of the * original +data+, also a +String+. The return value is +true+ if the * signature is valid, +false+ otherwise. A PKeyError is raised should errors * occur. * Any previous state of the +Digest+ instance is irrelevant to the validation * outcome, the digest instance is reset to its initial state during the * operation. * * == Example * data = 'Sign me!' * digest = OpenSSL::Digest::SHA256.new * pkey = OpenSSL::PKey::RSA.new(2048) * signature = pkey.sign(digest, data) * pub_key = pkey.public_key * puts pub_key.verify(digest, signature, data) # => true */ static VALUE ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) { EVP_PKEY *pkey; EVP_MD_CTX ctx; GetPKey(self, pkey); EVP_VerifyInit(&ctx, GetDigestPtr(digest)); StringValue(sig); StringValue(data); EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data)); switch (EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey)) { case 0: return Qfalse; case 1: return Qtrue; default: ossl_raise(ePKeyError, NULL); } return Qnil; /* dummy */ }
bool crypto_rsa_verify_signature(struct string *databuffer, struct string *signature, const char *pubkey) { int err; bool retval; EVP_MD_CTX md_ctx; EVP_PKEY *pkey; /* load public key into openssl structure */ pkey = crypto_load_key(pubkey, false); if (pkey == NULL) { log_err("crypto_verify_signature: key loading failed\n"); return false; } /* Verify the signature */ if (EVP_VerifyInit(&md_ctx, EVP_sha512()) != 1) { log_err("crypto_verify_signature: libcrypto verify init failed\n"); EVP_PKEY_free(pkey); return false; } EVP_VerifyUpdate(&md_ctx, string_get(databuffer), string_length(databuffer)); err = EVP_VerifyFinal(&md_ctx, (unsigned char*)string_get(signature), string_length(signature), pkey); EVP_PKEY_free(pkey); if (err != 1) { log_err("crypto_verify_signature: signature verify failed, received bogus data from backend.\n"); ERR_print_errors_fp(stderr); retval = false; goto bailout_ctx_cleanup; } retval = true; bailout_ctx_cleanup: EVP_MD_CTX_cleanup(&md_ctx); //log_info("Signature Verified Ok.\n"); return retval; }
/* * public static native void EVP_VerifyInit(int, java.lang.String) */ static void NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jstring algorithm) { // LOGI("NativeCrypto_EVP_VerifyInit"); if (ctx == NULL || algorithm == NULL) { throwNullPointerException(env); return; } const char* algorithmChars = env->GetStringUTFChars(algorithm, NULL); const EVP_MD *digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars)); env->ReleaseStringUTFChars(algorithm, algorithmChars); if (digest == NULL) { throwRuntimeException(env, "Hash algorithm not found"); return; } EVP_VerifyInit(ctx, digest); throwExceptionIfNecessary(env); }
extern int crypto_verify_sign(void * key, char *buffer, unsigned int buf_size, char *signature, unsigned int sig_size) { EVP_MD_CTX *ectx; int rc; ectx = EVP_MD_CTX_new(); EVP_VerifyInit(ectx, EVP_sha1()); EVP_VerifyUpdate(ectx, buffer, buf_size); rc = EVP_VerifyFinal(ectx, (unsigned char *) signature, sig_size, (EVP_PKEY *) key); if (rc <= 0) rc = SLURM_ERROR; else rc = SLURM_SUCCESS; EVP_MD_CTX_free(ectx); return rc; }
int evp_verify_internal(EVP_PKEY* evp, EVP_MD_CTX* ctx, enum EVP_DIGEST_TYPE type, const unsigned char* digest, unsigned int digest_length, string* s) { const EVP_MD* md = NULL; int r = 0; md = get_EVP_MD(type); if (md == NULL) { fprintf(stderr, "evp_verify_internal: no message digest\n"); return EVP_ERROR; } EVP_MD_CTX_init(ctx); if (!EVP_VerifyInit(ctx, md)) { fprintf(stderr, "evp_verify_iternal: EVP_VerifyInit failed\n"); return EVP_ERROR; } if (!EVP_VerifyUpdate(ctx, digest, digest_length)) { fprintf(stderr, "evp_verify_internal: EVP_VerifyUpdate failed\n"); return EVP_ERROR; } r = EVP_VerifyFinal(ctx, string_base(s), string_size(s), evp); switch (r) { case -1: fprintf(stderr, "evp_verify: EVP_VerifyFinal failed\n"); return EVP_ERROR; case 0: return EVP_FAILURE; default: return EVP_SUCCESS; } }
extern int crypto_verify_sign(void * key, char *buffer, unsigned int buf_size, char *signature, unsigned int sig_size) { EVP_MD_CTX ectx; int rc; EVP_VerifyInit(&ectx, EVP_sha1()); EVP_VerifyUpdate(&ectx, buffer, buf_size); rc = EVP_VerifyFinal(&ectx, (unsigned char *) signature, sig_size, (EVP_PKEY *) key); if (rc <= 0) rc = SLURM_ERROR; else rc = SLURM_SUCCESS; #ifdef HAVE_EVP_MD_CTX_CLEANUP /* Note: Likely memory leak if this function is absent */ EVP_MD_CTX_cleanup(&ectx); #endif return rc; }
const void * eet_identity_check(const void *data_base, unsigned int data_length, void **sha1, int *sha1_length, const void *signature_base, unsigned int signature_length, const void **raw_signature_base, unsigned int *raw_signature_length, int *x509_length) { #ifdef HAVE_SIGNATURE const int *header = signature_base; const unsigned char *sign; const unsigned char *cert_der; int sign_len; int cert_len; int magic; /* At least the header size */ if (signature_length < sizeof(int) * 3) return NULL; if (!emile_cipher_init()) return NULL; /* Get the header */ memcpy(&magic, header, sizeof(int)); memcpy(&sign_len, header+1, sizeof(int)); memcpy(&cert_len, header+2, sizeof(int)); magic = ntohl(magic); sign_len = ntohl(sign_len); cert_len = ntohl(cert_len); /* Verify the header */ if (magic != EET_MAGIC_SIGN) return NULL; if (sign_len + cert_len + sizeof(int) * 3 > signature_length) return NULL; /* Update the signature and certificate pointer */ sign = (unsigned char *)signature_base + sizeof(int) * 3; cert_der = sign + sign_len; # ifdef HAVE_GNUTLS gnutls_x509_crt_t cert; gnutls_datum_t datum; gnutls_datum_t signature; gnutls_pubkey_t pubkey; unsigned char *hash; gcry_md_hd_t md; int err; /* Create an understanding certificate structure for gnutls */ datum.data = (void *)cert_der; datum.size = cert_len; gnutls_x509_crt_init(&cert); gnutls_x509_crt_import(cert, &datum, GNUTLS_X509_FMT_DER); signature.data = (void *)sign; signature.size = sign_len; /* Verify the signature */ /* I am waiting for my patch being accepted in GnuTLS release. But we now have a way to prevent double computation of SHA1. */ err = gcry_md_open (&md, GCRY_MD_SHA1, 0); if (err < 0) return NULL; gcry_md_write(md, data_base, data_length); hash = gcry_md_read(md, GCRY_MD_SHA1); if (!hash) goto on_error; datum.size = gcry_md_get_algo_dlen(GCRY_MD_SHA1); datum.data = hash; if (gnutls_pubkey_init(&pubkey) < 0) goto on_error; if (gnutls_pubkey_import_x509(pubkey, cert, 0) < 0) goto on_error; if (gnutls_pubkey_verify_hash2(pubkey, gnutls_x509_crt_get_signature_algorithm(cert), 0, &datum, &signature) < 0) goto on_error; if (sha1) { *sha1 = malloc(datum.size); if (!*sha1) goto on_error; memcpy(*sha1, hash, datum.size); *sha1_length = datum.size; } gcry_md_close(md); gnutls_x509_crt_deinit(cert); # else /* ifdef HAVE_GNUTLS */ const unsigned char *tmp; EVP_PKEY *pkey; X509 *x509; #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) EVP_MD_CTX *md_ctx; #else EVP_MD_CTX md_ctx; #endif int err; /* Strange but d2i_X509 seems to put 0 all over the place. */ tmp = alloca(cert_len); memcpy((char *)tmp, cert_der, cert_len); x509 = d2i_X509(NULL, &tmp, cert_len); if (!x509) return NULL; /* Get public key - eay */ pkey = X509_get_pubkey(x509); if (!pkey) { X509_free(x509); return NULL; } /* Verify the signature */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) md_ctx = EVP_MD_CTX_new(); EVP_VerifyInit(md_ctx, EVP_sha1()); EVP_VerifyUpdate(md_ctx, data_base, data_length); err = EVP_VerifyFinal(md_ctx, sign, sign_len, pkey); EVP_MD_CTX_free(md_ctx); #else EVP_VerifyInit(&md_ctx, EVP_sha1()); EVP_VerifyUpdate(&md_ctx, data_base, data_length); err = EVP_VerifyFinal(&md_ctx, sign, sign_len, pkey); EVP_MD_CTX_cleanup(&md_ctx); #endif X509_free(x509); EVP_PKEY_free(pkey); if (sha1) { *sha1 = NULL; *sha1_length = -1; } if (err != 1) return NULL; # endif /* ifdef HAVE_GNUTLS */ if (x509_length) *x509_length = cert_len; if (raw_signature_base) *raw_signature_base = sign; if (raw_signature_length) *raw_signature_length = sign_len; return cert_der; # ifdef HAVE_GNUTLS on_error: gcry_md_close(md); return NULL; # endif #else /* ifdef HAVE_SIGNATURE */ data_base = NULL; data_length = 0; sha1 = NULL; sha1_length = NULL; signature_base = NULL; signature_length = 0; raw_signature_base = NULL; raw_signature_length = NULL; x509_length = NULL; return NULL; #endif /* ifdef HAVE_SIGNATURE */ }
int main(int argc, char *argv[]) { FILE *rsapub_key_fp; unsigned char *cam128_key, *cam128_iv; unsigned char *cipher_of_secret_text, *cipher_of_signed_key, *signed_key, *secret_text, *clobbered_key; EVP_PKEY *rsapub_key; unsigned char *rc4_40_key; const EVP_CIPHER *cam128_cfb8, *rc4_40; const EVP_MD *sha; EVP_MD_CTX sha_ctx; int cam128_cfb8_keylen, cam128_cfb8_ivlen, rc4_40_keylen, signed_key_size; int ret, count; long cipher_of_signed_key_size, clobbered_key_size, cipher_of_secret_text_size, secret_text_size; // get the parameters for CAMELLIA128_cfb8 cam128_cfb8 = EVP_camellia_128_cfb8(); cam128_cfb8_keylen = EVP_CIPHER_key_length(cam128_cfb8); cam128_cfb8_ivlen = EVP_CIPHER_iv_length(cam128_cfb8); // get the parameters for RC4_40 rc4_40 = EVP_rc4_40(); rc4_40_keylen = EVP_CIPHER_key_length(rc4_40); // get the parameters for sha sha = EVP_sha(); // read the s67766-clobbered-key.bin and store the key and iv for CAMELLIA128-cfb8 cam128_key = malloc(cam128_cfb8_keylen); cam128_iv = malloc(cam128_cfb8_ivlen); clobbered_key_size = read_file(clobbered_key_file, &clobbered_key); if(clobbered_key_size != cam128_cfb8_keylen+cam128_cfb8_ivlen) { printf("reading file %s returned not enough Bytes: %ld, instead of: %d\n", clobbered_key_file, clobbered_key_size, cam128_cfb8_keylen+cam128_cfb8_ivlen); perror(""); } memcpy(cam128_key, clobbered_key, cam128_cfb8_keylen); memcpy(cam128_iv, clobbered_key+cam128_cfb8_keylen, cam128_cfb8_ivlen); // read the s67766-cipher-of-signed-key.bin cipher_of_signed_key_size = read_file(cipher_of_signed_key_file, &cipher_of_signed_key); // read the public key from rsapub.pem rsapub_key_fp = fopen(rsapub_key_file, "r"); if (!rsapub_key_fp) { printf("opening file %s returned error\n", rsapub_key_file); perror(""); } rsapub_key = PEM_read_PUBKEY(rsapub_key_fp, NULL, NULL, NULL); if (!rsapub_key) { printf("PEM_read_PUBKEY returned error for RSA\n"); } if(fclose(rsapub_key_fp) != 0) { printf("closing file %s returned error\n", rsapub_key_file); perror(""); } // restore the clobbered key with bruteforce signed_key = malloc(cipher_of_signed_key_size); for(count = 0; count<=255; count++) { memset(cam128_key, count, 1); //decrypt the cipher with guessed key signed_key_size = decrypt(cam128_cfb8, &signed_key, cipher_of_signed_key, cipher_of_signed_key_size, cam128_key, cam128_iv); if(signed_key_size==-1) { return -1; } if(EVP_VerifyInit(&sha_ctx, sha) == 0) { printf("EVP_VerifyInit returned error for SHA\n"); } if(EVP_VerifyUpdate(&sha_ctx, signed_key, rc4_40_keylen) == 0) { printf("EVP_VerifyUpdate returned error for SHA\n"); } ret = EVP_VerifyFinal(&sha_ctx, signed_key+rc4_40_keylen, signed_key_size-rc4_40_keylen, rsapub_key); switch(ret) { case -1: printf("EVP_VerifyFinal returned error for SHA\n"); break; case 0: break; case 1: count = 255; break; } } // extract the key for RC-4 40 rc4_40_key = malloc(rc4_40_keylen); memcpy(rc4_40_key, signed_key, rc4_40_keylen); // read the s67766-cipher-of-secret-text.bin cipher_of_secret_text_size = read_file(cipher_of_secret_text_file, &cipher_of_secret_text); // decrypt s67766-cipher-of-secret-text.bin secret_text = malloc(cipher_of_secret_text_size); secret_text_size = 0; secret_text_size = decrypt(rc4_40, &secret_text, cipher_of_secret_text, cipher_of_secret_text_size, rc4_40_key, NULL); // write the s67766-plain.bin if(write_file(plain_file, secret_text, secret_text_size)==-1) { return -1; } return 0; }
SISSignature* makeSignature(SISField* controller, const char* keyData, const char* passphrase, SigType type, EVP_PKEY* publicKey) { if (type == SigAuto) { if (strstr(keyData, " DSA ")) type = SigDsa; else type = SigRsa; } BIO* io = BIO_new_mem_buf((void*) keyData, -1); EVP_PKEY* key = PEM_read_bio_PrivateKey(io, NULL, password_cb, (void*) passphrase); if (!key) { ERR_print_errors_fp(stderr); fprintf(stderr, "Unable to load key\n"); throw SignBadKey; } BIO_free_all(io); uint8_t* buffer = new uint8_t[controller->Length()]; uint8_t* ptr = buffer; controller->CopyFieldData(ptr); EVP_MD_CTX ctx, verify; EVP_MD_CTX_init(&ctx); EVP_MD_CTX_init(&verify); const EVP_MD* md = NULL; if (type == SigDsa) md = EVP_dss1(); else md = EVP_sha1(); if (EVP_SignInit_ex(&ctx, md, NULL) == 0) { ERR_print_errors_fp(stderr); throw SignOpenSSLErr; } if (EVP_VerifyInit(&verify, md) < 0) { ERR_print_errors_fp(stderr); throw SignOpenSSLErr; } if (EVP_SignUpdate(&ctx, buffer, controller->Length()) == 0) { ERR_print_errors_fp(stderr); throw SignOpenSSLErr; } if (EVP_VerifyUpdate(&verify, buffer, controller->Length()) == 0) { ERR_print_errors_fp(stderr); throw SignOpenSSLErr; } delete [] buffer; unsigned int siglen = EVP_PKEY_size(key); uint8_t* signature = new uint8_t[siglen]; if (EVP_SignFinal(&ctx, signature, &siglen, key) == 0) { ERR_print_errors_fp(stderr); throw SignOpenSSLErr; } EVP_MD_CTX_cleanup(&ctx); int ret = EVP_VerifyFinal(&verify, signature, siglen, publicKey); if (ret < 0) { ERR_print_errors_fp(stderr); throw SignOpenSSLErr; } if (ret == 0) { fprintf(stderr, "Could not verify signature with certificate\n"); throw SignBadKey; } EVP_MD_CTX_cleanup(&verify); EVP_PKEY_free(key); SISString* algorithm = NULL; if (type == SigDsa) algorithm = new SISString(L"1.2.840.10040.4.3"); else algorithm = new SISString(L"1.2.840.113549.1.1.5"); SISSignatureAlgorithm* signatureAlgorithm = new SISSignatureAlgorithm(algorithm); SISBlob* blob = new SISBlob(signature, siglen); delete [] signature; return new SISSignature(signatureAlgorithm, blob); }
/** * Check a canonical sig+rrset and signature against a dnskey * @param buf: buffer with data to verify, the first rrsig part and the * canonicalized rrset. * @param algo: DNSKEY algorithm. * @param sigblock: signature rdata field from RRSIG * @param sigblock_len: length of sigblock data. * @param key: public key data from DNSKEY RR. * @param keylen: length of keydata. * @param reason: bogus reason in more detail. * @return secure if verification succeeded, bogus on crypto failure, * unchecked on format errors and alloc failures. */ int _getdns_verify_canonrrset(gldns_buffer* buf, int algo, unsigned char* sigblock, unsigned int sigblock_len, unsigned char* key, unsigned int keylen, char** reason) { const EVP_MD *digest_type; EVP_MD_CTX* ctx; int res, dofree = 0; EVP_PKEY *evp_key = NULL; if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) { verbose(VERB_QUERY, "verify: failed to setup key"); *reason = "use of key for crypto failed"; EVP_PKEY_free(evp_key); return 0; } #ifdef USE_DSA /* if it is a DSA signature in bind format, convert to DER format */ if((algo == GLDNS_DSA || algo == GLDNS_DSA_NSEC3) && sigblock_len == 1+2*SHA_DIGEST_LENGTH) { if(!setup_dsa_sig(&sigblock, &sigblock_len)) { verbose(VERB_QUERY, "verify: failed to setup DSA sig"); *reason = "use of key for DSA crypto failed"; EVP_PKEY_free(evp_key); return 0; } dofree = 1; } #endif #if defined(USE_ECDSA) && defined(USE_DSA) else #endif #ifdef USE_ECDSA if(algo == GLDNS_ECDSAP256SHA256 || algo == GLDNS_ECDSAP384SHA384) { /* EVP uses ASN prefix on sig, which is not in the wire data */ if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) { verbose(VERB_QUERY, "verify: failed to setup ECDSA sig"); *reason = "use of signature for ECDSA crypto failed"; EVP_PKEY_free(evp_key); return 0; } dofree = 1; } #endif /* USE_ECDSA */ /* do the signature cryptography work */ #ifdef HAVE_EVP_MD_CTX_NEW ctx = EVP_MD_CTX_new(); #else ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx)); if(ctx) EVP_MD_CTX_init(ctx); #endif if(!ctx) { log_err("EVP_MD_CTX_new: malloc failure"); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); return 0; } if(EVP_VerifyInit(ctx, digest_type) == 0) { verbose(VERB_QUERY, "verify: EVP_VerifyInit failed"); EVP_MD_CTX_destroy(ctx); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); return 0; } if(EVP_VerifyUpdate(ctx, (unsigned char*)gldns_buffer_begin(buf), (unsigned int)gldns_buffer_limit(buf)) == 0) { verbose(VERB_QUERY, "verify: EVP_VerifyUpdate failed"); EVP_MD_CTX_destroy(ctx); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); return 0; } res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key); EVP_MD_CTX_destroy(ctx); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); if(res == 1) { return 1; } else if(res == 0) { verbose(VERB_QUERY, "verify: signature mismatch"); *reason = "signature crypto failed"; return 0; } log_crypto_error("verify:", ERR_get_error()); return 0; }
int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, X509 *x509) { ASN1_OCTET_STRING *os; EVP_MD_CTX mdc_tmp,*mdc; unsigned char *pp,*p; int ret=0,i; int md_type; STACK_OF(X509_ATTRIBUTE) *sk; BIO *btmp; EVP_PKEY *pkey; if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); goto err; } md_type=OBJ_obj2nid(si->digest_alg->algorithm); btmp=bio; for (;;) { if ((btmp == NULL) || ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL)) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } BIO_get_md_ctx(btmp,&mdc); if (mdc == NULL) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_INTERNAL_ERROR); goto err; } if (EVP_MD_CTX_type(mdc) == md_type) break; btmp=BIO_next(btmp); } /* mdc is the digest ctx that we want, unless there are attributes, * in which case the digest is the signed attributes */ memcpy(&mdc_tmp,mdc,sizeof(mdc_tmp)); sk=si->auth_attr; if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { unsigned char md_dat[EVP_MAX_MD_SIZE]; unsigned int md_len; ASN1_OCTET_STRING *message_digest; EVP_DigestFinal(&mdc_tmp,md_dat,&md_len); message_digest=PKCS7_digest_from_attributes(sk); if (!message_digest) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } if ((message_digest->length != (int)md_len) || (memcmp(message_digest->data,md_dat,md_len))) { #if 0 { int ii; for (ii=0; ii<message_digest->length; ii++) printf("%02X",message_digest->data[ii]); printf(" sent\n"); for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n"); } #endif PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE); ret= -1; goto err; } EVP_VerifyInit(&mdc_tmp,EVP_get_digestbynid(md_type)); /* Note: when forming the encoding of the attributes we * shouldn't reorder them or this will break the signature. * This is done by using the IS_SEQUENCE flag. */ i=i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,NULL,i2d_X509_ATTRIBUTE, V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE); pp=OPENSSL_malloc(i); p=pp; i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,&p,i2d_X509_ATTRIBUTE, V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE); EVP_VerifyUpdate(&mdc_tmp,pp,i); OPENSSL_free(pp); } os=si->enc_digest; pkey = X509_get_pubkey(x509); if (!pkey) { ret = -1; goto err; } #ifndef NO_DSA if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); #endif i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); EVP_PKEY_free(pkey); if (i <= 0) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); ret= -1; goto err; } else ret=1; err: return(ret); }
static void input_userauth_u2f_register_response(int type, u_int32_t seq, void *ctxt) { #define u2f_bounds_check(necessary_bytes) do { \ if (restlen < necessary_bytes) { \ logit("U2F response too short: need %d bytes, but only %d remaining", \ necessary_bytes, restlen); \ goto out; \ } \ } while (0) #define u2f_advance(parsed_bytes) do { \ int advance = parsed_bytes; \ walk += advance; \ restlen -= advance; \ } while (0) Authctxt *authctxt = ctxt; char *response, *regdata, *clientdata; u_char *decoded = NULL; u_char *walk = NULL; u_char *keyhandle = NULL; u_char *pubkey = NULL; u_char *signature = NULL; u_char *dummy = NULL; u_char *cdecoded = NULL; X509 *x509; EVP_MD_CTX mdctx; int restlen; int khlen; int cdecodedlen; int err; char errorbuf[4096]; u_char digest[ssh_digest_bytes(SSH_DIGEST_SHA256)]; authctxt->postponed = 0; response = packet_get_string(NULL); packet_check_eom(); if ((regdata = extract_json_string(response, "registrationData")) == NULL) { logit("Response not JSON, or does not contain \"registrationData\""); goto out; } decoded = xmalloc(strlen(regdata) * 3 / 4); restlen = urlsafe_base64_decode(regdata, decoded, strlen(regdata) * 3 / 4); walk = decoded; // Header (magic byte) u2f_bounds_check(1); if (walk[0] != 0x05) { logit("U2F response does not start with magic byte 0x05"); goto out; } u2f_advance(1); // Length of the public key u2f_bounds_check(u2f_pubkey_len); pubkey = walk; u2f_advance(u2f_pubkey_len); // Length of the key handle u2f_bounds_check(1); khlen = walk[0]; u2f_advance(1); // Key handle u2f_bounds_check(khlen); keyhandle = walk; u2f_advance(khlen); // Attestation certificate u2f_bounds_check(1); signature = walk; if ((x509 = d2i_X509(NULL, &signature, restlen)) == NULL) { logit("U2F response contains an invalid attestation certificate."); goto out; } // U2F dictates that the length of the certificate should be determined by // encoding the certificate using DER. u2f_advance(i2d_X509(x509, &dummy)); free(dummy); // Ensure we have at least one byte of signature. u2f_bounds_check(1); if ((clientdata = extract_json_string(response, "clientData")) == NULL) { logit("U2F response JSON lacks the \"clientData\" key."); goto out; } cdecoded = xmalloc(strlen(clientdata) * 3 / 4); cdecodedlen = urlsafe_base64_decode(clientdata, cdecoded, strlen(clientdata) * 3 / 4); EVP_PKEY *pkey = X509_get_pubkey(x509); if ((err = EVP_VerifyInit(&mdctx, EVP_ecdsa())) != 1) { ERR_error_string(ERR_get_error(), errorbuf); fatal("EVP_VerifyInit() failed: %s (reason: %s)", errorbuf, ERR_reason_error_string(err)); } EVP_VerifyUpdate(&mdctx, "\0", 1); u2f_sha256(digest, appid, strlen(appid)); EVP_VerifyUpdate(&mdctx, digest, sizeof(digest)); u2f_sha256(digest, cdecoded, cdecodedlen); EVP_VerifyUpdate(&mdctx, digest, sizeof(digest)); EVP_VerifyUpdate(&mdctx, keyhandle, khlen); EVP_VerifyUpdate(&mdctx, pubkey, u2f_pubkey_len); if ((err = EVP_VerifyFinal(&mdctx, walk, restlen, pkey)) == -1) { ERR_error_string(ERR_get_error(), errorbuf); logit("Verifying the U2F registration signature failed: %s (reason: %s)", errorbuf, ERR_reason_error_string(err)); goto out; } EVP_PKEY_free(pkey); { char *authorizedkey; char key[u2f_pubkey_len + khlen]; char key64[((sizeof(key)+2)/3)*4 + 1]; memcpy(key, pubkey, u2f_pubkey_len); memcpy(key+u2f_pubkey_len, keyhandle, khlen); if (b64_ntop(key, sizeof(key), key64, sizeof(key64)) == -1) fatal("b64_ntop()"); xasprintf(&authorizedkey, "ssh-u2f %s", key64); packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST); packet_put_cstring(authorizedkey); packet_send(); free(authorizedkey); dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); } out: free(decoded); userauth_finish(authctxt, 0, "u2f", NULL); return; #undef u2f_bounds_check #undef u2f_advance }
int main(int argc, char * const argv[]) { int ret = EX_DATAERR; ssize_t cd_len, reg_len; unsigned char kh_len; unsigned const char *kh, *sig; size_t siglen; EVP_PKEY *pkey = NULL; unsigned char cp_hash[SHA256_DIGEST_LENGTH]; unsigned char ap_hash[SHA256_DIGEST_LENGTH]; EVP_MD_CTX ctx; X509 *crt = NULL; unsigned const char *ptr; int i; cd_len = strlen(clientData); reg_len = sizeof(registrationData); if (registrationData[0] != 0x05) { fprintf(stderr, "invalid header byte\n"); goto DONE; } /* key handle */ kh = registrationData+67; kh_len = registrationData[66]; /* parse attestation certificate (X.509) */ ptr = registrationData + 67 + kh_len; crt = d2i_X509(NULL, (const unsigned char**)&ptr, reg_len - (ptr-registrationData)); if (crt == NULL) { fprintf(stderr, "Error while parsing X509\n"); goto DONE; } /* check if this is a valid signature */ sig = ptr; ECDSA_SIG *ecsig = d2i_ECDSA_SIG(NULL, (const unsigned char**)&ptr, reg_len - (ptr-registrationData)); if (ecsig == NULL) { fprintf(stderr, "Error while reading signature\n"); ECDSA_SIG_free(ecsig); ecsig = NULL; goto DONE; } siglen = ptr-sig; ECDSA_SIG_free(ecsig); ecsig = NULL; /* extract public key from X509 attestation certificare */ pkey = X509_get_pubkey(crt); if (pkey == NULL) { fprintf(stderr, "Can't get public key!\n"); goto DONE; } /* generate SHA256 hash on challenge parameter and application parameter */ (void)SHA256((const unsigned char*)clientData, cd_len, cp_hash); (void)SHA256((const unsigned char*)appId, strlen(appId), ap_hash); /* verify signature */ if (EVP_VerifyInit(&ctx, EVP_sha256()) != 1) { fprintf(stderr, "EVP_VerifyInit() failed\n"); goto DONE; } (void)EVP_VerifyUpdate(&ctx, "\0", 1UL); (void)EVP_VerifyUpdate(&ctx, ap_hash, 32UL); (void)EVP_VerifyUpdate(&ctx, cp_hash, 32UL); (void)EVP_VerifyUpdate(&ctx, kh, (unsigned long)kh_len); (void)EVP_VerifyUpdate(&ctx, registrationData+1, 65UL); if ((i = EVP_VerifyFinal(&ctx, sig, siglen, pkey)) != 1) { fprintf(stderr, "EVP_VerifyFinal failed: err=%i, %s\n", i, ERR_error_string(ERR_get_error(), NULL)); (void)EVP_MD_CTX_cleanup(&ctx); goto DONE; } (void)EVP_MD_CTX_cleanup(&ctx); printf("Valid response.\n"); ret = EX_OK; DONE: if (crt != NULL) { X509_free(crt); crt = NULL; } if (pkey != NULL) { EVP_PKEY_free(pkey); pkey = NULL; } return(ret); }
/** * Check a canonical sig+rrset and signature against a dnskey * @param buf: buffer with data to verify, the first rrsig part and the * canonicalized rrset. * @param algo: DNSKEY algorithm. * @param sigblock: signature rdata field from RRSIG * @param sigblock_len: length of sigblock data. * @param key: public key data from DNSKEY RR. * @param keylen: length of keydata. * @param reason: bogus reason in more detail. * @return secure if verification succeeded, bogus on crypto failure, * unchecked on format errors and alloc failures. */ enum sec_status verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock, unsigned int sigblock_len, unsigned char* key, unsigned int keylen, char** reason) { const EVP_MD *digest_type; EVP_MD_CTX ctx; int res, dofree = 0; EVP_PKEY *evp_key = NULL; if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) { verbose(VERB_QUERY, "verify: failed to setup key"); *reason = "use of key for crypto failed"; EVP_PKEY_free(evp_key); return sec_status_bogus; } /* if it is a DSA signature in bind format, convert to DER format */ if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && sigblock_len == 1+2*SHA_DIGEST_LENGTH) { if(!setup_dsa_sig(&sigblock, &sigblock_len)) { verbose(VERB_QUERY, "verify: failed to setup DSA sig"); *reason = "use of key for DSA crypto failed"; EVP_PKEY_free(evp_key); return sec_status_bogus; } dofree = 1; } #ifdef USE_ECDSA else if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) { /* EVP uses ASN prefix on sig, which is not in the wire data */ if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) { verbose(VERB_QUERY, "verify: failed to setup ECDSA sig"); *reason = "use of signature for ECDSA crypto failed"; EVP_PKEY_free(evp_key); return sec_status_bogus; } dofree = 1; } #endif /* USE_ECDSA */ /* do the signature cryptography work */ EVP_MD_CTX_init(&ctx); if(EVP_VerifyInit(&ctx, digest_type) == 0) { verbose(VERB_QUERY, "verify: EVP_VerifyInit failed"); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); return sec_status_unchecked; } if(EVP_VerifyUpdate(&ctx, (unsigned char*)ldns_buffer_begin(buf), (unsigned int)ldns_buffer_limit(buf)) == 0) { verbose(VERB_QUERY, "verify: EVP_VerifyUpdate failed"); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); return sec_status_unchecked; } res = EVP_VerifyFinal(&ctx, sigblock, sigblock_len, evp_key); if(EVP_MD_CTX_cleanup(&ctx) == 0) { verbose(VERB_QUERY, "verify: EVP_MD_CTX_cleanup failed"); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); return sec_status_unchecked; } EVP_PKEY_free(evp_key); if(dofree) free(sigblock); if(res == 1) { return sec_status_secure; } else if(res == 0) { verbose(VERB_QUERY, "verify: signature mismatch"); *reason = "signature crypto failed"; return sec_status_bogus; } log_crypto_error("verify:", ERR_get_error()); return sec_status_unchecked; }
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 main(int argc, char *argv[]) { FILE *fin, *fkey; u_int16_t siglen; u_int32_t magic; long nread, ndata; char *sigbuf, *inbuf; EVP_PKEY *pkey; EVP_MD_CTX ctx; int err, retval; if (argc != 3) usage(); ERR_load_crypto_strings(); /* open file and check for magic */ fin = fopen(argv[2], "r+"); if (fin == NULL) { fprintf(stderr, "unable to open file '%s'\n", argv[2]); exit(4); } fseek(fin, -(sizeof(magic)), SEEK_END); fread(&magic, sizeof(magic), 1, fin); if (magic != SIG_MAGIC) { fclose(fin); exit(2); } /* magic is good; get signature length */ fseek(fin, -(sizeof(magic) + sizeof(siglen)), SEEK_END); fread(&siglen, sizeof(siglen), 1, fin); /* read public key */ fkey = fopen(argv[1], "r"); if (fkey == NULL) { fprintf(stderr, "unable to open public key file '%s'\n", argv[1]); exit(4); } pkey = PEM_read_PUBKEY(fkey, NULL, NULL, NULL); fclose(fkey); if (pkey == NULL) { ERR_print_errors_fp(stderr); exit(4); } /* check if siglen is sane */ if ((siglen == 0) || (siglen > EVP_PKEY_size(pkey))) exit(3); /* got signature length; read signature */ sigbuf = malloc(siglen); if (sigbuf == NULL) exit(4); fseek(fin, -(sizeof(magic) + sizeof(siglen) + siglen), SEEK_END); if (fread(sigbuf, 1, siglen, fin) != siglen) exit(4); /* signature read; truncate file to remove sig */ fseek(fin, 0, SEEK_END); ndata = ftell(fin) - (sizeof(magic) + sizeof(siglen) + siglen); ftruncate(fileno(fin), ndata); /* verify the signature now */ EVP_VerifyInit(&ctx, EVP_sha1()); /* allocate data buffer */ inbuf = malloc(SIG_INBUFLEN); if (inbuf == NULL) exit(4); rewind(fin); while (!feof(fin)) { nread = fread(inbuf, 1, SIG_INBUFLEN, fin); if (nread != SIG_INBUFLEN) { if (ferror(fin)) { fprintf(stderr, "read error in file '%s'\n", argv[2]); exit(4); } } EVP_VerifyUpdate(&ctx, inbuf, nread); } err = EVP_VerifyFinal(&ctx, sigbuf, siglen, pkey); EVP_PKEY_free(pkey); if (err == 1) retval = 0; /* correct signature */ else if (err == 0) retval = 1; /* invalid signature */ else retval = 3; /* error */ free(inbuf); free(sigbuf); fclose(fin); return retval; }
AXIS2_EXTERN axis2_status_t AXIS2_CALL openssl_sig_verify(const axutil_env_t *env, openssl_pkey_t *pubkey, oxs_buffer_t *input_buf, oxs_buffer_t *sig_buf) { axis2_status_t status = AXIS2_FAILURE; const EVP_MD* digest; EVP_MD_CTX md_ctx; EVP_PKEY* pkey = NULL; int ret; /*Get the publickey*/ pkey = openssl_pkey_get_key(pubkey, env); if(!pkey){ oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_SIG_VERIFICATION_FAILED,"Cannot load the public key" ); } /*TODO Set the digest according to the signature method*/ digest = EVP_sha1(); /*Init MD Ctx*/ EVP_MD_CTX_init(&md_ctx); /*Intialize verification*/ ret = EVP_VerifyInit(&md_ctx, digest); if(ret != 1) { /*Error*/ oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_SIG_VERIFICATION_FAILED,"EVP_VerifyInit failed" ); return AXIS2_FAILURE; } ret = EVP_VerifyUpdate(&md_ctx, oxs_buffer_get_data(input_buf, env), oxs_buffer_get_size(input_buf, env)); if(ret != 1) { /*Error*/ oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_SIG_VERIFICATION_FAILED,"EVP_VerifyUpdate failed" ); return AXIS2_FAILURE; } ret = EVP_VerifyFinal(&md_ctx, oxs_buffer_get_data(sig_buf, env), oxs_buffer_get_size(sig_buf, env), pkey); if(ret == 0){ /*Error. Signature verification FAILED */ oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_SIG_VERIFICATION_FAILED,"Signature verification FAILED." ); status = AXIS2_FAILURE; }else if(ret < 0){ /*Erorr. Some other error*/ oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_SIG_VERIFICATION_FAILED,"Error occured while verifying the signature." ); status = AXIS2_FAILURE; }else{ /*SUCCESS. */ AXIS2_LOG_INFO(env->log, "[openssl][sig] Signature verification SUCCESS " ); status = AXIS2_SUCCESS; } EVP_MD_CTX_cleanup(&md_ctx); return status; }
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[]) { 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; }
/** @fn int soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen) @brief Initiates a (signed) digest computation. @param soap context @param[in,out] data smdevp engine context @param[in] alg is algorithm to use @param[in] key is key to use or NULL for digests @param[in] keylen is length of HMAC key (when provided) @return SOAP_OK or SOAP_SSL_ERROR */ int soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen) { int ok = 1; const EVP_MD *type; soap_ssl_init(); /* the algorithm to use */ data->alg = alg; /* the key to use */ data->key = key; /* allocate and init the OpenSSL HMAC or EVP_MD context */ if ((alg & SOAP_SMD_ALGO) == SOAP_SMD_HMAC) { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(HMAC_CTX)); if (!data->ctx) return soap_set_receiver_error(soap, "soap_smd_init() failed", "No context", SOAP_SSL_ERROR); HMAC_CTX_init((HMAC_CTX*)data->ctx); } else { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(EVP_MD_CTX)); if (!data->ctx) return soap_set_receiver_error(soap, "soap_smd_init() failed", "No context", SOAP_SSL_ERROR); EVP_MD_CTX_init((EVP_MD_CTX*)data->ctx); } DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Init alg=%x (%p) --\n", alg, data->ctx)); /* init the digest or signature computations */ switch (alg & SOAP_SMD_HASH) { case SOAP_SMD_MD5: type = EVP_md5(); break; case SOAP_SMD_SHA1: type = EVP_sha1(); break; #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) case SOAP_SMD_SHA224: type = EVP_sha224(); break; case SOAP_SMD_SHA256: type = EVP_sha256(); break; case SOAP_SMD_SHA384: type = EVP_sha384(); break; case SOAP_SMD_SHA512: type = EVP_sha512(); break; #endif default: return soap_smd_check(soap, data, 0, "soap_smd_init() failed: cannot load digest"); } switch (alg & SOAP_SMD_ALGO) { case SOAP_SMD_HMAC: HMAC_Init((HMAC_CTX*)data->ctx, key, keylen, type); break; case SOAP_SMD_DGST: EVP_DigestInit((EVP_MD_CTX*)data->ctx, type); break; case SOAP_SMD_SIGN: ok = EVP_SignInit((EVP_MD_CTX*)data->ctx, type); break; case SOAP_SMD_VRFY: ok = EVP_VerifyInit((EVP_MD_CTX*)data->ctx, type); break; default: return soap_set_receiver_error(soap, "Unsupported digest algorithm", NULL, SOAP_SSL_ERROR); } /* check and return */ return soap_smd_check(soap, data, ok, "soap_smd_init() failed"); }