bool OSSLRSA::verifyFinal(const ByteString& signature) { // Save necessary state before calling super class verifyFinal OSSLRSAPublicKey* pk = (OSSLRSAPublicKey*) currentPublicKey; AsymMech::Type mechanism = currentMechanism; if (!AsymmetricAlgorithm::verifyFinal(signature)) { return false; } ByteString firstHash, secondHash; bool bFirstResult = pCurrentHash->hashFinal(firstHash); bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true; delete pCurrentHash; pCurrentHash = NULL; if (pSecondHash != NULL) { delete pSecondHash; pSecondHash = NULL; } if (!bFirstResult || !bSecondResult) { return false; } ByteString digest = firstHash + secondHash; // Determine the signature NID type int type = 0; bool isPSS = false; const EVP_MD* hash = NULL; switch (mechanism) { case AsymMech::RSA_MD5_PKCS: type = NID_md5; break; case AsymMech::RSA_SHA1_PKCS: type = NID_sha1; break; case AsymMech::RSA_SHA224_PKCS: type = NID_sha224; break; case AsymMech::RSA_SHA256_PKCS: type = NID_sha256; break; case AsymMech::RSA_SHA384_PKCS: type = NID_sha384; break; case AsymMech::RSA_SHA512_PKCS: type = NID_sha512; break; case AsymMech::RSA_SHA1_PKCS_PSS: isPSS = true; hash = EVP_sha1(); break; case AsymMech::RSA_SHA224_PKCS_PSS: isPSS = true; hash = EVP_sha224(); break; case AsymMech::RSA_SHA256_PKCS_PSS: isPSS = true; hash = EVP_sha256(); break; case AsymMech::RSA_SHA384_PKCS_PSS: isPSS = true; hash = EVP_sha384(); break; case AsymMech::RSA_SHA512_PKCS_PSS: isPSS = true; hash = EVP_sha512(); break; case AsymMech::RSA_SSL: type = NID_md5_sha1; break; default: break; } // Perform the verify operation bool rv; if (isPSS) { ByteString plain; plain.resize(pk->getN().size()); int result = RSA_public_decrypt(signature.size(), (unsigned char*) signature.const_byte_str(), &plain[0], pk->getOSSLKey(), RSA_NO_PADDING); if (result < 0) { rv = false; ERROR_MSG("RSA public decrypt failed (0x%08X)", ERR_get_error()); } else { plain.resize(result); result = RSA_verify_PKCS1_PSS(pk->getOSSLKey(), &digest[0], hash, &plain[0], sLen); if (result == 1) { rv = true; } else { rv = false; ERROR_MSG("RSA PSS verify failed (0x%08X)", ERR_get_error()); } } } else { rv = (RSA_verify(type, &digest[0], digest.size(), (unsigned char*) signature.const_byte_str(), signature.size(), pk->getOSSLKey()) == 1); if (!rv) ERROR_MSG("RSA verify failed (0x%08X)", ERR_get_error()); } return rv; }
int KA_CTX_set_protocol(KA_CTX *ctx, int protocol) { if (!ctx) { log_err("Invalid arguments"); return 0; } if ( protocol == NID_id_CA_DH_3DES_CBC_CBC || protocol == NID_id_PACE_DH_GM_3DES_CBC_CBC || protocol == NID_id_PACE_DH_IM_3DES_CBC_CBC) { ctx->generate_key = dh_generate_key; ctx->compute_key = dh_compute_key; ctx->mac_keylen = 16; ctx->md = EVP_sha1(); ctx->cipher = EVP_des_ede_cbc(); ctx->enc_keylen = ctx->cipher->key_len; } else if (protocol == NID_id_CA_DH_AES_CBC_CMAC_128 || protocol == NID_id_PACE_DH_GM_AES_CBC_CMAC_128 || protocol == NID_id_PACE_DH_IM_AES_CBC_CMAC_128) { ctx->generate_key = dh_generate_key; ctx->compute_key = dh_compute_key; ctx->mac_keylen = 16; ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */ ctx->md = EVP_sha1(); ctx->cipher = EVP_aes_128_cbc(); ctx->enc_keylen = ctx->cipher->key_len; } else if (protocol == NID_id_CA_DH_AES_CBC_CMAC_192 || protocol == NID_id_PACE_DH_GM_AES_CBC_CMAC_192 || protocol == NID_id_PACE_DH_IM_AES_CBC_CMAC_192) { ctx->generate_key = dh_generate_key; ctx->compute_key = dh_compute_key; ctx->mac_keylen = 24; ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */ ctx->md = EVP_sha256(); ctx->cipher = EVP_aes_192_cbc(); ctx->enc_keylen = ctx->cipher->key_len; } else if (protocol == NID_id_CA_DH_AES_CBC_CMAC_256 || protocol == NID_id_PACE_DH_GM_AES_CBC_CMAC_256 || protocol == NID_id_PACE_DH_IM_AES_CBC_CMAC_256) { ctx->generate_key = dh_generate_key; ctx->compute_key = dh_compute_key; ctx->mac_keylen = 32; ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */ ctx->md = EVP_sha256(); ctx->cipher = EVP_aes_256_cbc(); ctx->enc_keylen = ctx->cipher->key_len; } else if (protocol == NID_id_CA_ECDH_3DES_CBC_CBC || protocol == NID_id_PACE_ECDH_GM_3DES_CBC_CBC || protocol == NID_id_PACE_ECDH_IM_3DES_CBC_CBC) { ctx->generate_key = ecdh_generate_key; ctx->compute_key = ecdh_compute_key; ctx->mac_keylen = 16; ctx->md = EVP_sha1(); ctx->cipher = EVP_des_ede_cbc(); ctx->enc_keylen = ctx->cipher->key_len; } else if (protocol == NID_id_CA_ECDH_AES_CBC_CMAC_128 || protocol == NID_id_PACE_ECDH_GM_AES_CBC_CMAC_128 || protocol == NID_id_PACE_ECDH_IM_AES_CBC_CMAC_128) { ctx->generate_key = ecdh_generate_key; ctx->compute_key = ecdh_compute_key; ctx->mac_keylen = 16; ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */ ctx->md = EVP_sha1(); ctx->cipher = EVP_aes_128_cbc(); ctx->enc_keylen = ctx->cipher->key_len; } else if (protocol == NID_id_CA_ECDH_AES_CBC_CMAC_192 || protocol == NID_id_PACE_ECDH_GM_AES_CBC_CMAC_192 || protocol == NID_id_PACE_ECDH_IM_AES_CBC_CMAC_192) { ctx->generate_key = ecdh_generate_key; ctx->compute_key = ecdh_compute_key; ctx->mac_keylen = 24; ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */ ctx->md = EVP_sha256(); ctx->cipher = EVP_aes_192_cbc(); ctx->enc_keylen = ctx->cipher->key_len; } else if (protocol == NID_id_CA_ECDH_AES_CBC_CMAC_256 || protocol == NID_id_PACE_ECDH_GM_AES_CBC_CMAC_256 || protocol == NID_id_PACE_ECDH_IM_AES_CBC_CMAC_256) { ctx->generate_key = ecdh_generate_key; ctx->compute_key = ecdh_compute_key; ctx->mac_keylen = 32; ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */ ctx->md = EVP_sha256(); ctx->cipher = EVP_aes_256_cbc(); ctx->enc_keylen = ctx->cipher->key_len; } else { log_err("Unknown protocol"); return 0; } return 1; }
int SSL_library_init(void) { #ifndef OPENSSL_NO_DES EVP_add_cipher(EVP_des_cbc()); EVP_add_cipher(EVP_des_ede3_cbc()); #endif #ifndef OPENSSL_NO_IDEA EVP_add_cipher(EVP_idea_cbc()); #endif #ifndef OPENSSL_NO_RC4 EVP_add_cipher(EVP_rc4()); #if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__)) EVP_add_cipher(EVP_rc4_hmac_md5()); #endif #endif #ifndef OPENSSL_NO_RC2 EVP_add_cipher(EVP_rc2_cbc()); /* Not actually used for SSL/TLS but this makes PKCS#12 work * if an application only calls SSL_library_init(). */ EVP_add_cipher(EVP_rc2_40_cbc()); #endif #ifndef OPENSSL_NO_AES EVP_add_cipher(EVP_aes_128_cbc()); EVP_add_cipher(EVP_aes_192_cbc()); EVP_add_cipher(EVP_aes_256_cbc()); EVP_add_cipher(EVP_aes_128_gcm()); EVP_add_cipher(EVP_aes_256_gcm()); #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); #endif #endif #ifndef OPENSSL_NO_CAMELLIA EVP_add_cipher(EVP_camellia_128_cbc()); EVP_add_cipher(EVP_camellia_256_cbc()); #endif #ifndef OPENSSL_NO_SEED EVP_add_cipher(EVP_seed_cbc()); #endif #ifndef OPENSSL_NO_MD5 EVP_add_digest(EVP_md5()); EVP_add_digest_alias(SN_md5,"ssl2-md5"); EVP_add_digest_alias(SN_md5,"ssl3-md5"); #endif #ifndef OPENSSL_NO_SHA EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ EVP_add_digest_alias(SN_sha1,"ssl3-sha1"); EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA); #endif #ifndef OPENSSL_NO_SHA256 EVP_add_digest(EVP_sha224()); EVP_add_digest(EVP_sha256()); #endif #ifndef OPENSSL_NO_SHA512 EVP_add_digest(EVP_sha384()); EVP_add_digest(EVP_sha512()); #endif #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA) EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2); EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1"); EVP_add_digest_alias(SN_dsaWithSHA1,"dss1"); #endif #ifndef OPENSSL_NO_ECDSA EVP_add_digest(EVP_ecdsa()); #endif /* If you want support for phased out ciphers, add the following */ #if 0 EVP_add_digest(EVP_sha()); EVP_add_digest(EVP_dss()); #endif #ifndef OPENSSL_NO_COMP /* This will initialise the built-in compression algorithms. The value returned is a STACK_OF(SSL_COMP), but that can be discarded safely */ (void)SSL_COMP_get_compression_methods(); #endif /* initialize cipher/digest methods table */ ssl_load_ciphers(); return(1); }
/* DTLS-SRTP initialization */ gint janus_dtls_srtp_init(gchar *server_pem, gchar *server_key) { ssl_ctx = SSL_CTX_new(DTLSv1_method()); if(!ssl_ctx) { JANUS_LOG(LOG_FATAL, "Ops, error creating DTLS context?\n"); return -1; } SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, janus_dtls_verify_callback); SSL_CTX_set_tlsext_use_srtp(ssl_ctx, "SRTP_AES128_CM_SHA1_80"); /* FIXME Should we support something else as well? */ if(!server_pem || !SSL_CTX_use_certificate_file(ssl_ctx, server_pem, SSL_FILETYPE_PEM)) { JANUS_LOG(LOG_FATAL, "Certificate error, does it exist?\n"); JANUS_LOG(LOG_FATAL, " %s\n", server_pem); return -2; } if(!server_key || !SSL_CTX_use_PrivateKey_file(ssl_ctx, server_key, SSL_FILETYPE_PEM)) { JANUS_LOG(LOG_FATAL, "Certificate key error, does it exist?\n"); JANUS_LOG(LOG_FATAL, " %s\n", server_key); return -3; } if(!SSL_CTX_check_private_key(ssl_ctx)) { JANUS_LOG(LOG_FATAL, "Certificate check error...\n"); return -4; } BIO *certbio = BIO_new(BIO_s_file()); if(certbio == NULL) { JANUS_LOG(LOG_FATAL, "Certificate BIO error...\n"); return -5; } if(BIO_read_filename(certbio, server_pem) == 0) { JANUS_LOG(LOG_FATAL, "Error reading certificate...\n"); BIO_free_all(certbio); return -6; } X509 *cert = PEM_read_bio_X509(certbio, NULL, 0, NULL); if(cert == NULL) { JANUS_LOG(LOG_FATAL, "Error reading certificate...\n"); BIO_free_all(certbio); return -7; } unsigned int size; unsigned char fingerprint[EVP_MAX_MD_SIZE]; if(X509_digest(cert, EVP_sha256(), (unsigned char *)fingerprint, &size) == 0) { JANUS_LOG(LOG_FATAL, "Error converting X509 structure...\n"); X509_free(cert); BIO_free_all(certbio); return -7; } char *lfp = (char *)&local_fingerprint; int i = 0; for(i = 0; i < size; i++) { sprintf(lfp, "%.2X:", fingerprint[i]); lfp += 3; } *(lfp-1) = 0; JANUS_LOG(LOG_INFO, "Fingerprint of our certificate: %s\n", local_fingerprint); X509_free(cert); BIO_free_all(certbio); SSL_CTX_set_cipher_list(ssl_ctx, DTLS_CIPHERS); /* Initialize libsrtp */ if(srtp_init() != err_status_ok) { JANUS_LOG(LOG_FATAL, "Ops, error setting up libsrtp?\n"); return 5; } return 0; }
int main(int argc, char *argv[]) { # ifndef OPENSSL_NO_MD5 int i; char *p; # endif int err = 0; HMAC_CTX ctx, ctx2; unsigned char buf[EVP_MAX_MD_SIZE]; unsigned int len; # ifdef OPENSSL_NO_MD5 printf("test skipped: MD5 disabled\n"); # else # ifdef CHARSET_EBCDIC ebcdic2ascii(test[0].data, test[0].data, test[0].data_len); ebcdic2ascii(test[1].data, test[1].data, test[1].data_len); ebcdic2ascii(test[2].key, test[2].key, test[2].key_len); ebcdic2ascii(test[2].data, test[2].data, test[2].data_len); # endif for (i = 0; i < 4; i++) { p = pt(HMAC(EVP_md5(), test[i].key, test[i].key_len, test[i].data, test[i].data_len, NULL, NULL), MD5_DIGEST_LENGTH); if (strcmp(p, (const char *)test[i].digest) != 0) { printf("Error calculating HMAC on %d entry'\n", i); printf("got %s instead of %s\n", p, test[i].digest); err++; } else printf("test %d ok\n", i); } # endif /* OPENSSL_NO_MD5 */ /* test4 */ HMAC_CTX_init(&ctx); if (HMAC_Init_ex(&ctx, NULL, 0, NULL, NULL)) { printf("Should fail to initialise HMAC with empty MD and key (test 4)\n"); err++; goto test5; } if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) { printf("Should fail HMAC_Update with ctx not set up (test 4)\n"); err++; goto test5; } if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha1(), NULL)) { printf("Should fail to initialise HMAC with empty key (test 4)\n"); err++; goto test5; } if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) { printf("Should fail HMAC_Update with ctx not set up (test 4)\n"); err++; goto test5; } printf("test 4 ok\n"); test5: HMAC_CTX_cleanup(&ctx); HMAC_CTX_init(&ctx); if (HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, NULL, NULL)) { printf("Should fail to initialise HMAC with empty MD (test 5)\n"); err++; goto test6; } if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) { printf("Should fail HMAC_Update with ctx not set up (test 5)\n"); err++; goto test6; } if (HMAC_Init_ex(&ctx, test[4].key, -1, EVP_sha1(), NULL)) { printf("Should fail to initialise HMAC with invalid key len(test 5)\n"); err++; goto test6; } if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) { printf("Failed to initialise HMAC (test 5)\n"); err++; goto test6; } if (!HMAC_Update(&ctx, test[4].data, test[4].data_len)) { printf("Error updating HMAC with data (test 5)\n"); err++; goto test6; } if (!HMAC_Final(&ctx, buf, &len)) { printf("Error finalising data (test 5)\n"); err++; goto test6; } p = pt(buf, len); if (strcmp(p, (const char *)test[4].digest) != 0) { printf("Error calculating interim HMAC on test 5\n"); printf("got %s instead of %s\n", p, test[4].digest); err++; goto test6; } if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha256(), NULL)) { printf("Should disallow changing MD without a new key (test 5)\n"); err++; goto test6; } if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) { printf("Failed to reinitialise HMAC (test 5)\n"); err++; goto test6; } if (!HMAC_Update(&ctx, test[5].data, test[5].data_len)) { printf("Error updating HMAC with data (sha256) (test 5)\n"); err++; goto test6; } if (!HMAC_Final(&ctx, buf, &len)) { printf("Error finalising data (sha256) (test 5)\n"); err++; goto test6; } p = pt(buf, len); if (strcmp(p, (const char *)test[5].digest) != 0) { printf("Error calculating 2nd interim HMAC on test 5\n"); printf("got %s instead of %s\n", p, test[5].digest); err++; goto test6; } if (!HMAC_Init_ex(&ctx, test[6].key, test[6].key_len, NULL, NULL)) { printf("Failed to reinitialise HMAC with key (test 5)\n"); err++; goto test6; } if (!HMAC_Update(&ctx, test[6].data, test[6].data_len)) { printf("Error updating HMAC with data (new key) (test 5)\n"); err++; goto test6; } if (!HMAC_Final(&ctx, buf, &len)) { printf("Error finalising data (new key) (test 5)\n"); err++; goto test6; } p = pt(buf, len); if (strcmp(p, (const char *)test[6].digest) != 0) { printf("error calculating HMAC on test 5\n"); printf("got %s instead of %s\n", p, test[6].digest); err++; } else { printf("test 5 ok\n"); } test6: HMAC_CTX_cleanup(&ctx); HMAC_CTX_init(&ctx); if (!HMAC_Init_ex(&ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) { printf("Failed to initialise HMAC (test 6)\n"); err++; goto end; } if (!HMAC_Update(&ctx, test[7].data, test[7].data_len)) { printf("Error updating HMAC with data (test 6)\n"); err++; goto end; } if (!HMAC_CTX_copy(&ctx2, &ctx)) { printf("Failed to copy HMAC_CTX (test 6)\n"); err++; goto end; } if (!HMAC_Final(&ctx2, buf, &len)) { printf("Error finalising data (test 6)\n"); err++; goto end; } p = pt(buf, len); if (strcmp(p, (const char *)test[7].digest) != 0) { printf("Error calculating HMAC on test 6\n"); printf("got %s instead of %s\n", p, test[7].digest); err++; } else { printf("test 6 ok\n"); } end: HMAC_CTX_cleanup(&ctx); EXIT(err); return (0); }
static int knot_tsig_compute_digest(const uint8_t *wire, size_t wire_len, uint8_t *digest, size_t *digest_len, const knot_tsig_key_t *key) { if (!wire || !digest || !digest_len || !key) { dbg_tsig("TSIG: digest: bad args.\n"); return KNOT_EINVAL; } if (!key->name) { dbg_tsig("TSIG: digest: no algorithm\n"); return KNOT_EMALF; } knot_tsig_algorithm_t tsig_alg = key->algorithm; if (tsig_alg == 0) { dbg_tsig("TSIG: digest: unknown algorithm\n"); return KNOT_TSIG_EBADSIG; } dbg_tsig_detail("TSIG: key size: %zu\n", key->secret.size); dbg_tsig_detail("TSIG: key:\n"); dbg_tsig_hex_detail((char *)key->secret.data, key->secret.size); dbg_tsig_detail("Wire for signing is %zu bytes long.\n", wire_len); /* Compute digest. */ HMAC_CTX ctx; switch (tsig_alg) { case KNOT_TSIG_ALG_HMAC_MD5: HMAC_Init(&ctx, key->secret.data, key->secret.size, EVP_md5()); break; case KNOT_TSIG_ALG_HMAC_SHA1: HMAC_Init(&ctx, key->secret.data, key->secret.size, EVP_sha1()); break; case KNOT_TSIG_ALG_HMAC_SHA224: HMAC_Init(&ctx, key->secret.data, key->secret.size, EVP_sha224()); break; case KNOT_TSIG_ALG_HMAC_SHA256: HMAC_Init(&ctx, key->secret.data, key->secret.size, EVP_sha256()); break; case KNOT_TSIG_ALG_HMAC_SHA384: HMAC_Init(&ctx, key->secret.data, key->secret.size, EVP_sha384()); break; case KNOT_TSIG_ALG_HMAC_SHA512: HMAC_Init(&ctx, key->secret.data, key->secret.size, EVP_sha512()); break; default: return KNOT_ENOTSUP; } /* switch */ unsigned tmp_dig_len = *digest_len; HMAC_Update(&ctx, (const unsigned char *)wire, wire_len); HMAC_Final(&ctx, digest, &tmp_dig_len); *digest_len = tmp_dig_len; HMAC_CTX_cleanup(&ctx); return KNOT_EOK; }
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); }
static int pbkdf2_check( const struct berval *scheme, const struct berval *passwd, const struct berval *cred, const char **text) { int rc; int iteration; /* salt_value require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */ unsigned char salt_value[PBKDF2_SALT_SIZE + 1]; char salt_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_SALT_SIZE) + 1]; /* dk_value require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */ unsigned char dk_value[PBKDF2_MAX_DK_SIZE + 1]; char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_MAX_DK_SIZE) + 1]; unsigned char input_dk_value[PBKDF2_MAX_DK_SIZE]; size_t dk_len; #ifdef HAVE_OPENSSL const EVP_MD *md; #elif HAVE_GNUTLS struct hmac_sha1_ctx sha1_ctx; struct hmac_sha256_ctx sha256_ctx; struct hmac_sha512_ctx sha512_ctx; void * current_ctx = NULL; pbkdf2_hmac_update current_hmac_update = NULL; pbkdf2_hmac_digest current_hmac_digest = NULL; #endif #ifdef SLAPD_PBKDF2_DEBUG printf("Checking for %s\n", scheme->bv_val); printf(" Stored Value:\t%s\n", passwd->bv_val); printf(" Input Cred:\t%s\n", cred->bv_val); #endif #ifdef HAVE_OPENSSL if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ dk_len = PBKDF2_SHA256_DK_SIZE; md = EVP_sha256(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ dk_len = PBKDF2_SHA512_DK_SIZE; md = EVP_sha512(); }else{ return LUTIL_PASSWD_ERR; } #elif HAVE_GNUTLS if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; current_ctx = &sha1_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; hmac_sha1_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; current_ctx = &sha1_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; hmac_sha1_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ dk_len = PBKDF2_SHA256_DK_SIZE; current_ctx = &sha256_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha256_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha256_digest; hmac_sha256_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ dk_len = PBKDF2_SHA512_DK_SIZE; current_ctx = &sha512_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha512_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha512_digest; hmac_sha512_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else{ return LUTIL_PASSWD_ERR; } #endif iteration = atoi(passwd->bv_val); if(iteration < 1){ return LUTIL_PASSWD_ERR; } char *ptr; ptr = strchr(passwd->bv_val, '$'); if(!ptr){ return LUTIL_PASSWD_ERR; } ptr++; /* skip '$' */ rc = ab64_to_b64(ptr, salt_b64, sizeof(salt_b64)); if(rc < 0){ return LUTIL_PASSWD_ERR; } ptr = strchr(ptr, '$'); if(!ptr){ return LUTIL_PASSWD_ERR; } ptr++; /* skip '$' */ rc = ab64_to_b64(ptr, dk_b64, sizeof(dk_b64)); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* The targetsize require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */ rc = lutil_b64_pton(salt_b64, salt_value, PBKDF2_SALT_SIZE + 1); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* consistency check */ if(rc != PBKDF2_SALT_SIZE){ return LUTIL_PASSWD_ERR; } /* The targetsize require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */ rc = lutil_b64_pton(dk_b64, dk_value, sizeof(dk_value)); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* consistency check */ if(rc != dk_len){ return LUTIL_PASSWD_ERR; } #ifdef HAVE_OPENSSL if(!PKCS5_PBKDF2_HMAC(cred->bv_val, cred->bv_len, salt_value, PBKDF2_SALT_SIZE, iteration, md, dk_len, input_dk_value)){ return LUTIL_PASSWD_ERR; } #elif HAVE_GNUTLS PBKDF2(current_ctx, current_hmac_update, current_hmac_digest, dk_len, iteration, PBKDF2_SALT_SIZE, salt_value, dk_len, input_dk_value); #endif rc = memcmp(dk_value, input_dk_value, dk_len); #ifdef SLAPD_PBKDF2_DEBUG printf(" Iteration:\t%d\n", iteration); printf(" Base64 Salt:\t%s\n", salt_b64); printf(" Base64 DK:\t%s\n", dk_b64); int i; printf(" Stored Salt:\t"); for(i=0; i<PBKDF2_SALT_SIZE; i++){ printf("%02x", salt_value[i]); } printf("\n"); printf(" Stored DK:\t"); for(i=0; i<dk_len; i++){ printf("%02x", dk_value[i]); } printf("\n"); printf(" Input DK:\t"); for(i=0; i<dk_len; i++){ printf("%02x", input_dk_value[i]); } printf("\n"); printf(" Result:\t%d\n", rc); #endif return rc?LUTIL_PASSWD_ERR:LUTIL_PASSWD_OK; }
int main(int argc, char *argv[]) { /* //test char testki[32]; print(testki,32); menuOp(testki); print(testki,32); menuOp(testki); print(testki,32); */ //select mode from argv, and decide the port and ip and if client or server int port, PORT; char c, *p, *ip; int MODE = 0, TUNMODE = IFF_TUN, DEBUG = 0; while ((c = getopt(argc, argv, "s:c:ehd")) != -1) { switch (c) { case 'h': usage(); case 'd': DEBUG++; break; case 's': MODE = 1; PORT = atoi(optarg); break; case 'c': MODE = 2; p = memchr(optarg,':',16); if (!p) ERROR("invalid argument : [%s]\n",optarg); *p = 0; ip = optarg; port = atoi(p+1); PORT = 0; break; case 'e': TUNMODE = IFF_TAP; break; default: usage(); } } if (MODE == 0) usage(); ///////////////////////////tunnel communicate part begin//////////////////////////////////// struct sockaddr_in sin, sout, from; struct ifreq ifr; int fd, s, fromlen, soutlen, l, outl; /* Allow enough space in output buffer for additional block */ unsigned char buf[BUFFER_LENGTH + OUTPUT_LENGTH], encryptedbuf[BUFFER_LENGTH + OUTPUT_LENGTH + EVP_MAX_BLOCK_LENGTH]; unsigned char digest[OUTPUT_LENGTH]; fd_set fdset; if ( (fd = open("/dev/net/tun",O_RDWR)) < 0) PERROR("open"); memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = TUNMODE; strncpy(ifr.ifr_name, "toto%d", IFNAMSIZ); if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) PERROR("ioctl"); printf("Allocated interface %s. Configure and use it\n", ifr.ifr_name); s = socket(PF_INET, SOCK_DGRAM, 0); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(PORT); if ( bind(s,(struct sockaddr *)&sin, sizeof(sin)) < 0) PERROR("bind"); fromlen = sizeof(from); if (MODE == 1) { while(1) { l = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen); if (l < 0) PERROR("recvfrom"); if (strncmp(MAGIC_WORD, buf, sizeof(MAGIC_WORD)) == 0) break; // printf("Bad magic word from %s:%i\n", // inet_ntoa(from.sin_addr.s_addr), ntohs(from.sin_port)); } l = sendto(s, MAGIC_WORD, sizeof(MAGIC_WORD), 0, (struct sockaddr *)&from, fromlen); if (l < 0) PERROR("sendto"); } else { from.sin_family = AF_INET; from.sin_port = htons(port); inet_aton(ip, &from.sin_addr); l =sendto(s, MAGIC_WORD, sizeof(MAGIC_WORD), 0, (struct sockaddr *)&from, sizeof(from)); if (l < 0) PERROR("sendto"); l = recvfrom(s,buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen); if (l < 0) PERROR("recvfrom"); if (strncmp(MAGIC_WORD, buf, sizeof(MAGIC_WORD) != 0)) ERROR("Bad magic word for peer\n"); } ///////////////////////////tunnel create part end//////////////////////////////////// char newkeyiv[32]; char keyiv[32];// = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}; //pipe and fork prepare int pipefd[2]; pid_t cpid; if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } cpid = fork(); if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); } //pki part if (cpid > 0) { // Parent writes argv[1] to pipe close(pipefd[0]); // Close unused read end //pki if(MODE == 1) {doPKIServer(cpid,pipefd,newkeyiv,port, PORT, ip);} else if(MODE == 2) {doPKIClient(cpid,pipefd,newkeyiv,port, PORT, ip);} //exit wait(NULL); // Wait for child kill(cpid,SIGKILL); } //tunnel part else { // Child reads from pipe close(pipefd[1]); // Close unused write end fcntl(pipefd[0],F_SETFL,O_NONBLOCK);//set unblock pipe read ///////////////////////////tunnel communicate part begin//////////////////////////////////// int num; int i; char key[16]; while (1) { num=read(pipefd[0], keyiv, 32);//read key and iv from pki process if(num==32){//if read new key and iv, print it printf("new key and iv:\n"); print(keyiv,32); } FD_ZERO(&fdset); FD_SET(fd, &fdset); FD_SET(s, &fdset); if (select(fd+s+1, &fdset,NULL,NULL,NULL) < 0) PERROR("select"); if (FD_ISSET(fd, &fdset)) { if (DEBUG) write(1,">", 1); l = read(fd, buf, BUFFER_LENGTH); if (l < 0) PERROR("read"); // encrypt here do_crypt(keyiv, buf, l, encryptedbuf, &outl, 1); // hmac for(i=0;i<16;i++) { key[i] = keyiv[i]; } strncpy(digest, HMAC(EVP_sha256(), key, 16, (unsigned char *)encryptedbuf, outl, NULL, NULL), OUTPUT_LENGTH); // add on hmac strncpy(encryptedbuf + outl, digest, OUTPUT_LENGTH); outl += OUTPUT_LENGTH; if (sendto(s, encryptedbuf, outl, 0, (struct sockaddr *)&from, fromlen) < 0) PERROR("sendto"); } else { if (DEBUG) write(1,"<", 1); l = recvfrom(s, encryptedbuf, sizeof(encryptedbuf), 0, (struct sockaddr *)&sout, &soutlen); // get hmac l -= OUTPUT_LENGTH; strncpy(digest, encryptedbuf + l, OUTPUT_LENGTH); for(i=0;i<16;i++) { key[i] = keyiv[i]; } if (strncmp(digest, HMAC(EVP_sha256(), key, 16, (unsigned char *)encryptedbuf, l, NULL, NULL), OUTPUT_LENGTH)) { continue; } // decrypt here do_crypt(keyiv, encryptedbuf, l, buf, &outl, 0); if (write(fd, buf, outl) < 0) PERROR("write"); } } ///////////////////////////tunnel communicate part end//////////////////////////////////// //exit _exit(EXIT_SUCCESS); } }
/** * Setup key and digest for verification. Adjust sig if necessary. * * @param algo: key algorithm * @param evp_key: EVP PKEY public key to create. * @param digest_type: digest type to use * @param key: key to setup for. * @param keylen: length of key. * @return false on failure. */ static int setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, unsigned char* key, size_t keylen) { DSA* dsa; RSA* rsa; switch(algo) { case LDNS_DSA: case LDNS_DSA_NSEC3: *evp_key = EVP_PKEY_new(); if(!*evp_key) { log_err("verify: malloc failure in crypto"); return 0; } dsa = ldns_key_buf2dsa_raw(key, keylen); if(!dsa) { verbose(VERB_QUERY, "verify: " "ldns_key_buf2dsa_raw failed"); return 0; } if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) { verbose(VERB_QUERY, "verify: " "EVP_PKEY_assign_DSA failed"); return 0; } *digest_type = EVP_dss1(); break; case LDNS_RSASHA1: case LDNS_RSASHA1_NSEC3: #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) case LDNS_RSASHA256: #endif #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) case LDNS_RSASHA512: #endif *evp_key = EVP_PKEY_new(); if(!*evp_key) { log_err("verify: malloc failure in crypto"); return 0; } rsa = ldns_key_buf2rsa_raw(key, keylen); if(!rsa) { verbose(VERB_QUERY, "verify: " "ldns_key_buf2rsa_raw SHA failed"); return 0; } if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { verbose(VERB_QUERY, "verify: " "EVP_PKEY_assign_RSA SHA failed"); return 0; } /* select SHA version */ #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) if(algo == LDNS_RSASHA256) *digest_type = EVP_sha256(); else #endif #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) if(algo == LDNS_RSASHA512) *digest_type = EVP_sha512(); else #endif *digest_type = EVP_sha1(); break; case LDNS_RSAMD5: *evp_key = EVP_PKEY_new(); if(!*evp_key) { log_err("verify: malloc failure in crypto"); return 0; } rsa = ldns_key_buf2rsa_raw(key, keylen); if(!rsa) { verbose(VERB_QUERY, "verify: " "ldns_key_buf2rsa_raw MD5 failed"); return 0; } if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { verbose(VERB_QUERY, "verify: " "EVP_PKEY_assign_RSA MD5 failed"); return 0; } *digest_type = EVP_md5(); break; #ifdef USE_GOST case LDNS_ECC_GOST: *evp_key = ldns_gost2pkey_raw(key, keylen); if(!*evp_key) { verbose(VERB_QUERY, "verify: " "ldns_gost2pkey_raw failed"); return 0; } *digest_type = EVP_get_digestbyname("md_gost94"); if(!*digest_type) { verbose(VERB_QUERY, "verify: " "EVP_getdigest md_gost94 failed"); return 0; } break; #endif #ifdef USE_ECDSA case LDNS_ECDSAP256SHA256: *evp_key = ldns_ecdsa2pkey_raw(key, keylen, LDNS_ECDSAP256SHA256); if(!*evp_key) { verbose(VERB_QUERY, "verify: " "ldns_ecdsa2pkey_raw failed"); return 0; } #ifdef USE_ECDSA_EVP_WORKAROUND /* openssl before 1.0.0 fixes RSA with the SHA256 * hash in EVP. We create one for ecdsa_sha256 */ { static int md_ecdsa_256_done = 0; static EVP_MD md; if(!md_ecdsa_256_done) { EVP_MD m = *EVP_sha256(); md_ecdsa_256_done = 1; m.required_pkey_type[0] = (*evp_key)->type; m.verify = (void*)ECDSA_verify; md = m; } *digest_type = &md; } #else *digest_type = EVP_sha256(); #endif break; case LDNS_ECDSAP384SHA384: *evp_key = ldns_ecdsa2pkey_raw(key, keylen, LDNS_ECDSAP384SHA384); if(!*evp_key) { verbose(VERB_QUERY, "verify: " "ldns_ecdsa2pkey_raw failed"); return 0; } #ifdef USE_ECDSA_EVP_WORKAROUND /* openssl before 1.0.0 fixes RSA with the SHA384 * hash in EVP. We create one for ecdsa_sha384 */ { static int md_ecdsa_384_done = 0; static EVP_MD md; if(!md_ecdsa_384_done) { EVP_MD m = *EVP_sha384(); md_ecdsa_384_done = 1; m.required_pkey_type[0] = (*evp_key)->type; m.verify = (void*)ECDSA_verify; md = m; } *digest_type = &md; } #else *digest_type = EVP_sha384(); #endif break; #endif /* USE_ECDSA */ default: verbose(VERB_QUERY, "verify: unknown algorithm %d", algo); return 0; } return 1; }
CK_RV PKCS11_Digest_OpenSSL::DigestInit(Cryptoki_Session_Context* pSessionCtx, CK_MECHANISM_PTR pMechanism) { OPENSSL_HEADER(); OpenSSLDigestData* pDigData; const EVP_MD* pDigest; CK_OBJECT_HANDLE hKey = CK_OBJECT_HANDLE_INVALID; bool isHMAC = false; if(pSessionCtx == NULL) return CKR_SESSION_CLOSED; if(pSessionCtx->DigestCtx != NULL) return CKR_SESSION_PARALLEL_NOT_SUPPORTED; // another digest is in progress pDigData = (OpenSSLDigestData*)TINYCLR_SSL_MALLOC(sizeof(*pDigData)); if(pDigData == NULL) return CKR_DEVICE_MEMORY; TINYCLR_SSL_MEMSET(pDigData, 0, sizeof(*pDigData)); EVP_MD_CTX_init(&pDigData->CurrentCtx); switch(pMechanism->mechanism) { case CKM_SHA_1: pDigest = EVP_sha1(); break; case CKM_SHA224: pDigest = EVP_sha224(); break; case CKM_SHA256: pDigest = EVP_sha256(); break; case CKM_SHA384: pDigest = EVP_sha384(); break; case CKM_SHA512: pDigest = EVP_sha512(); break; case CKM_MD5: pDigest = EVP_md5(); break; case CKM_RIPEMD160: pDigest = EVP_ripemd160(); break; case CKM_MD5_HMAC: pDigest = EVP_md5(); isHMAC = true; break; case CKM_SHA_1_HMAC: pDigest = EVP_sha1(); isHMAC = true; break; case CKM_SHA256_HMAC: pDigest = EVP_sha256(); isHMAC = true; break; case CKM_SHA384_HMAC: pDigest = EVP_sha384(); isHMAC = true; break; case CKM_SHA512_HMAC: pDigest = EVP_sha512(); isHMAC = true; break; case CKM_RIPEMD160_HMAC: pDigest = EVP_ripemd160(); isHMAC = true; break; default: OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_INVALID); } if(isHMAC) { if(pMechanism->pParameter != NULL && pMechanism->ulParameterLen == sizeof(CK_OBJECT_HANDLE)) { hKey = SwapEndianIfBEc32(*(CK_OBJECT_HANDLE*)pMechanism->pParameter); } else { OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_PARAM_INVALID); } pDigData->HmacKey = PKCS11_Keys_OpenSSL::GetKeyFromHandle(pSessionCtx, hKey, TRUE); if(pDigData->HmacKey==NULL) OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_PARAM_INVALID); pDigData->HmacCtx.md = pDigest; OPENSSL_CHECKRESULT(HMAC_Init(&pDigData->HmacCtx, pDigData->HmacKey->key, pDigData->HmacKey->size/8, pDigData->HmacCtx.md)); } else { OPENSSL_CHECKRESULT(EVP_DigestInit_ex(&pDigData->CurrentCtx, pDigest, NULL)); } pSessionCtx->DigestCtx = pDigData; OPENSSL_CLEANUP(); if(retVal != CKR_OK && pDigData != NULL) { TINYCLR_SSL_FREE(pDigData); } OPENSSL_RETURN(); }
int EVP_PBE_scrypt(const char *pass, size_t passlen, const unsigned char *salt, size_t saltlen, uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, unsigned char *key, size_t keylen) { int rv = 0; unsigned char *B; uint32_t *X, *V, *T; uint64_t i, Blen, Vlen; size_t allocsize; /* Sanity check parameters */ /* initial check, r,p must be non zero, N >= 2 and a power of 2 */ if (r == 0 || p == 0 || N < 2 || (N & (N - 1))) return 0; /* Check p * r < SCRYPT_PR_MAX avoiding overflow */ if (p > SCRYPT_PR_MAX / r) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } /* * Need to check N: if 2^(128 * r / 8) overflows limit this is * automatically satisfied since N <= UINT64_MAX. */ if (16 * r <= LOG2_UINT64_MAX) { if (N >= (((uint64_t)1) << (16 * r))) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } } /* Memory checks: check total allocated buffer size fits in uint64_t */ /* * B size in section 5 step 1.S * Note: we know p * 128 * r < UINT64_MAX because we already checked * p * r < SCRYPT_PR_MAX */ Blen = p * 128 * r; /* * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in * uint64_t and also size_t (their sizes are unrelated). * This is combined size V, X and T (section 4) */ i = UINT64_MAX / (32 * sizeof(uint32_t)); if (N + 2 > i / r) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } Vlen = 32 * r * (N + 2) * sizeof(uint32_t); /* check total allocated size fits in uint64_t */ if (Blen > UINT64_MAX - Vlen) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } /* check total allocated size fits in size_t */ if (Blen > SIZE_MAX - Vlen) return 0; allocsize = (size_t)(Blen + Vlen); if (maxmem == 0) maxmem = SCRYPT_MAX_MEM; if (allocsize > maxmem) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); return 0; } /* If no key return to indicate parameters are OK */ if (key == NULL) return 1; B = OPENSSL_malloc(allocsize); if (B == NULL) { EVPerr(EVP_F_EVP_PBE_SCRYPT, ERR_R_MALLOC_FAILURE); return 0; } X = (uint32_t *)(B + Blen); T = X + 32 * r; V = T + 32 * r; if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(), Blen, B) == 0) goto err; for (i = 0; i < p; i++) scryptROMix(B + 128 * r * i, r, N, X, T, V); if (PKCS5_PBKDF2_HMAC(pass, passlen, B, Blen, 1, EVP_sha256(), keylen, key) == 0) goto err; rv = 1; err: if (rv == 0) EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PBKDF2_ERROR); OPENSSL_clear_free(B, allocsize); return rv; }
cjose_jwk_t *cjose_jwk_derive_ecdh_ephemeral_key( cjose_jwk_t *jwk_self, cjose_jwk_t *jwk_peer, cjose_err *err) { EVP_PKEY_CTX *ctx = NULL; EVP_PKEY *pkey_self = NULL; EVP_PKEY *pkey_peer = NULL; uint8_t *secret = NULL; size_t secret_len = 0; uint8_t *ephemeral_key = NULL; size_t ephemeral_key_len = 0; cjose_jwk_t *jwk_ephemeral_key = NULL; // get EVP_KEY from jwk_self if (!_cjose_jwk_evp_key_from_ec_key(jwk_self, &pkey_self, err)) { goto _cjose_jwk_derive_shared_secret_fail; } // get EVP_KEY from jwk_peer if (!_cjose_jwk_evp_key_from_ec_key(jwk_peer, &pkey_peer, err)) { goto _cjose_jwk_derive_shared_secret_fail; } // create derivation context based on local key pair ctx = EVP_PKEY_CTX_new(pkey_self, NULL); if (NULL == ctx) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwk_derive_shared_secret_fail; } // initialize derivation context if (1 != EVP_PKEY_derive_init(ctx)) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwk_derive_shared_secret_fail; } // provide the peer public key if (1 != EVP_PKEY_derive_set_peer(ctx, pkey_peer)) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwk_derive_shared_secret_fail; } // determine buffer length for shared secret if(1 != EVP_PKEY_derive(ctx, NULL, &secret_len)) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwk_derive_shared_secret_fail; } // allocate buffer for shared secret secret = (uint8_t *)cjose_get_alloc()(secret_len); if (NULL == secret) { CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY); goto _cjose_jwk_derive_shared_secret_fail; } memset(secret, 0, secret_len); // derive the shared secret if (1 != (EVP_PKEY_derive(ctx, secret, &secret_len))) { CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY); goto _cjose_jwk_derive_shared_secret_fail; } // HKDF of the DH shared secret (SHA256, no salt, no info, 256 bit expand) ephemeral_key_len = 32; ephemeral_key = (uint8_t *)cjose_get_alloc()(ephemeral_key_len); if (!cjose_jwk_hkdf(EVP_sha256(), (uint8_t *)"", 0, (uint8_t *)"", 0, secret, secret_len, ephemeral_key, ephemeral_key_len, err)) { goto _cjose_jwk_derive_shared_secret_fail; } // create a JWK of the shared secret jwk_ephemeral_key = cjose_jwk_create_oct_spec( ephemeral_key, ephemeral_key_len, err); if (NULL == jwk_ephemeral_key) { goto _cjose_jwk_derive_shared_secret_fail; } // happy path EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey_self); EVP_PKEY_free(pkey_peer); cjose_get_dealloc()(secret); cjose_get_dealloc()(ephemeral_key); return jwk_ephemeral_key; // fail path _cjose_jwk_derive_shared_secret_fail: if (NULL != ctx) { EVP_PKEY_CTX_free(ctx); } if (NULL != pkey_self) { EVP_PKEY_free(pkey_self); } if (NULL != pkey_peer) { EVP_PKEY_free(pkey_peer); } if (NULL != jwk_ephemeral_key) { cjose_jwk_release(jwk_ephemeral_key); } cjose_get_dealloc()(secret); cjose_get_dealloc()(ephemeral_key); return NULL; }
bool find_server(EVP_PKEY *pk, sockaddr6 *addr, uint32_t usecs, uint32_t retries) { bool ok = false; interface ifs[16]; ssize_t count = active_interfaces(ifs, 16); if (count <= 0) return false; addr->sin6_family = AF_INET6; addr->sin6_port = htons(atoi(MCAST_PORT)); addr->sin6_scope_id = ifs[0].index; inet_pton(AF_INET6, MCAST_HOST, &addr->sin6_addr); int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (fd == -1) return false; struct ipv6_mreq req = { .ipv6mr_interface = ifs[0].index }; memcpy(&req.ipv6mr_multiaddr, &addr->sin6_addr, sizeof(struct in6_addr)); if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &req, sizeof(req))) { return false; } struct timeval timeout = { .tv_usec = usecs / retries }; setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); sockaddr6 from6; socklen_t from_len = sizeof(from6); sockaddr *from = (sockaddr *) &from6; uint8_t ping[PING_LEN]; struct pong pong; ssize_t len; RAND_bytes(ping, PING_LEN); for (uint32_t i = 0; !ok && i < retries; i++) { EVP_MD_CTX ctx; sendto(fd, ping, PING_LEN, 0, (sockaddr *) addr, sizeof(*addr)); if ((len = recvfrom(fd, &pong, sizeof(pong), 0, from, &from_len)) > 0) { EVP_MD_CTX_init(&ctx); EVP_DigestVerifyInit(&ctx, NULL, EVP_sha256(), NULL, pk); EVP_DigestVerifyUpdate(&ctx, &ping, PING_LEN); EVP_DigestVerifyUpdate(&ctx, &pong, PONG_LEN); if (EVP_DigestVerifyFinal(&ctx, pong.sig, len) == 1) { memcpy(addr->sin6_addr.s6_addr, &pong.addr, 16); addr->sin6_port = pong.port; ok = true; } EVP_MD_CTX_cleanup(&ctx); } } close(fd); return ok; } int mcast_sock(interface *ifa, sockaddr6 *addr, char *host) { struct ipv6_mreq req = { .ipv6mr_interface = ifa->index }; inet_pton(AF_INET6, host, &req.ipv6mr_multiaddr); int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (fd == -1 || bind(fd, (sockaddr *) addr, sizeof(*addr))) goto error; if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &req, sizeof(req))) goto error; return fd; error: if (fd >= 0) close(fd); return -1; } char *name(sockaddr6 *addr, socklen_t len) { static char host[NI_MAXHOST]; int flags = NI_NUMERICHOST; getnameinfo((struct sockaddr *) addr, len, host, NI_MAXHOST, NULL, 0, flags); return host; }
bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) const { merchant.clear(); if (!IsInitialized()) return false; // One day we'll support more PKI types, but just // x509 for now: const EVP_MD* digestAlgorithm = nullptr; if (paymentRequest.pki_type() == "x509+sha256") { digestAlgorithm = EVP_sha256(); } else if (paymentRequest.pki_type() == "x509+sha1") { digestAlgorithm = EVP_sha1(); } else if (paymentRequest.pki_type() == "none") { qWarning() << "PaymentRequestPlus::getMerchant: Payment request: pki_type == none"; return false; } else { qWarning() << "PaymentRequestPlus::getMerchant: Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type()); return false; } payments::X509Certificates certChain; if (!certChain.ParseFromString(paymentRequest.pki_data())) { qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error parsing pki_data"; return false; } std::vector<X509*> certs; const QDateTime currentTime = QDateTime::currentDateTime(); for (int i = 0; i < certChain.certificate_size(); i++) { QByteArray certData(certChain.certificate(i).data(), certChain.certificate(i).size()); QSslCertificate qCert(certData, QSsl::Der); if (currentTime < qCert.effectiveDate() || currentTime > qCert.expiryDate()) { qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate expired or not yet active: " << qCert; return false; } #if QT_VERSION >= 0x050000 if (qCert.isBlacklisted()) { qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate blacklisted: " << qCert; return false; } #endif const unsigned char *data = (const unsigned char *)certChain.certificate(i).data(); X509 *cert = d2i_X509(nullptr, &data, certChain.certificate(i).size()); if (cert) certs.push_back(cert); } if (certs.empty()) { qWarning() << "PaymentRequestPlus::getMerchant: Payment request: empty certificate chain"; return false; } // The first cert is the signing cert, the rest are untrusted certs that chain // to a valid root authority. OpenSSL needs them separately. STACK_OF(X509) *chain = sk_X509_new_null(); for (int i = certs.size() - 1; i > 0; i--) { sk_X509_push(chain, certs[i]); } X509 *signing_cert = certs[0]; // Now create a "store context", which is a single use object for checking, // load the signing cert into it and verify. X509_STORE_CTX *store_ctx = X509_STORE_CTX_new(); if (!store_ctx) { qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error creating X509_STORE_CTX"; return false; } char *website = nullptr; bool fResult = true; try { if (!X509_STORE_CTX_init(store_ctx, certStore, signing_cert, chain)) { int error = X509_STORE_CTX_get_error(store_ctx); throw SSLVerifyError(X509_verify_cert_error_string(error)); } // Now do the verification! int result = X509_verify_cert(store_ctx); if (result != 1) { int error = X509_STORE_CTX_get_error(store_ctx); // For testing payment requests, we allow self signed root certs! // This option is just shown in the UI options, if -help-debug is enabled. if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && gArgs.GetBoolArg("-allowselfsignedrootcertificates", DEFAULT_SELFSIGNED_ROOTCERTS))) { throw SSLVerifyError(X509_verify_cert_error_string(error)); } else { qDebug() << "PaymentRequestPlus::getMerchant: Allowing self signed root certificate, because -allowselfsignedrootcertificates is true."; } } X509_NAME *certname = X509_get_subject_name(signing_cert); // Valid cert; check signature: payments::PaymentRequest rcopy(paymentRequest); // Copy rcopy.set_signature(std::string("")); std::string data_to_verify; // Everything but the signature rcopy.SerializeToString(&data_to_verify); #if HAVE_DECL_EVP_MD_CTX_NEW EVP_MD_CTX *ctx = EVP_MD_CTX_new(); if (!ctx) throw SSLVerifyError("Error allocating OpenSSL context."); #else EVP_MD_CTX _ctx; EVP_MD_CTX *ctx; ctx = &_ctx; #endif EVP_PKEY *pubkey = X509_get_pubkey(signing_cert); EVP_MD_CTX_init(ctx); if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, nullptr) || !EVP_VerifyUpdate(ctx, data_to_verify.data(), data_to_verify.size()) || !EVP_VerifyFinal(ctx, (const unsigned char*)paymentRequest.signature().data(), (unsigned int)paymentRequest.signature().size(), pubkey)) { throw SSLVerifyError("Bad signature, invalid payment request."); } #if HAVE_DECL_EVP_MD_CTX_NEW EVP_MD_CTX_free(ctx); #endif // OpenSSL API for getting human printable strings from certs is baroque. int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, nullptr, 0); website = new char[textlen + 1]; if (X509_NAME_get_text_by_NID(certname, NID_commonName, website, textlen + 1) == textlen && textlen > 0) { merchant = website; } else { throw SSLVerifyError("Bad certificate, missing common name."); } // TODO: detect EV certificates and set merchant = business name instead of unfriendly NID_commonName ? } catch (const SSLVerifyError& err) { fResult = false; qWarning() << "PaymentRequestPlus::getMerchant: SSL error: " << err.what(); } if (website) delete[] website; X509_STORE_CTX_free(store_ctx); for (unsigned int i = 0; i < certs.size(); i++) X509_free(certs[i]); return fResult; }
void CC_SHA256(const void *data, uint32_t len, unsigned char *md) { CC_EVP(EVP_sha256(), 32, data, len, md); }
static int pbkdf2_encrypt( const struct berval *scheme, const struct berval *passwd, struct berval *msg, const char **text) { unsigned char salt_value[PBKDF2_SALT_SIZE]; struct berval salt; unsigned char dk_value[PBKDF2_MAX_DK_SIZE]; struct berval dk; int iteration = PBKDF2_ITERATION; int rc; #ifdef HAVE_OPENSSL const EVP_MD *md; #elif HAVE_GNUTLS struct hmac_sha1_ctx sha1_ctx; struct hmac_sha256_ctx sha256_ctx; struct hmac_sha512_ctx sha512_ctx; void * current_ctx = NULL; pbkdf2_hmac_update current_hmac_update = NULL; pbkdf2_hmac_digest current_hmac_digest = NULL; #endif salt.bv_val = (char *)salt_value; salt.bv_len = sizeof(salt_value); dk.bv_val = (char *)dk_value; #ifdef HAVE_OPENSSL if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk.bv_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ dk.bv_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ dk.bv_len = PBKDF2_SHA256_DK_SIZE; md = EVP_sha256(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ dk.bv_len = PBKDF2_SHA512_DK_SIZE; md = EVP_sha512(); }else{ return LUTIL_PASSWD_ERR; } #elif HAVE_GNUTLS if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk.bv_len = PBKDF2_SHA1_DK_SIZE; current_ctx = &sha1_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; hmac_sha1_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ dk.bv_len = PBKDF2_SHA1_DK_SIZE; current_ctx = &sha1_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; hmac_sha1_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ dk.bv_len = PBKDF2_SHA256_DK_SIZE; current_ctx = &sha256_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha256_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha256_digest; hmac_sha256_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ dk.bv_len = PBKDF2_SHA512_DK_SIZE; current_ctx = &sha512_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha512_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha512_digest; hmac_sha512_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); }else{ return LUTIL_PASSWD_ERR; } #endif if(lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0){ return LUTIL_PASSWD_ERR; } #ifdef HAVE_OPENSSL if(!PKCS5_PBKDF2_HMAC(passwd->bv_val, passwd->bv_len, (unsigned char *)salt.bv_val, salt.bv_len, iteration, md, dk.bv_len, dk_value)){ return LUTIL_PASSWD_ERR; } #elif HAVE_GNUTLS PBKDF2(current_ctx, current_hmac_update, current_hmac_digest, dk.bv_len, iteration, salt.bv_len, (const uint8_t *) salt.bv_val, dk.bv_len, dk_value); #endif #ifdef SLAPD_PBKDF2_DEBUG printf("Encrypt for %s\n", scheme->bv_val); printf(" Password:\t%s\n", passwd->bv_val); printf(" Salt:\t\t"); int i; for(i=0; i<salt.bv_len; i++){ printf("%02x", salt_value[i]); } printf("\n"); printf(" Iteration:\t%d\n", iteration); printf(" DK:\t\t"); for(i=0; i<dk.bv_len; i++){ printf("%02x", dk_value[i]); } printf("\n"); #endif rc = pbkdf2_format(scheme, iteration, &salt, &dk, msg); #ifdef SLAPD_PBKDF2_DEBUG printf(" Output:\t%s\n", msg->bv_val); #endif return rc; }
enum nssync_error nssync_crypto_decrypt_record(const char *record, struct nssync_crypto_keybundle *keybundle, uint8_t **plaintext_out, size_t *plaintext_length_out) { /* json objects */ json_t *root; json_error_t error; json_t *hmac_hex16_json; json_t *ciphertext_b64_json; json_t *iv_b64_json; /* text from json */ const char *hmac_hex16; const char *ciphertext_b64; const char *iv_b64; /* HMAC from record */ uint8_t *record_hmac; size_t record_hmac_length = HMAC_KEY_LENGTH; /* HMAC computed from key */ unsigned int local_hmac_length = HMAC_KEY_LENGTH; uint8_t local_hmac[HMAC_KEY_LENGTH]; /* decoded ciphertext */ uint8_t *ciphertext; size_t ciphertext_length; uint8_t *iv; size_t iv_length; /* AES state */ AES_KEY aeskey; /* decypted data */ uint8_t *plaintext; /* json load */ root = json_loads(record, 0, &error); if (!root) { debugf("error: on line %d of reply: %s\n", error.line, error.text); return NSSYNC_ERROR_PROTOCOL; } if(!json_is_object(root)) { debugf("error: root is not an object\n"); json_decref(root); return NSSYNC_ERROR_PROTOCOL; } /* extract ciphertext from record (undecoded) */ hmac_hex16_json = json_object_get(root, "hmac"); ciphertext_b64_json = json_object_get(root, "ciphertext"); iv_b64_json = json_object_get(root, "IV"); if ((!json_is_string(hmac_hex16_json)) || (!json_is_string(ciphertext_b64_json)) || (!json_is_string(iv_b64_json))) { debugf("missing or incorrectly formatted fields in record\n"); json_decref(root); return NSSYNC_ERROR_PROTOCOL; } hmac_hex16 = json_string_value(hmac_hex16_json); ciphertext_b64 = json_string_value(ciphertext_b64_json); iv_b64 = json_string_value(iv_b64_json); /* hex16 decode hmac from record */ record_hmac = hex16_decode((uint8_t *)hmac_hex16, strlen(hmac_hex16), &record_hmac_length); if (record_hmac_length != HMAC_KEY_LENGTH) { debugf("record hmac length %zu incorrect (should be %d)\n", record_hmac_length, HMAC_KEY_LENGTH); json_decref(root); return NSSYNC_ERROR_PROTOCOL; } /* calculate local hmac value */ HMAC(EVP_sha256(), keybundle->hmac, HMAC_KEY_LENGTH, (uint8_t *)ciphertext_b64, strlen(ciphertext_b64), local_hmac, &local_hmac_length); /* verify hmac */ if (memcmp(record_hmac, local_hmac, SHA256_DIGEST_LENGTH) != 0) { debugf("record hmac does not match computed. bad key?\n"); free(record_hmac); json_decref(root); return NSSYNC_ERROR_HMAC; } free(record_hmac); /* base64 decode iv from record */ iv = base64_decode((uint8_t *)iv_b64, strlen(iv_b64), &iv_length); if ((iv == NULL) || (iv_length != IV_LENGTH)) { debugf("IV data was size %zu (expected %d)\n", iv_length, IV_LENGTH); json_decref(root); return NSSYNC_ERROR_PROTOCOL; } /* base64 decode ciphertext */ ciphertext = base64_decode((uint8_t *)ciphertext_b64, strlen(ciphertext_b64), &ciphertext_length); if (ciphertext == NULL) { json_decref(root); free(iv); return NSSYNC_ERROR_NOMEM; } /* json unref */ json_decref(root); /* decrypt data */ plaintext = malloc(ciphertext_length + 1); if (plaintext == NULL) { free(ciphertext); free(iv); return NSSYNC_ERROR_NOMEM; } plaintext[ciphertext_length] = 0; AES_set_decrypt_key(keybundle->encryption, 256, &aeskey); AES_cbc_encrypt(ciphertext, plaintext, ciphertext_length, &aeskey, iv, AES_DECRYPT); free(ciphertext); free(iv); *plaintext_out = plaintext; if (plaintext_length_out != NULL) { *plaintext_length_out = ciphertext_length; } return NSSYNC_ERROR_OK; }
int hmac_test(const EVP_MD *md, FILE *out, FILE *in) { char *linebuf, *olinebuf, *p, *q; char *keyword, *value; unsigned char *Key = NULL, *Msg = NULL; int Count, Klen, Tlen; long Keylen, Msglen; int ret = 0; int lnum = 0; olinebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN); linebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN); if (!linebuf || !olinebuf) goto error; Count = -1; Klen = -1; Tlen = -1; while (fgets(olinebuf, HMAC_TEST_MAXLINELEN, in)) { lnum++; strcpy(linebuf, olinebuf); keyword = linebuf; /* Skip leading space */ while (isspace((unsigned char)*keyword)) keyword++; /* Look for = sign */ p = strchr(linebuf, '='); /* If no = or starts with [ (for [L=20] line) just copy */ if (!p) { if (fputs(olinebuf, out) < 0) goto error; continue; } q = p - 1; /* Remove trailing space */ while (isspace((unsigned char)*q)) *q-- = 0; *p = 0; value = p + 1; /* Remove leading space from value */ while (isspace((unsigned char)*value)) value++; /* Remove trailing space from value */ p = value + strlen(value) - 1; while (*p == '\n' || isspace((unsigned char)*p)) *p-- = 0; if (!strcmp(keyword,"[L") && *p==']') { switch (atoi(value)) { case 20: md=EVP_sha1(); break; case 28: md=EVP_sha224(); break; case 32: md=EVP_sha256(); break; case 48: md=EVP_sha384(); break; case 64: md=EVP_sha512(); break; default: goto parse_error; } } else if (!strcmp(keyword, "Count")) { if (Count != -1) goto parse_error; Count = atoi(value); if (Count < 0) goto parse_error; } else if (!strcmp(keyword, "Klen")) { if (Klen != -1) goto parse_error; Klen = atoi(value); if (Klen < 0) goto parse_error; } else if (!strcmp(keyword, "Tlen")) { if (Tlen != -1) goto parse_error; Tlen = atoi(value); if (Tlen < 0) goto parse_error; } else if (!strcmp(keyword, "Msg")) { if (Msg) goto parse_error; Msg = hex2bin_m(value, &Msglen); if (!Msg) goto parse_error; } else if (!strcmp(keyword, "Key")) { if (Key) goto parse_error; Key = hex2bin_m(value, &Keylen); if (!Key) goto parse_error; } else if (!strcmp(keyword, "Mac")) continue; else goto parse_error; fputs(olinebuf, out); if (Key && Msg && (Tlen > 0) && (Klen > 0)) { if (!print_hmac(md, out, Key, Klen, Msg, Msglen, Tlen)) goto error; OPENSSL_free(Key); Key = NULL; OPENSSL_free(Msg); Msg = NULL; Klen = -1; Tlen = -1; Count = -1; } } ret = 1; error: if (olinebuf) OPENSSL_free(olinebuf); if (linebuf) OPENSSL_free(linebuf); if (Key) OPENSSL_free(Key); if (Msg) OPENSSL_free(Msg); return ret; parse_error: fprintf(stderr, "FATAL parse error processing line %d\n", lnum); goto error; }
bool OSSLRSA::signFinal(ByteString& signature) { // Save necessary state before calling super class signFinal OSSLRSAPrivateKey* pk = (OSSLRSAPrivateKey*) currentPrivateKey; AsymMech::Type mechanism = currentMechanism; if (!AsymmetricAlgorithm::signFinal(signature)) { return false; } ByteString firstHash, secondHash; bool bFirstResult = pCurrentHash->hashFinal(firstHash); bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true; delete pCurrentHash; pCurrentHash = NULL; if (pSecondHash != NULL) { delete pSecondHash; pSecondHash = NULL; } if (!bFirstResult || !bSecondResult) { return false; } ByteString digest = firstHash + secondHash; // Resize the data block for the signature to the modulus size of the key signature.resize(pk->getN().size()); // Determine the signature NID type int type = 0; bool isPSS = false; const EVP_MD* hash = NULL; switch (mechanism) { case AsymMech::RSA_MD5_PKCS: type = NID_md5; break; case AsymMech::RSA_SHA1_PKCS: type = NID_sha1; break; case AsymMech::RSA_SHA224_PKCS: type = NID_sha224; break; case AsymMech::RSA_SHA256_PKCS: type = NID_sha256; break; case AsymMech::RSA_SHA384_PKCS: type = NID_sha384; break; case AsymMech::RSA_SHA512_PKCS: type = NID_sha512; break; case AsymMech::RSA_SHA1_PKCS_PSS: isPSS = true; hash = EVP_sha1(); break; case AsymMech::RSA_SHA224_PKCS_PSS: isPSS = true; hash = EVP_sha224(); break; case AsymMech::RSA_SHA256_PKCS_PSS: isPSS = true; hash = EVP_sha256(); break; case AsymMech::RSA_SHA384_PKCS_PSS: isPSS = true; hash = EVP_sha384(); break; case AsymMech::RSA_SHA512_PKCS_PSS: isPSS = true; hash = EVP_sha512(); break; case AsymMech::RSA_SSL: type = NID_md5_sha1; break; default: break; } // Perform the signature operation unsigned int sigLen = signature.size(); RSA* rsa = pk->getOSSLKey(); if (!RSA_blinding_on(rsa, NULL)) { ERROR_MSG("Failed to turn blinding on for OpenSSL RSA key"); return false; } bool rv; if (isPSS) { ByteString em; em.resize(pk->getN().size()); rv = (RSA_padding_add_PKCS1_PSS(pk->getOSSLKey(), &em[0], &digest[0], hash, sLen) == 1); if (!rv) { ERROR_MSG("RSA PSS padding failed (0x%08X)", ERR_get_error()); } else { int result = RSA_private_encrypt(em.size(), &em[0], &signature[0], pk->getOSSLKey(), RSA_NO_PADDING); if (result >= 0) { sigLen = result; rv = true; } else { rv = false; ERROR_MSG("RSA private encrypt failed (0x%08X)", ERR_get_error()); } } } else { rv = (RSA_sign(type, &digest[0], digest.size(), &signature[0], &sigLen, pk->getOSSLKey()) == 1); } RSA_blinding_off(rsa); signature.resize(sigLen); return rv; }
const EVP_MD* CryptoNative_EvpSha256() { return EVP_sha256(); }
/** * @brief Build client-final-message * @returns -1 on error. */ static int rd_kafka_sasl_scram_build_client_final_message ( rd_kafka_transport_t *rktrans, const rd_chariov_t *salt, const char *server_nonce, const rd_chariov_t *server_first_msg, int itcnt, rd_chariov_t *out) { struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state; const rd_kafka_conf_t *conf = &rktrans->rktrans_rkb->rkb_rk->rk_conf; rd_chariov_t SaslPassword = { .ptr = conf->sasl.password, .size = strlen(conf->sasl.password) }; rd_chariov_t SaltedPassword = { .ptr = rd_alloca(EVP_MAX_MD_SIZE) }; rd_chariov_t ClientKey = { .ptr = rd_alloca(EVP_MAX_MD_SIZE) }; rd_chariov_t ServerKey = { .ptr = rd_alloca(EVP_MAX_MD_SIZE) }; rd_chariov_t StoredKey = { .ptr = rd_alloca(EVP_MAX_MD_SIZE) }; rd_chariov_t AuthMessage = RD_ZERO_INIT; rd_chariov_t ClientSignature = { .ptr = rd_alloca(EVP_MAX_MD_SIZE) }; rd_chariov_t ServerSignature = { .ptr = rd_alloca(EVP_MAX_MD_SIZE) }; const rd_chariov_t ClientKeyVerbatim = { .ptr = "Client Key", .size = 10 }; const rd_chariov_t ServerKeyVerbatim = { .ptr = "Server Key", .size = 10 }; rd_chariov_t ClientProof = { .ptr = rd_alloca(EVP_MAX_MD_SIZE) }; rd_chariov_t client_final_msg_wo_proof; char *ClientProofB64; int i; /* Constructing the ClientProof attribute (p): * * p = Base64-encoded ClientProof * SaltedPassword := Hi(Normalize(password), salt, i) * ClientKey := HMAC(SaltedPassword, "Client Key") * StoredKey := H(ClientKey) * AuthMessage := client-first-message-bare + "," + * server-first-message + "," + * client-final-message-without-proof * ClientSignature := HMAC(StoredKey, AuthMessage) * ClientProof := ClientKey XOR ClientSignature * ServerKey := HMAC(SaltedPassword, "Server Key") * ServerSignature := HMAC(ServerKey, AuthMessage) */ /* SaltedPassword := Hi(Normalize(password), salt, i) */ if (rd_kafka_sasl_scram_Hi( rktrans, &SaslPassword, salt, itcnt, &SaltedPassword) == -1) return -1; /* ClientKey := HMAC(SaltedPassword, "Client Key") */ if (rd_kafka_sasl_scram_HMAC( rktrans, &SaltedPassword, &ClientKeyVerbatim, &ClientKey) == -1) return -1; /* StoredKey := H(ClientKey) */ if (rd_kafka_sasl_scram_H(rktrans, &ClientKey, &StoredKey) == -1) return -1; /* client-final-message-without-proof */ rd_kafka_sasl_scram_build_client_final_message_wo_proof( state, server_nonce, &client_final_msg_wo_proof); /* AuthMessage := client-first-message-bare + "," + * server-first-message + "," + * client-final-message-without-proof */ AuthMessage.size = state->first_msg_bare.size + 1 + server_first_msg->size + 1 + client_final_msg_wo_proof.size; AuthMessage.ptr = rd_alloca(AuthMessage.size+1); rd_snprintf(AuthMessage.ptr, AuthMessage.size+1, "%.*s,%.*s,%.*s", (int)state->first_msg_bare.size, state->first_msg_bare.ptr, (int)server_first_msg->size, server_first_msg->ptr, (int)client_final_msg_wo_proof.size, client_final_msg_wo_proof.ptr); /* * Calculate ServerSignature for later verification when * server-final-message is received. */ /* ServerKey := HMAC(SaltedPassword, "Server Key") */ if (rd_kafka_sasl_scram_HMAC( rktrans, &SaltedPassword, &ServerKeyVerbatim, &ServerKey) == -1) { rd_free(client_final_msg_wo_proof.ptr); return -1; } /* ServerSignature := HMAC(ServerKey, AuthMessage) */ if (rd_kafka_sasl_scram_HMAC(rktrans, &ServerKey, &AuthMessage, &ServerSignature) == -1) { rd_free(client_final_msg_wo_proof.ptr); return -1; } /* Store the Base64 encoded ServerSignature for quick comparison */ state->ServerSignatureB64 = rd_base64_encode(&ServerSignature); /* * Continue with client-final-message */ /* ClientSignature := HMAC(StoredKey, AuthMessage) */ if (rd_kafka_sasl_scram_HMAC(rktrans, &StoredKey, &AuthMessage, &ClientSignature) == -1) { rd_free(client_final_msg_wo_proof.ptr); return -1; } /* ClientProof := ClientKey XOR ClientSignature */ assert(ClientKey.size == ClientSignature.size); for (i = 0 ; i < (int)ClientKey.size ; i++) ClientProof.ptr[i] = ClientKey.ptr[i] ^ ClientSignature.ptr[i]; ClientProof.size = ClientKey.size; /* Base64 encoded ClientProof */ ClientProofB64 = rd_base64_encode(&ClientProof); /* Construct client-final-message */ out->size = client_final_msg_wo_proof.size + strlen(",p=") + strlen(ClientProofB64); out->ptr = rd_malloc(out->size + 1); rd_snprintf(out->ptr, out->size+1, "%.*s,p=%s", (int)client_final_msg_wo_proof.size, client_final_msg_wo_proof.ptr, ClientProofB64); rd_free(ClientProofB64); rd_free(client_final_msg_wo_proof.ptr); return 0; } /** * @brief Handle first message from server * * Parse server response which looks something like: * "r=fyko+d2lbbFgONR....,s=QSXCR+Q6sek8bf92,i=4096" * * @returns -1 on error. */ static int rd_kafka_sasl_scram_handle_server_first_message (rd_kafka_transport_t *rktrans, const rd_chariov_t *in, rd_chariov_t *out, char *errstr, size_t errstr_size) { struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state; char *server_nonce; rd_chariov_t salt_b64, salt; char *itcntstr; const char *endptr; int itcnt; char *attr_m; /* Mandatory future extension check */ if ((attr_m = rd_kafka_sasl_scram_get_attr( in, 'm', NULL, NULL, 0))) { rd_snprintf(errstr, errstr_size, "Unsupported mandatory SCRAM extension"); rd_free(attr_m); return -1; } /* Server nonce */ if (!(server_nonce = rd_kafka_sasl_scram_get_attr( in, 'r', "Server nonce in server-first-message", errstr, errstr_size))) return -1; if (strlen(server_nonce) <= state->cnonce.size || strncmp(state->cnonce.ptr, server_nonce, state->cnonce.size)) { rd_snprintf(errstr, errstr_size, "Server/client nonce mismatch in " "server-first-message"); rd_free(server_nonce); return -1; } /* Salt (Base64) */ if (!(salt_b64.ptr = rd_kafka_sasl_scram_get_attr( in, 's', "Salt in server-first-message", errstr, errstr_size))) { rd_free(server_nonce); return -1; } salt_b64.size = strlen(salt_b64.ptr); /* Convert Salt to binary */ if (rd_base64_decode(&salt_b64, &salt) == -1) { rd_snprintf(errstr, errstr_size, "Invalid Base64 Salt in server-first-message"); rd_free(server_nonce); rd_free(salt_b64.ptr); } rd_free(salt_b64.ptr); /* Iteration count (as string) */ if (!(itcntstr = rd_kafka_sasl_scram_get_attr( in, 'i', "Iteration count in server-first-message", errstr, errstr_size))) { rd_free(server_nonce); rd_free(salt.ptr); return -1; } /* Iteration count (as int) */ errno = 0; itcnt = (int)strtoul(itcntstr, (char **)&endptr, 10); if (itcntstr == endptr || *endptr != '\0' || errno != 0 || itcnt > 1000000) { rd_snprintf(errstr, errstr_size, "Invalid value (not integer or too large) " "for Iteration count in server-first-message"); rd_free(server_nonce); rd_free(salt.ptr); rd_free(itcntstr); return -1; } rd_free(itcntstr); /* Build client-final-message */ if (rd_kafka_sasl_scram_build_client_final_message( rktrans, &salt, server_nonce, in, itcnt, out) == -1) { rd_snprintf(errstr, errstr_size, "Failed to build SCRAM client-final-message"); rd_free(salt.ptr); rd_free(server_nonce); return -1; } rd_free(server_nonce); rd_free(salt.ptr); return 0; } /** * @brief Handle server-final-message * * This is the end of authentication and the SCRAM state * will be freed at the end of this function regardless of * authentication outcome. * * @returns -1 on failure */ static int rd_kafka_sasl_scram_handle_server_final_message ( rd_kafka_transport_t *rktrans, const rd_chariov_t *in, char *errstr, size_t errstr_size) { struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state; char *attr_v, *attr_e; if ((attr_e = rd_kafka_sasl_scram_get_attr( in, 'e', "server-error in server-final-message", errstr, errstr_size))) { /* Authentication failed */ rd_snprintf(errstr, errstr_size, "SASL SCRAM authentication failed: " "broker responded with %s", attr_e); rd_free(attr_e); return -1; } else if ((attr_v = rd_kafka_sasl_scram_get_attr( in, 'v', "verifier in server-final-message", errstr, errstr_size))) { const rd_kafka_conf_t *conf; /* Authentication succesful on server, * but we need to verify the ServerSignature too. */ rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY | RD_KAFKA_DBG_BROKER, "SCRAMAUTH", "SASL SCRAM authentication succesful on server: " "verifying ServerSignature"); if (strcmp(attr_v, state->ServerSignatureB64)) { rd_snprintf(errstr, errstr_size, "SASL SCRAM authentication failed: " "ServerSignature mismatch " "(server's %s != ours %s)", attr_v, state->ServerSignatureB64); rd_free(attr_v); return -1; } rd_free(attr_v); conf = &rktrans->rktrans_rkb->rkb_rk->rk_conf; rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY | RD_KAFKA_DBG_BROKER, "SCRAMAUTH", "Authenticated as %s using %s", conf->sasl.username, conf->sasl.mechanisms); rd_kafka_sasl_auth_done(rktrans); return 0; } else { rd_snprintf(errstr, errstr_size, "SASL SCRAM authentication failed: " "no verifier or server-error returned from broker"); return -1; } } /** * @brief Build client-first-message */ static void rd_kafka_sasl_scram_build_client_first_message ( rd_kafka_transport_t *rktrans, rd_chariov_t *out) { char *sasl_username; struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state; const rd_kafka_conf_t *conf = &rktrans->rktrans_rkb->rkb_rk->rk_conf; rd_kafka_sasl_scram_generate_nonce(&state->cnonce); sasl_username = rd_kafka_sasl_safe_string(conf->sasl.username); out->size = strlen("n,,n=,r=") + strlen(sasl_username) + state->cnonce.size; out->ptr = rd_malloc(out->size+1); rd_snprintf(out->ptr, out->size+1, "n,,n=%s,r=%.*s", sasl_username, (int)state->cnonce.size, state->cnonce.ptr); rd_free(sasl_username); /* Save client-first-message-bare (skip gs2-header) */ state->first_msg_bare.size = out->size-3; state->first_msg_bare.ptr = rd_memdup(out->ptr+3, state->first_msg_bare.size); } /** * @brief SASL SCRAM client state machine * @returns -1 on failure (errstr set), else 0. */ static int rd_kafka_sasl_scram_fsm (rd_kafka_transport_t *rktrans, const rd_chariov_t *in, char *errstr, size_t errstr_size) { static const char *state_names[] = { "client-first-message", "server-first-message", "client-final-message", }; struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state; rd_chariov_t out = RD_ZERO_INIT; int r = -1; rd_ts_t ts_start = rd_clock(); int prev_state = state->state; rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "SASLSCRAM", "SASL SCRAM client in state %s", state_names[state->state]); switch (state->state) { case RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FIRST_MESSAGE: rd_dassert(!in); /* Not expecting any server-input */ rd_kafka_sasl_scram_build_client_first_message(rktrans, &out); state->state = RD_KAFKA_SASL_SCRAM_STATE_SERVER_FIRST_MESSAGE; break; case RD_KAFKA_SASL_SCRAM_STATE_SERVER_FIRST_MESSAGE: rd_dassert(in); /* Requires server-input */ if (rd_kafka_sasl_scram_handle_server_first_message( rktrans, in, &out, errstr, errstr_size) == -1) return -1; state->state = RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FINAL_MESSAGE; break; case RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FINAL_MESSAGE: rd_dassert(in); /* Requires server-input */ r = rd_kafka_sasl_scram_handle_server_final_message( rktrans, in, errstr, errstr_size); break; } if (out.ptr) { r = rd_kafka_sasl_send(rktrans, out.ptr, (int)out.size, errstr, errstr_size); rd_free(out.ptr); } ts_start = (rd_clock() - ts_start) / 1000; if (ts_start >= 100) rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "SCRAM", "SASL SCRAM state %s handled in %"PRId64"ms", state_names[prev_state], ts_start); return r; } /** * @brief Handle received frame from broker. */ static int rd_kafka_sasl_scram_recv (rd_kafka_transport_t *rktrans, const void *buf, size_t size, char *errstr, size_t errstr_size) { const rd_chariov_t in = { .ptr = (char *)buf, .size = size }; return rd_kafka_sasl_scram_fsm(rktrans, &in, errstr, errstr_size); } /** * @brief Initialize and start SASL SCRAM (builtin) authentication. * * Returns 0 on successful init and -1 on error. * * @locality broker thread */ static int rd_kafka_sasl_scram_client_new (rd_kafka_transport_t *rktrans, const char *hostname, char *errstr, size_t errstr_size) { struct rd_kafka_sasl_scram_state *state; state = rd_calloc(1, sizeof(*state)); state->state = RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FIRST_MESSAGE; rktrans->rktrans_sasl.state = state; /* Kick off the FSM */ return rd_kafka_sasl_scram_fsm(rktrans, NULL, errstr, errstr_size); } /** * @brief Validate SCRAM config and look up the hash function */ static int rd_kafka_sasl_scram_conf_validate (rd_kafka_t *rk, char *errstr, size_t errstr_size) { const char *mech = rk->rk_conf.sasl.mechanisms; if (!rk->rk_conf.sasl.username || !rk->rk_conf.sasl.password) { rd_snprintf(errstr, errstr_size, "sasl.username and sasl.password must be set"); return -1; } if (!strcmp(mech, "SCRAM-SHA-1")) { rk->rk_conf.sasl.scram_evp = EVP_sha1(); rk->rk_conf.sasl.scram_H = SHA1; rk->rk_conf.sasl.scram_H_size = SHA_DIGEST_LENGTH; } else if (!strcmp(mech, "SCRAM-SHA-256")) { rk->rk_conf.sasl.scram_evp = EVP_sha256(); rk->rk_conf.sasl.scram_H = SHA256; rk->rk_conf.sasl.scram_H_size = SHA256_DIGEST_LENGTH; } else if (!strcmp(mech, "SCRAM-SHA-512")) { rk->rk_conf.sasl.scram_evp = EVP_sha512(); rk->rk_conf.sasl.scram_H = SHA512; rk->rk_conf.sasl.scram_H_size = SHA512_DIGEST_LENGTH; } else { rd_snprintf(errstr, errstr_size, "Unsupported hash function: %s " "(try SCRAM-SHA-512)", mech); return -1; } return 0; } const struct rd_kafka_sasl_provider rd_kafka_sasl_scram_provider = { .name = "SCRAM (builtin)", .client_new = rd_kafka_sasl_scram_client_new, .recv = rd_kafka_sasl_scram_recv, .close = rd_kafka_sasl_scram_close, .conf_validate = rd_kafka_sasl_scram_conf_validate, };
int dgst_main(int argc, char **argv) { BIO *in = NULL, *inp, *bmd = NULL, *out = NULL; ENGINE *e = NULL, *impl = NULL; EVP_PKEY *sigkey = NULL; STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; char *hmac_key = NULL; char *mac_name = NULL; char *passinarg = NULL, *passin = NULL; const EVP_MD *md = NULL, *m; const char *outfile = NULL, *keyfile = NULL, *prog = NULL; const char *sigfile = NULL, *randfile = NULL; OPTION_CHOICE o; int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0; int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0; unsigned char *buf = NULL, *sigbuf = NULL; int engine_impl = 0; prog = opt_progname(argv[0]); buf = app_malloc(BUFSIZE, "I/O buffer"); md = EVP_get_digestbyname(prog); prog = opt_init(argc, argv, dgst_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(dgst_options); ret = 0; goto end; case OPT_C: separator = 1; break; case OPT_R: separator = 2; break; case OPT_RAND: randfile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_SIGN: keyfile = opt_arg(); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_VERIFY: keyfile = opt_arg(); want_pub = do_verify = 1; break; case OPT_PRVERIFY: keyfile = opt_arg(); do_verify = 1; break; case OPT_SIGNATURE: sigfile = opt_arg(); break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) goto opthelp; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_ENGINE_IMPL: engine_impl = 1; break; case OPT_HEX: out_bin = 0; break; case OPT_BINARY: out_bin = 1; break; case OPT_DEBUG: debug = 1; break; case OPT_FIPS_FINGERPRINT: hmac_key = "etaonrishdlcupfm"; break; case OPT_HMAC: hmac_key = opt_arg(); break; case OPT_MAC: mac_name = opt_arg(); break; case OPT_SIGOPT: if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) goto opthelp; break; case OPT_MACOPT: if (!macopts) macopts = sk_OPENSSL_STRING_new_null(); if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg())) goto opthelp; break; case OPT_DIGEST: if (!opt_md(opt_unknown(), &m)) goto opthelp; md = m; break; } } argc = opt_num_rest(); argv = opt_rest(); if (keyfile != NULL && argc > 1) { BIO_printf(bio_err, "%s: Can only sign or verify one file.\n", prog); goto end; } if (do_verify && !sigfile) { BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); goto end; } if (engine_impl) impl = e; in = BIO_new(BIO_s_file()); bmd = BIO_new(BIO_f_md()); if ((in == NULL) || (bmd == NULL)) { ERR_print_errors(bio_err); goto end; } if (debug) { BIO_set_callback(in, BIO_debug_callback); /* needed for windows 3.1 */ BIO_set_callback_arg(in, (char *)bio_err); } if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (out_bin == -1) { if (keyfile) out_bin = 1; else out_bin = 0; } if (randfile) app_RAND_load_file(randfile, 0); out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); if (out == NULL) goto end; if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) { BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); goto end; } if (keyfile) { if (want_pub) sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file"); else sigkey = load_key(keyfile, keyform, 0, passin, e, "key file"); if (!sigkey) { /* * load_[pub]key() has already printed an appropriate message */ goto end; } } if (mac_name) { EVP_PKEY_CTX *mac_ctx = NULL; int r = 0; if (!init_gen_str(&mac_ctx, mac_name, impl, 0)) goto mac_end; if (macopts) { char *macopt; for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { macopt = sk_OPENSSL_STRING_value(macopts, i); if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { BIO_printf(bio_err, "MAC parameter error \"%s\"\n", macopt); ERR_print_errors(bio_err); goto mac_end; } } } if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) { BIO_puts(bio_err, "Error generating key\n"); ERR_print_errors(bio_err); goto mac_end; } r = 1; mac_end: EVP_PKEY_CTX_free(mac_ctx); if (r == 0) goto end; } if (hmac_key) { sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl, (unsigned char *)hmac_key, -1); if (!sigkey) goto end; } if (sigkey) { EVP_MD_CTX *mctx = NULL; EVP_PKEY_CTX *pctx = NULL; int r; if (!BIO_get_md_ctx(bmd, &mctx)) { BIO_printf(bio_err, "Error getting context\n"); ERR_print_errors(bio_err); goto end; } if (do_verify) r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey); else r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey); if (!r) { BIO_printf(bio_err, "Error setting context\n"); ERR_print_errors(bio_err); goto end; } if (sigopts) { char *sigopt; for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { sigopt = sk_OPENSSL_STRING_value(sigopts, i); if (pkey_ctrl_string(pctx, sigopt) <= 0) { BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); ERR_print_errors(bio_err); goto end; } } } } /* we use md as a filter, reading from 'in' */ else { EVP_MD_CTX *mctx = NULL; if (!BIO_get_md_ctx(bmd, &mctx)) { BIO_printf(bio_err, "Error getting context\n"); ERR_print_errors(bio_err); goto end; } if (md == NULL) md = EVP_sha256(); if (!EVP_DigestInit_ex(mctx, md, impl)) { BIO_printf(bio_err, "Error setting digest\n"); ERR_print_errors(bio_err); goto end; } } if (sigfile && sigkey) { BIO *sigbio = BIO_new_file(sigfile, "rb"); if (!sigbio) { BIO_printf(bio_err, "Error opening signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } siglen = EVP_PKEY_size(sigkey); sigbuf = app_malloc(siglen, "signature buffer"); siglen = BIO_read(sigbio, sigbuf, siglen); BIO_free(sigbio); if (siglen <= 0) { BIO_printf(bio_err, "Error reading signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } } inp = BIO_push(bmd, in); if (md == NULL) { EVP_MD_CTX *tctx; BIO_get_md_ctx(bmd, &tctx); md = EVP_MD_CTX_md(tctx); } if (argc == 0) { BIO_set_fp(in, stdin, BIO_NOCLOSE); ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, NULL, NULL, "stdin"); } else { const char *md_name = NULL, *sig_name = NULL; if (!out_bin) { if (sigkey) { const EVP_PKEY_ASN1_METHOD *ameth; ameth = EVP_PKEY_get0_asn1(sigkey); if (ameth) EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &sig_name, ameth); } if (md) md_name = EVP_MD_name(md); } ret = 0; for (i = 0; i < argc; i++) { int r; if (BIO_read_filename(in, argv[i]) <= 0) { perror(argv[i]); ret++; continue; } else r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, sig_name, md_name, argv[i]); if (r) ret = r; (void)BIO_reset(bmd); } } end: OPENSSL_clear_free(buf, BUFSIZE); BIO_free(in); OPENSSL_free(passin); BIO_free_all(out); EVP_PKEY_free(sigkey); sk_OPENSSL_STRING_free(sigopts); sk_OPENSSL_STRING_free(macopts); OPENSSL_free(sigbuf); BIO_free(bmd); release_engine(e); return (ret); }
const EVP_MD *ssl_handshake_md(SSL *s) { return EVP_sha256(); }
static int xmlSecOpenSSLEvpDigestInitialize(xmlSecTransformPtr transform) { xmlSecOpenSSLDigestCtxPtr ctx; xmlSecAssert2(xmlSecOpenSSLEvpDigestCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpDigestSize), -1); ctx = xmlSecOpenSSLEvpDigestGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); /* initialize context */ memset(ctx, 0, sizeof(xmlSecOpenSSLDigestCtx)); #ifndef XMLSEC_NO_MD5 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformMd5Id)) { ctx->digest = EVP_md5(); } else #endif /* XMLSEC_NO_MD5 */ #ifndef XMLSEC_NO_RIPEMD160 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRipemd160Id)) { ctx->digest = EVP_ripemd160(); } else #endif /* XMLSEC_NO_RIPEMD160 */ #ifndef XMLSEC_NO_SHA1 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha1Id)) { ctx->digest = EVP_sha1(); } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA224 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha224Id)) { ctx->digest = EVP_sha224(); } else #endif /* XMLSEC_NO_SHA224 */ #ifndef XMLSEC_NO_SHA256 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha256Id)) { ctx->digest = EVP_sha256(); } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha384Id)) { ctx->digest = EVP_sha384(); } else #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha512Id)) { ctx->digest = EVP_sha512(); } else #endif /* XMLSEC_NO_SHA512 */ { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_TRANSFORM, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } #ifndef XMLSEC_OPENSSL_096 EVP_MD_CTX_init(&(ctx->digestCtx)); #endif /* XMLSEC_OPENSSL_096 */ return(0); }
const EVP_MD *ssl_md(int idx) { return EVP_sha256(); }
void janus_dtls_srtp_incoming_msg(janus_dtls_srtp *dtls, char *buf, uint16_t len) { if(dtls == NULL) { JANUS_LOG(LOG_ERR, "No DTLS-SRTP stack, no incoming message...\n"); return; } janus_ice_component *component = (janus_ice_component *)dtls->component; if(component == NULL) { JANUS_LOG(LOG_ERR, "No component, no DTLS...\n"); return; } janus_ice_stream *stream = component->stream; if(!stream) { JANUS_LOG(LOG_ERR, "No stream, no DTLS...\n"); return; } janus_ice_handle *handle = stream->handle; if(!handle || !handle->agent) { JANUS_LOG(LOG_ERR, "No handle/agent, no DTLS...\n"); return; } if(janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT)) { JANUS_LOG(LOG_ERR, "Alert already received, clearing up...\n"); return; } if(!dtls->ssl || !dtls->read_bio) { JANUS_LOG(LOG_ERR, "[%"SCNu64"] No DTLS stuff for component %d in stream %d??\n", handle->handle_id, component->component_id, stream->stream_id); return; } /* We just got a message, can we get rid of the last sent message? */ if(dtls->dtls_last_msg != NULL) { g_free(dtls->dtls_last_msg); dtls->dtls_last_msg = NULL; dtls->dtls_last_len = 0; } janus_dtls_fd_bridge(dtls); int written = BIO_write(dtls->read_bio, buf, len); JANUS_LOG(LOG_HUGE, " Written %d of those bytes on the read BIO...\n", written); janus_dtls_fd_bridge(dtls); int read = SSL_read(dtls->ssl, buf, len); JANUS_LOG(LOG_HUGE, " ...and read %d of them from SSL...\n", read); janus_dtls_fd_bridge(dtls); if(janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_STOP) || janus_is_stopping()) { /* DTLS alert received, we should end it here */ JANUS_LOG(LOG_VERB, "[%"SCNu64"] Forced to stop it here...\n", handle->handle_id); return; } if(SSL_is_init_finished(dtls->ssl)) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] DTLS established, yay!\n", handle->handle_id); /* Check the remote fingerprint */ X509 *rcert = SSL_get_peer_certificate(dtls->ssl); if(!rcert) { JANUS_LOG(LOG_ERR, "[%"SCNu64"] No remote certificate??\n", handle->handle_id); } else { unsigned int rsize; unsigned char rfingerprint[EVP_MAX_MD_SIZE]; char remote_fingerprint[160]; char *rfp = (char *)&remote_fingerprint; if(handle->remote_hashing && !strcasecmp(handle->remote_hashing, "sha-1")) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Computing sha-1 fingerprint of remote certificate...\n", handle->handle_id); X509_digest(rcert, EVP_sha1(), (unsigned char *)rfingerprint, &rsize); } else { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Computing sha-256 fingerprint of remote certificate...\n", handle->handle_id); X509_digest(rcert, EVP_sha256(), (unsigned char *)rfingerprint, &rsize); } X509_free(rcert); rcert = NULL; int i = 0; for(i = 0; i < rsize; i++) { sprintf(rfp, "%.2X:", rfingerprint[i]); rfp += 3; } *(rfp-1) = 0; JANUS_LOG(LOG_VERB, "[%"SCNu64"] Remote fingerprint (%s) of the client is %s\n", handle->handle_id, handle->remote_hashing ? handle->remote_hashing : "sha-256", remote_fingerprint); if(!strcasecmp(remote_fingerprint, handle->remote_fingerprint ? handle->remote_fingerprint : "(none)")) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Fingerprint is a match!\n", handle->handle_id); dtls->dtls_state = JANUS_DTLS_STATE_CONNECTED; } else { /* FIXME NOT a match! MITM? */ JANUS_LOG(LOG_ERR, "[%"SCNu64"] Fingerprint is NOT a match! expected %s\n", handle->handle_id, handle->remote_fingerprint); dtls->dtls_state = JANUS_DTLS_STATE_FAILED; goto done; } if(dtls->dtls_state == JANUS_DTLS_STATE_CONNECTED) { /* Complete with SRTP setup */ unsigned char material[SRTP_MASTER_LENGTH*2]; unsigned char *local_key, *local_salt, *remote_key, *remote_salt; /* Export keying material for SRTP */ if (!SSL_export_keying_material(dtls->ssl, material, SRTP_MASTER_LENGTH*2, "EXTRACTOR-dtls_srtp", 19, NULL, 0, 0)) { /* Oops... */ JANUS_LOG(LOG_ERR, "[%"SCNu64"] Oops, couldn't extract SRTP keying material for component %d in stream %d??\n", handle->handle_id, component->component_id, stream->stream_id); goto done; } /* Key derivation (http://tools.ietf.org/html/rfc5764#section-4.2) */ if(dtls->dtls_role == JANUS_DTLS_ROLE_CLIENT) { local_key = material; remote_key = local_key + SRTP_MASTER_KEY_LENGTH; local_salt = remote_key + SRTP_MASTER_KEY_LENGTH; remote_salt = local_salt + SRTP_MASTER_SALT_LENGTH; } else { remote_key = material; local_key = remote_key + SRTP_MASTER_KEY_LENGTH; remote_salt = local_key + SRTP_MASTER_KEY_LENGTH; local_salt = remote_salt + SRTP_MASTER_SALT_LENGTH; } /* Build master keys and set SRTP policies */ /* Remote (inbound) */ crypto_policy_set_rtp_default(&(dtls->remote_policy.rtp)); crypto_policy_set_rtcp_default(&(dtls->remote_policy.rtcp)); dtls->remote_policy.ssrc.type = ssrc_any_inbound; dtls->remote_policy.key = calloc(SRTP_MASTER_LENGTH+8, sizeof(char)); if(dtls->remote_policy.key == NULL) { JANUS_LOG(LOG_FATAL, "Memory error!\n"); goto done; } memcpy(dtls->remote_policy.key, remote_key, SRTP_MASTER_KEY_LENGTH); memcpy(dtls->remote_policy.key + SRTP_MASTER_KEY_LENGTH, remote_salt, SRTP_MASTER_SALT_LENGTH); dtls->remote_policy.window_size = 128; dtls->remote_policy.allow_repeat_tx = 0; dtls->remote_policy.next = NULL; /* Local (outbound) */ crypto_policy_set_rtp_default(&(dtls->local_policy.rtp)); crypto_policy_set_rtcp_default(&(dtls->local_policy.rtcp)); dtls->local_policy.ssrc.type = ssrc_any_outbound; dtls->local_policy.key = calloc(SRTP_MASTER_LENGTH+8, sizeof(char)); if(dtls->local_policy.key == NULL) { JANUS_LOG(LOG_FATAL, "Memory error!\n"); goto done; } memcpy(dtls->local_policy.key, local_key, SRTP_MASTER_KEY_LENGTH); memcpy(dtls->local_policy.key + SRTP_MASTER_KEY_LENGTH, local_salt, SRTP_MASTER_SALT_LENGTH); dtls->local_policy.window_size = 128; dtls->local_policy.allow_repeat_tx = 0; dtls->local_policy.next = NULL; /* Create SRTP sessions */ err_status_t res = srtp_create(&(dtls->srtp_in), &(dtls->remote_policy)); if(res != err_status_ok) { /* Something went wrong... */ JANUS_LOG(LOG_ERR, "[%"SCNu64"] Oops, error creating inbound SRTP session for component %d in stream %d??\n", handle->handle_id, component->component_id, stream->stream_id); JANUS_LOG(LOG_ERR, "[%"SCNu64"] -- %d (%s)\n", handle->handle_id, res, janus_get_srtp_error(res)); goto done; } JANUS_LOG(LOG_VERB, "[%"SCNu64"] Created inbound SRTP session for component %d in stream %d\n", handle->handle_id, component->component_id, stream->stream_id); res = srtp_create(&(dtls->srtp_out), &(dtls->local_policy)); if(res != err_status_ok) { /* Something went wrong... */ JANUS_LOG(LOG_ERR, "[%"SCNu64"] Oops, error creating outbound SRTP session for component %d in stream %d??\n", handle->handle_id, component->component_id, stream->stream_id); JANUS_LOG(LOG_ERR, "[%"SCNu64"] -- %d (%s)\n", handle->handle_id, res, janus_get_srtp_error(res)); goto done; } dtls->srtp_valid = 1; JANUS_LOG(LOG_VERB, "[%"SCNu64"] Created outbound SRTP session for component %d in stream %d\n", handle->handle_id, component->component_id, stream->stream_id); } done: if(!janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT) && dtls->srtp_valid) { /* Handshake successfully completed */ janus_ice_dtls_handshake_done(handle, component); } else { /* Something went wrong in either DTLS or SRTP... tell the plugin about it */ janus_dtls_callback(dtls->ssl, SSL_CB_ALERT, 0); } } } }
int main(int argc, char **argv) { unsigned char md[SHA256_DIGEST_LENGTH]; int i; EVP_MD_CTX evp; fprintf(stdout, "Testing SHA-256 "); EVP_Digest("abc", 3, md, NULL, EVP_sha256(), NULL); if (sgx_memcmp(md, app_b1, sizeof(app_b1))) { fflush(stdout); fprintf(stderr, "\nTEST 1 of 3 failed.\n"); return 1; } else fprintf(stdout, "."); fflush(stdout); EVP_Digest("abcdbcde" "cdefdefg" "efghfghi" "ghijhijk" "ijkljklm" "klmnlmno" "mnopnopq", 56, md, NULL, EVP_sha256(), NULL); if (sgx_memcmp(md, app_b2, sizeof(app_b2))) { fflush(stdout); fprintf(stderr, "\nTEST 2 of 3 failed.\n"); return 1; } else fprintf(stdout, "."); fflush(stdout); EVP_MD_CTX_init(&evp); EVP_DigestInit_ex(&evp, EVP_sha256(), NULL); for (i = 0; i < 1000000; i += 160) EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa", (1000000 - i) < 160 ? 1000000 - i : 160); EVP_DigestFinal_ex(&evp, md, NULL); EVP_MD_CTX_cleanup(&evp); if (sgx_memcmp(md, app_b3, sizeof(app_b3))) { fflush(stdout); fprintf(stderr, "\nTEST 3 of 3 failed.\n"); return 1; } else fprintf(stdout, "."); fflush(stdout); fprintf(stdout, " passed.\n"); fflush(stdout); fprintf(stdout, "Testing SHA-224 "); EVP_Digest("abc", 3, md, NULL, EVP_sha224(), NULL); if (sgx_memcmp(md, addenum_1, sizeof(addenum_1))) { fflush(stdout); fprintf(stderr, "\nTEST 1 of 3 failed.\n"); return 1; } else fprintf(stdout, "."); fflush(stdout); EVP_Digest("abcdbcde" "cdefdefg" "efghfghi" "ghijhijk" "ijkljklm" "klmnlmno" "mnopnopq", 56, md, NULL, EVP_sha224(), NULL); if (sgx_memcmp(md, addenum_2, sizeof(addenum_2))) { fflush(stdout); fprintf(stderr, "\nTEST 2 of 3 failed.\n"); return 1; } else fprintf(stdout, "."); fflush(stdout); EVP_MD_CTX_init(&evp); EVP_DigestInit_ex(&evp, EVP_sha224(), NULL); for (i = 0; i < 1000000; i += 64) EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa", (1000000 - i) < 64 ? 1000000 - i : 64); EVP_DigestFinal_ex(&evp, md, NULL); EVP_MD_CTX_cleanup(&evp); if (sgx_memcmp(md, addenum_3, sizeof(addenum_3))) { fflush(stdout); fprintf(stderr, "\nTEST 3 of 3 failed.\n"); return 1; } else fprintf(stdout, "."); fflush(stdout); fprintf(stdout, " passed.\n"); fflush(stdout); return 0; }
static bool _cjose_jws_build_dig_sha(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err) { bool retval = false; EVP_MD_CTX *ctx = NULL; // make sure we have an alg header json_t *alg_obj = json_object_get(jws->hdr, CJOSE_HDR_ALG); if (NULL == alg_obj) { CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG); return false; } const char *alg = json_string_value(alg_obj); // build digest using SHA-256/384/512 digest algorithm const EVP_MD *digest_alg = NULL; if ((strcmp(alg, CJOSE_HDR_ALG_RS256) == 0) || (strcmp(alg, CJOSE_HDR_ALG_PS256) == 0) || (strcmp(alg, CJOSE_HDR_ALG_ES256) == 0)) digest_alg = EVP_sha256(); else if ((strcmp(alg, CJOSE_HDR_ALG_RS384) == 0) || (strcmp(alg, CJOSE_HDR_ALG_PS384) == 0) || (strcmp(alg, CJOSE_HDR_ALG_ES384) == 0)) digest_alg = EVP_sha384(); else if ((strcmp(alg, CJOSE_HDR_ALG_RS512) == 0) || (strcmp(alg, CJOSE_HDR_ALG_PS512) == 0) || (strcmp(alg, CJOSE_HDR_ALG_ES512) == 0)) digest_alg = EVP_sha512(); if (NULL == digest_alg) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jws_build_dig_sha_cleanup; } if (NULL != jws->dig) { cjose_get_dealloc()(jws->dig); jws->dig = NULL; } // allocate buffer for digest jws->dig_len = EVP_MD_size(digest_alg); jws->dig = (uint8_t *)cjose_get_alloc()(jws->dig_len); if (NULL == jws->dig) { CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY); goto _cjose_jws_build_dig_sha_cleanup; } // instantiate and initialize a new mac digest context ctx = EVP_MD_CTX_create(); if (NULL == ctx) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jws_build_dig_sha_cleanup; } EVP_MD_CTX_init(ctx); // create digest as DIGEST(B64U(HEADER).B64U(DATA)) if (EVP_DigestInit_ex(ctx, digest_alg, NULL) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jws_build_dig_sha_cleanup; } if (EVP_DigestUpdate(ctx, jws->hdr_b64u, jws->hdr_b64u_len) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jws_build_dig_sha_cleanup; } if (EVP_DigestUpdate(ctx, ".", 1) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jws_build_dig_sha_cleanup; } if (EVP_DigestUpdate(ctx, jws->dat_b64u, jws->dat_b64u_len) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jws_build_dig_sha_cleanup; } if (EVP_DigestFinal_ex(ctx, jws->dig, NULL) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jws_build_dig_sha_cleanup; } // if we got this far - success retval = true; _cjose_jws_build_dig_sha_cleanup: if (NULL != ctx) { EVP_MD_CTX_destroy(ctx); } return retval; }
int TLSTicketKeyManager::processTicket(SSL* ssl, unsigned char* keyName, unsigned char* iv, EVP_CIPHER_CTX* cipherCtx, HMAC_CTX* hmacCtx, int encrypt) { uint8_t salt[kTLSTicketKeySaltLen]; uint8_t* saltptr = nullptr; uint8_t output[SHA256_DIGEST_LENGTH]; uint8_t* hmacKey = nullptr; uint8_t* aesKey = nullptr; TLSTicketKeySource* key = nullptr; int result = 0; if (encrypt) { key = findEncryptionKey(); if (key == nullptr) { // no keys available to encrypt VLOG(2) << "No TLS ticket key found"; return -1; } VLOG(4) << "Encrypting new ticket with key name=" << SSLUtil::hexlify(key->keyName_); // Get a random salt and write out key name RAND_pseudo_bytes(salt, (int)sizeof(salt)); memcpy(keyName, key->keyName_.data(), kTLSTicketKeyNameLen); memcpy(keyName + kTLSTicketKeyNameLen, salt, kTLSTicketKeySaltLen); // Create the unique keys by hashing with the salt makeUniqueKeys(key->keySource_, sizeof(key->keySource_), salt, output); // This relies on the fact that SHA256 has 32 bytes of output // and that AES-128 keys are 16 bytes hmacKey = output; aesKey = output + SHA256_DIGEST_LENGTH / 2; // Initialize iv and cipher/mac CTX RAND_pseudo_bytes(iv, AES_BLOCK_SIZE); HMAC_Init_ex(hmacCtx, hmacKey, SHA256_DIGEST_LENGTH / 2, EVP_sha256(), nullptr); EVP_EncryptInit_ex(cipherCtx, EVP_aes_128_cbc(), nullptr, aesKey, iv); result = 1; } else { key = findDecryptionKey(keyName); if (key == nullptr) { // no ticket found for decryption - will issue a new ticket if (VLOG_IS_ON(4)) { string skeyName((char *)keyName, kTLSTicketKeyNameLen); VLOG(4) << "Can't find ticket key with name=" << SSLUtil::hexlify(skeyName)<< ", will generate new ticket"; } result = 0; } else { VLOG(4) << "Decrypting ticket with key name=" << SSLUtil::hexlify(key->keyName_); // Reconstruct the unique key via the salt saltptr = keyName + kTLSTicketKeyNameLen; makeUniqueKeys(key->keySource_, sizeof(key->keySource_), saltptr, output); hmacKey = output; aesKey = output + SHA256_DIGEST_LENGTH / 2; // Initialize cipher/mac CTX HMAC_Init_ex(hmacCtx, hmacKey, SHA256_DIGEST_LENGTH / 2, EVP_sha256(), nullptr); EVP_DecryptInit_ex(cipherCtx, EVP_aes_128_cbc(), nullptr, aesKey, iv); result = 1; } } // result records whether a ticket key was found to decrypt this ticket, // not wether the session was re-used. if (stats_) { stats_->recordTLSTicket(encrypt, result); } return result; }