diff --git a/src/XrdCrypto/XrdCryptoLite_bf32.cc b/src/XrdCrypto/XrdCryptoLite_bf32.cc index 8a608b0c827..21b00a886f6 100644 --- a/src/XrdCrypto/XrdCryptoLite_bf32.cc +++ b/src/XrdCrypto/XrdCryptoLite_bf32.cc @@ -40,7 +40,7 @@ #include #include -#include +#include #include "XrdOuc/XrdOucCRC.hh" #include "XrdSys/XrdSysHeaders.hh" @@ -82,23 +82,23 @@ int XrdCryptoLite_bf32::Decrypt(const char *key, char *dst, int dstLen) { - BF_KEY decKey; unsigned char ivec[8] = {0,0,0,0,0,0,0,0}; unsigned int crc32; - int ivnum = 0, dLen = srcLen-sizeof(crc32); + int wLen; + int dLen = srcLen - sizeof(crc32); // Make sure we have data // if (dstLen <= (int)sizeof(crc32) || dstLen < srcLen) return -EINVAL; -// Set the key -// - BF_set_key(&decKey, keyLen, (const unsigned char *)key); - // Decrypt // - BF_cfb64_encrypt((const unsigned char *)src, (unsigned char *)dst, srcLen, - &decKey, ivec, &ivnum, BF_DECRYPT); + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit_ex(ctx, EVP_bf_cfb64(), 0, (unsigned char *)key, ivec); + EVP_DecryptUpdate(ctx, (unsigned char *)dst, &wLen, + (unsigned char *)src, srcLen); + EVP_DecryptFinal_ex(ctx, (unsigned char *)dst, &wLen); + EVP_CIPHER_CTX_free(ctx); // Perform the CRC check to verify we have valid data here // @@ -123,10 +123,10 @@ int XrdCryptoLite_bf32::Encrypt(const char *key, char *dst, int dstLen) { - BF_KEY encKey; unsigned char buff[4096], *bP, *mP = 0, ivec[8] = {0,0,0,0,0,0,0,0}; unsigned int crc32; - int ivnum = 0, dLen = srcLen+sizeof(crc32); + int wLen; + int dLen = srcLen + sizeof(crc32); // Make sure that the destination if at least 4 bytes larger and we have data // @@ -146,14 +146,13 @@ int XrdCryptoLite_bf32::Encrypt(const char *key, crc32 = htonl(crc32); memcpy((bP+srcLen), &crc32, sizeof(crc32)); -// Set the key -// - BF_set_key(&encKey, keyLen, (const unsigned char *)key); - // Encrypt // - BF_cfb64_encrypt(bP, (unsigned char *)dst, dLen, - &encKey, ivec, &ivnum, BF_ENCRYPT); + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex(ctx, EVP_bf_cfb64(), 0, (unsigned char *)key, ivec); + EVP_EncryptUpdate(ctx, (unsigned char *)dst, &wLen, bP, dLen); + EVP_EncryptFinal_ex(ctx, (unsigned char *)dst, &wLen); + EVP_CIPHER_CTX_free(ctx); // Free temp buffer and return success // diff --git a/src/XrdCrypto/XrdCryptoX509Chain.cc b/src/XrdCrypto/XrdCryptoX509Chain.cc index 118dee790e6..ad618fb7527 100644 --- a/src/XrdCrypto/XrdCryptoX509Chain.cc +++ b/src/XrdCrypto/XrdCryptoX509Chain.cc @@ -44,7 +44,7 @@ // Description of errors static const char *X509ChainErrStr[] = { - "no error condition occurred", // 0 + "no error condition occurred", // 0 "chain is inconsistent", // 1 "size exceeds max allowed depth", // 2 "invalid or missing CA", // 3 diff --git a/src/XrdCrypto/XrdCryptosslAux.cc b/src/XrdCrypto/XrdCryptosslAux.cc index 240141a7070..fdf8cac1148 100644 --- a/src/XrdCrypto/XrdCryptosslAux.cc +++ b/src/XrdCrypto/XrdCryptosslAux.cc @@ -59,6 +59,22 @@ static RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) } #endif +static int XrdCheckRSA (EVP_PKEY *pkey) { + int rc; +#if OPENSSL_VERSION_NUMBER < 0x10101000L + RSA *rsa = EVP_PKEY_get0_RSA(pkey); + if (rsa) + rc = RSA_check_key(rsa); + else + rc = -2; +#else + EVP_PKEY_CTX *ckctx = EVP_PKEY_CTX_new(pkey, 0); + rc = EVP_PKEY_check(ckctx); + EVP_PKEY_CTX_free(ckctx); +#endif + return rc; +} + //____________________________________________________________________________ int XrdCryptosslX509VerifyCB(int ok, X509_STORE_CTX *ctx) { @@ -151,7 +167,7 @@ bool XrdCryptosslX509VerifyChain(XrdCryptoX509Chain *chain, int &errcode) return 0; // Set the verify callback function - X509_STORE_set_verify_cb_func(store,0); + X509_STORE_set_verify_cb_func(store, 0); // Add the first (the CA) certificate XrdCryptoX509 *cert = chain->Begin(); @@ -515,29 +531,14 @@ int XrdCryptosslX509ParseFile(FILE *fcer, // rewind and look for it if (nci) { rewind(fcer); - RSA *rsap = 0; - if (!PEM_read_RSAPrivateKey(fcer, &rsap, 0, 0)) { + EVP_PKEY *rsa = 0; + if (!PEM_read_PrivateKey(fcer, &rsa, 0, 0)) { DEBUG("no RSA private key found in file " << fname); } else { DEBUG("found a RSA private key in file " << fname); - // We need to complete the key: we save it temporarily - // to a bio and check all the private keys of the - // loaded certificates - bool ok = 1; - BIO *bkey = BIO_new(BIO_s_mem()); - if (!bkey) { - DEBUG("unable to create BIO for key completion"); - ok = 0; - } - if (ok) { - // Write the private key - if (!PEM_write_bio_RSAPrivateKey(bkey,rsap,0,0,0,0,0)) { - DEBUG("unable to write RSA private key to bio"); - ok = 0; - } - } - RSA_free(rsap); - if (ok) { + // We need to complete the key: + // check all the private keys of the loaded certificates + { // Loop over the chain certificates XrdCryptoX509 *cert = chain->Begin(); while (cert->Opaque()) { @@ -545,20 +546,17 @@ int XrdCryptosslX509ParseFile(FILE *fcer, // Get the public key EVP_PKEY *evpp = X509_get_pubkey((X509 *)(cert->Opaque())); if (evpp) { - RSA *rsa = 0; - if (PEM_read_bio_RSAPrivateKey(bkey,&rsa,0,0)) { - EVP_PKEY_assign_RSA(evpp, rsa); + EVP_PKEY_copy_parameters(evpp, rsa); DEBUG("RSA key completed for '"<Subject()<<"'"); // Test consistency - int rc = RSA_check_key(EVP_PKEY_get0_RSA(evpp)); - if (rc != 0) { + if (XrdCheckRSA(evpp) == 1) { // Update PKI in certificate cert->SetPKI((XrdCryptoX509data)evpp); // Update status cert->PKI()->status = XrdCryptoRSA::kComplete; break; } - } + EVP_PKEY_free(evpp); } } // Get next @@ -566,7 +564,7 @@ int XrdCryptosslX509ParseFile(FILE *fcer, } } // Cleanup - BIO_free(bkey); + EVP_PKEY_free(rsa); } } @@ -610,7 +608,7 @@ int XrdCryptosslX509ParseBucket(XrdSutBucket *b, XrdCryptoX509Chain *chain) // Get certificates from BIO X509 *xcer = 0; - while (PEM_read_bio_X509(bmem,&xcer,0,0)) { + while (PEM_read_bio_X509(bmem, &xcer, 0, 0)) { // // Create container and add to the list XrdCryptoX509 *c = new XrdCryptosslX509(xcer); @@ -632,29 +630,14 @@ int XrdCryptosslX509ParseBucket(XrdSutBucket *b, XrdCryptoX509Chain *chain) // as read operations modify the BIO contents; a read-only BIO // may be more efficient) if (nci && BIO_write(bmem,(const void *)(b->buffer),b->size) == b->size) { - RSA *rsap = 0; - if (!PEM_read_bio_RSAPrivateKey(bmem, &rsap, 0, 0)) { - DEBUG("no RSA private key found in bucket "); + EVP_PKEY *rsa = 0; + if (!PEM_read_bio_PrivateKey(bmem, &rsa, 0, 0)) { + DEBUG("no RSA private key found in bucket"); } else { - DEBUG("found a RSA private key in bucket "); - // We need to complete the key: we save it temporarily - // to a bio and check all the private keys of the - // loaded certificates - bool ok = 1; - BIO *bkey = BIO_new(BIO_s_mem()); - if (!bkey) { - DEBUG("unable to create BIO for key completion"); - ok = 0; - } - if (ok) { - // Write the private key - if (!PEM_write_bio_RSAPrivateKey(bkey,rsap,0,0,0,0,0)) { - DEBUG("unable to write RSA private key to bio"); - ok = 0; - } - } - RSA_free(rsap); - if (ok) { + DEBUG("found a RSA private key in bucket"); + // We need to complete the key + // check all the private keys of the loaded certificates + { // Loop over the chain certificates XrdCryptoX509 *cert = chain->Begin(); while (cert->Opaque()) { @@ -662,20 +645,17 @@ int XrdCryptosslX509ParseBucket(XrdSutBucket *b, XrdCryptoX509Chain *chain) // Get the public key EVP_PKEY *evpp = X509_get_pubkey((X509 *)(cert->Opaque())); if (evpp) { - RSA *rsa = 0; - if (PEM_read_bio_RSAPrivateKey(bkey,&rsa,0,0)) { - EVP_PKEY_assign_RSA(evpp, rsa); - DEBUG("RSA key completed "); + EVP_PKEY_copy_parameters(evpp, rsa); + DEBUG("RSA key completed"); // Test consistency - int rc = RSA_check_key(EVP_PKEY_get0_RSA(evpp)); - if (rc != 0) { + if (XrdCheckRSA(evpp) == 1) { // Update PKI in certificate cert->SetPKI((XrdCryptoX509data)evpp); // Update status cert->PKI()->status = XrdCryptoRSA::kComplete; break; } - } + EVP_PKEY_free(evpp); } } // Get next @@ -683,7 +663,7 @@ int XrdCryptosslX509ParseBucket(XrdSutBucket *b, XrdCryptoX509Chain *chain) } } // Cleanup - BIO_free(bkey); + EVP_PKEY_free(rsa); } } diff --git a/src/XrdCrypto/XrdCryptosslCipher.cc b/src/XrdCrypto/XrdCryptosslCipher.cc index 0ce116d83b6..d21ce9ba725 100644 --- a/src/XrdCrypto/XrdCryptosslCipher.cc +++ b/src/XrdCrypto/XrdCryptosslCipher.cc @@ -41,6 +41,10 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#include +#endif // ---------------------------------------------------------------------------// // @@ -49,6 +53,14 @@ // ---------------------------------------------------------------------------// #if OPENSSL_VERSION_NUMBER < 0x10100000L +static DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_DH) { + return NULL; + } + return pkey->pkey.dh; +} + static void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) { @@ -133,25 +145,24 @@ static int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) } #endif -#if !defined(HAVE_DH_PADDED) -#if defined(HAVE_DH_PADDED_FUNC) -int DH_compute_key_padded(unsigned char *, const BIGNUM *, DH *); +static int XrdCheckDH (EVP_PKEY *pkey) { + int rc; +#if OPENSSL_VERSION_NUMBER < 0x10101000L + DH *dh = EVP_PKEY_get0_DH(pkey); + if (dh) { + DH_check(dh, &rc); + rc = (rc == 0 ? 1 : 0); + } + else { + rc = -2; + } #else -static int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) -{ - int rv, pad; - rv = dh->meth->compute_key(key, pub_key, dh); - if (rv <= 0) - return rv; - pad = BN_num_bytes(dh->p) - rv; - if (pad > 0) { - memmove(key + pad, key, rv); - memset(key, 0, pad); - } - return rv + pad; -} -#endif + EVP_PKEY_CTX *ckctx = EVP_PKEY_CTX_new(pkey, 0); + rc = EVP_PKEY_check(ckctx); + EVP_PKEY_CTX_free(ckctx); #endif + return rc; +} //_____________________________________________________________________________ bool XrdCryptosslCipher::IsSupported(const char *cip) @@ -369,7 +380,6 @@ XrdCryptosslCipher::XrdCryptosslCipher(XrdSutBucket *bck) } // DH, if any if (lp > 0 || lg > 0 || lpub > 0 || lpri > 0) { - if ((fDH = DH_new())) { char *buf = 0; BIGNUM *p = NULL, *g = NULL; BIGNUM *pub = NULL, *pri = NULL; @@ -397,7 +407,6 @@ XrdCryptosslCipher::XrdCryptosslCipher(XrdSutBucket *bck) valid = 0; cur += lg; } - DH_set0_pqg(fDH, p, NULL, g); // pub_key if (lpub > 0) { buf = new char[lpub+1]; @@ -422,13 +431,32 @@ XrdCryptosslCipher::XrdCryptosslCipher(XrdSutBucket *bck) valid = 0; cur += lpri; } - DH_set0_key(fDH, pub, pri); - int dhrc = 0; - DH_check(fDH,&dhrc); - if (dhrc == 0) - valid = 1; - } else - valid = 0; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); + if (p) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p); + if (g) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g); + if (pub) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub); + if (pri) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, pri); + OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld); + OSSL_PARAM_BLD_free(bld); + if (p) BN_free(p); + if (g) BN_free(g); + if (pub) BN_free(pub); + if (pri) BN_free(pri); + EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0); + EVP_PKEY_fromdata_init(pkctx); + EVP_PKEY_fromdata(pkctx, &fDH, EVP_PKEY_KEYPAIR, params); + EVP_PKEY_CTX_free(pkctx); + OSSL_PARAM_free(params); +#else + DH* dh = DH_new(); + DH_set0_pqg(dh, p, NULL, g); + DH_set0_key(dh, pub, pri); + fDH = EVP_PKEY_new(); + EVP_PKEY_assign_DH(fDH, dh); +#endif + if (XrdCheckDH(fDH) != 1) + valid = 0; } } // @@ -481,27 +509,36 @@ XrdCryptosslCipher::XrdCryptosslCipher(bool padded, int bits, char *pub, bits = (bits < kDHMINBITS) ? kDHMINBITS : bits; // // Generate params for DH object - fDH = DH_new(); - if (fDH && DH_generate_parameters_ex(fDH, bits, DH_GENERATOR_5, NULL)) { - int prc = 0; - DH_check(fDH,&prc); - if (prc == 0) { + EVP_PKEY *dhParam = 0; + EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0); + EVP_PKEY_paramgen_init(pkctx); + EVP_PKEY_CTX_set_dh_paramgen_prime_len(pkctx, bits); + EVP_PKEY_CTX_set_dh_paramgen_generator(pkctx, 5); + EVP_PKEY_paramgen(pkctx, &dhParam); + EVP_PKEY_CTX_free(pkctx); + if (dhParam) { + if (XrdCheckDH(dhParam) == 1) { // // Generate DH key - if (DH_generate_key(fDH)) { + pkctx = EVP_PKEY_CTX_new(dhParam, 0); + EVP_PKEY_keygen_init(pkctx); + EVP_PKEY_keygen(pkctx, &fDH); + EVP_PKEY_CTX_free(pkctx); + if (fDH) { // Init context ctx = EVP_CIPHER_CTX_new(); if (ctx) valid = 1; } } + EVP_PKEY_free(dhParam); } } else { DEBUG("initialize cipher from key-agreement buffer"); // char *ktmp = 0; - int ltmp = 0; + size_t ltmp = 0; // Extract string with bignumber BIGNUM *bnpub = 0; char *pb = strstr(pub,"---BPUB---"); @@ -522,30 +559,67 @@ XrdCryptosslCipher::XrdCryptosslCipher(bool padded, int bits, char *pub, // Write buffer into BIO BIO_write(biop,pub,lpub); // - // Create a key object - if ((fDH = DH_new())) { - // - // Read parms from BIO - PEM_read_bio_DHparams(biop,&fDH,0,0); - int prc = 0; - DH_check(fDH,&prc); - if (prc == 0) { + // Read params from BIO + EVP_PKEY *dhParam = 0; + PEM_read_bio_Parameters(biop, &dhParam); + if (dhParam) { + if (XrdCheckDH(dhParam) == 1) { // // generate DH key - if (DH_generate_key(fDH)) { + EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new(dhParam, 0); + EVP_PKEY_keygen_init(pkctx); + EVP_PKEY_keygen(pkctx, &fDH); + EVP_PKEY_CTX_free(pkctx); + if (fDH) { // Now we can compute the cipher - ktmp = new char[DH_size(fDH)]; - memset(ktmp, 0, DH_size(fDH)); + ktmp = new char[EVP_PKEY_size(fDH)]; + memset(ktmp, 0, EVP_PKEY_size(fDH)); if (ktmp) { - if (padded) { - ltmp = DH_compute_key_padded((unsigned char *)ktmp,bnpub,fDH); - } else { - ltmp = DH_compute_key((unsigned char *)ktmp,bnpub,fDH); + // Create peer public key +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY *peer = 0; + OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, bnpub); + OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld); + OSSL_PARAM_BLD_free(bld); + pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0); + EVP_PKEY_fromdata_init(pkctx); + EVP_PKEY_fromdata(pkctx, &peer, EVP_PKEY_PUBLIC_KEY, params); + EVP_PKEY_CTX_free(pkctx); + OSSL_PARAM_free(params); +#else + DH* dh = DH_new(); + DH_set0_key(dh, BN_dup(bnpub), NULL); + EVP_PKEY *peer = EVP_PKEY_new(); + EVP_PKEY_assign_DH(peer, dh); +#endif + // Derive shared secret + pkctx = EVP_PKEY_CTX_new(fDH, 0); + EVP_PKEY_derive_init(pkctx); +#if OPENSSL_VERSION_NUMBER >= 0x10101000L + EVP_PKEY_CTX_set_dh_pad(pkctx, padded); +#endif + EVP_PKEY_derive_set_peer(pkctx, peer); + EVP_PKEY_derive(pkctx, (unsigned char *)ktmp, <mp); + EVP_PKEY_CTX_free(pkctx); + EVP_PKEY_free(peer); + if (ltmp > 0) { +#if OPENSSL_VERSION_NUMBER < 0x10101000L + if (padded) { + int pad = EVP_PKEY_size(fDH) - ltmp; + if (pad > 0) { + memmove(ktmp + pad, ktmp, ltmp); + memset(ktmp, 0, pad); + ltmp += pad; + } + } +#endif + valid = 1; } - if (ltmp > 0) valid = 1; } } } + EVP_PKEY_free(dhParam); } BIO_free(biop); } @@ -568,11 +642,11 @@ XrdCryptosslCipher::XrdCryptosslCipher(bool padded, int bits, char *pub, ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp; int ldef = EVP_CIPHER_key_length(cipher); // Try setting the key length - if (ltmp != ldef) { + if ((int)ltmp != ldef) { EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1); EVP_CIPHER_CTX_set_key_length(ctx,ltmp); EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1); - if (ltmp == EVP_CIPHER_CTX_key_length(ctx)) { + if ((int)ltmp == EVP_CIPHER_CTX_key_length(ctx)) { // Use the ltmp bytes at ktmp SetBuffer(ltmp,ktmp); deflength = 0; @@ -622,16 +696,46 @@ XrdCryptosslCipher::XrdCryptosslCipher(const XrdCryptosslCipher &c) fDH = 0; if (valid && c.fDH) { valid = 0; - if ((fDH = DH_new())) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BIGNUM *p = BN_new(); + BIGNUM *g = BN_new(); + BIGNUM *pub = BN_new(); + BIGNUM *pri = BN_new(); + OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); + if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_FFC_P, &p) == 1) + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p); + if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_FFC_G, &g) == 1) + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g); + if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_PUB_KEY, &pub) == 1) + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub); + if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_PRIV_KEY, &pri) == 1) + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, pri); + OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld); + OSSL_PARAM_BLD_free(bld); + BN_free(p); + BN_free(g); + BN_free(pub); + BN_free(pri); + EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0); + EVP_PKEY_fromdata_init(pkctx); + EVP_PKEY_fromdata(pkctx, &fDH, EVP_PKEY_KEYPAIR, params); + EVP_PKEY_CTX_free(pkctx); + OSSL_PARAM_free(params); +#else + DH* dh = DH_new(); + if (dh) { const BIGNUM *p, *g; - DH_get0_pqg(c.fDH, &p, NULL, &g); - DH_set0_pqg(fDH, p ? BN_dup(p) : NULL, NULL, g ? BN_dup(g) : NULL); + DH_get0_pqg(EVP_PKEY_get0_DH(c.fDH), &p, NULL, &g); + DH_set0_pqg(dh, p ? BN_dup(p) : NULL, NULL, g ? BN_dup(g) : NULL); const BIGNUM *pub, *pri; - DH_get0_key(c.fDH, &pub, &pri); - DH_set0_key(fDH, pub ? BN_dup(pub) : NULL, pri ? BN_dup(pri) : NULL); - int dhrc = 0; - DH_check(fDH,&dhrc); - if (dhrc == 0) + DH_get0_key(EVP_PKEY_get0_DH(c.fDH), &pub, &pri); + DH_set0_key(dh, pub ? BN_dup(pub) : NULL, pri ? BN_dup(pri) : NULL); + fDH = EVP_PKEY_new(); + EVP_PKEY_assign_DH(fDH, dh); + } +#endif + if (fDH) { + if (XrdCheckDH(fDH) == 1) valid = 1; } } @@ -668,7 +772,7 @@ void XrdCryptosslCipher::Cleanup() // Cleanup IV if (fDH) { - DH_free(fDH); + EVP_PKEY_free(fDH); fDH = 0; } } @@ -691,7 +795,7 @@ bool XrdCryptosslCipher::Finalize(bool padded, } char *ktmp = 0; - int ltmp = 0; + size_t ltmp = 0; valid = 0; if (pub) { // @@ -708,15 +812,50 @@ bool XrdCryptosslCipher::Finalize(bool padded, } if (bnpub) { // Now we can compute the cipher - ktmp = new char[DH_size(fDH)]; - memset(ktmp, 0, DH_size(fDH)); + ktmp = new char[EVP_PKEY_size(fDH)]; + memset(ktmp, 0, EVP_PKEY_size(fDH)); if (ktmp) { - if (padded) { - ltmp = DH_compute_key_padded((unsigned char *)ktmp,bnpub,fDH); - } else { - ltmp = DH_compute_key((unsigned char *)ktmp,bnpub,fDH); + // Create peer public key + EVP_PKEY_CTX *pkctx; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY *peer = 0; + OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, bnpub); + OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld); + OSSL_PARAM_BLD_free(bld); + pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0); + EVP_PKEY_fromdata_init(pkctx); + EVP_PKEY_fromdata(pkctx, &peer, EVP_PKEY_PUBLIC_KEY, params); + EVP_PKEY_CTX_free(pkctx); + OSSL_PARAM_free(params); +#else + DH* dh = DH_new(); + DH_set0_key(dh, BN_dup(bnpub), NULL); + EVP_PKEY *peer = EVP_PKEY_new(); + EVP_PKEY_assign_DH(peer, dh); +#endif + // Derive shared secret + pkctx = EVP_PKEY_CTX_new(fDH, 0); + EVP_PKEY_derive_init(pkctx); +#if OPENSSL_VERSION_NUMBER >= 0x10101000L + EVP_PKEY_CTX_set_dh_pad(pkctx, padded); +#endif + EVP_PKEY_derive_set_peer(pkctx, peer); + EVP_PKEY_derive(pkctx, (unsigned char *)ktmp, <mp); + EVP_PKEY_CTX_free(pkctx); + if (ltmp > 0) { +#if OPENSSL_VERSION_NUMBER < 0x10101000L + if (padded) { + int pad = EVP_PKEY_size(fDH) - ltmp; + if (pad > 0) { + memmove(ktmp + pad, ktmp, ltmp); + memset(ktmp, 0, pad); + ltmp += pad; + } + } +#endif + valid = 1; } - if (ltmp > 0) valid = 1; } BN_free(bnpub); bnpub=0; @@ -735,11 +874,11 @@ bool XrdCryptosslCipher::Finalize(bool padded, ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp; int ldef = EVP_CIPHER_key_length(cipher); // Try setting the key length - if (ltmp != ldef) { + if ((int)ltmp != ldef) { EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1); EVP_CIPHER_CTX_set_key_length(ctx,ltmp); EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1); - if (ltmp == EVP_CIPHER_CTX_key_length(ctx)) { + if ((int)ltmp == EVP_CIPHER_CTX_key_length(ctx)) { // Use the ltmp bytes at ktmp SetBuffer(ltmp,ktmp); deflength = 0; @@ -775,7 +914,7 @@ int XrdCryptosslCipher::Publen() "-----END DH PARAMETERS-----") + 3; if (fDH) { // minimum length of the core is 22 bytes - int l = 2*DH_size(fDH); + int l = 2 * EVP_PKEY_size(fDH); if (l < 22) l = 22; // for headers l += lhdr; @@ -796,9 +935,16 @@ char *XrdCryptosslCipher::Public(int &lpub) if (fDH) { // // Calculate and write public key hex +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BIGNUM *pub = BN_new(); + EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_PUB_KEY, &pub); + char *phex = BN_bn2hex(pub); + BN_free(pub); +#else const BIGNUM *pub; - DH_get0_key(fDH, &pub, NULL); + DH_get0_key(EVP_PKEY_get0_DH(fDH), &pub, NULL); char *phex = BN_bn2hex(pub); +#endif int lhex = strlen(phex); // // Prepare bio to export info buffer @@ -808,7 +954,7 @@ char *XrdCryptosslCipher::Public(int &lpub) char *pub = new char[ltmp]; if (pub) { // Write parms first - PEM_write_bio_DHparams(biop,fDH); + PEM_write_bio_Parameters(biop, fDH); // Read key from BIO to buf BIO_read(biop,(void *)pub,ltmp); BIO_free(biop); @@ -855,11 +1001,26 @@ void XrdCryptosslCipher::PrintPublic(BIGNUM *pub) BIO *biop = BIO_new(BIO_s_mem()); if (biop) { // Use a DSA structure to export the public part - DSA *dsa = DSA_new(); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY *dsa = 0; + OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub); + OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld); + OSSL_PARAM_BLD_free(bld); + EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, 0); + EVP_PKEY_fromdata_init(pkctx); + EVP_PKEY_fromdata(pkctx, &dsa, EVP_PKEY_PUBLIC_KEY, params); + EVP_PKEY_CTX_free(pkctx); + OSSL_PARAM_free(params); +#else + EVP_PKEY *dsa = EVP_PKEY_new(); + DSA *fdsa = DSA_new(); + DSA_set0_key(fdsa, BN_dup(pub), NULL); + EVP_PKEY_assign_DSA(dsa, fdsa); +#endif if (dsa) { - DSA_set0_key(dsa, BN_dup(pub), NULL); // Write public key to BIO - PEM_write_bio_DSA_PUBKEY(biop,dsa); + PEM_write_bio_PUBKEY(biop, dsa); // Read key from BIO to buf int lpub = Publen(); char *bpub = new char[lpub]; @@ -868,7 +1029,7 @@ void XrdCryptosslCipher::PrintPublic(BIGNUM *pub) cerr << bpub << endl; delete[] bpub; } - DSA_free(dsa); + EVP_PKEY_free(dsa); } BIO_free(biop); } @@ -889,14 +1050,31 @@ XrdSutBucket *XrdCryptosslCipher::AsBucket() kXR_int32 lbuf = Length(); kXR_int32 ltyp = Type() ? strlen(Type()) : 0; kXR_int32 livc = lIV; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BIGNUM *p = BN_new(); + BIGNUM *g = BN_new(); + BIGNUM *pub = BN_new(); + BIGNUM *pri = BN_new(); + EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_FFC_P, &p); + EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_FFC_G, &g); + EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_PUB_KEY, &pub); + EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_PRIV_KEY, &pri); +#else const BIGNUM *p, *g; const BIGNUM *pub, *pri; - DH_get0_pqg(fDH, &p, NULL, &g); - DH_get0_key(fDH, &pub, &pri); + DH_get0_pqg(EVP_PKEY_get0_DH(fDH), &p, NULL, &g); + DH_get0_key(EVP_PKEY_get0_DH(fDH), &pub, &pri); +#endif char *cp = BN_bn2hex(p); char *cg = BN_bn2hex(g); char *cpub = BN_bn2hex(pub); char *cpri = BN_bn2hex(pri); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BN_free(p); + BN_free(g); + BN_free(pub); + BN_free(pri); +#endif kXR_int32 lp = cp ? strlen(cp) : 0; kXR_int32 lg = cg ? strlen(cg) : 0; kXR_int32 lpub = cpub ? strlen(cpub) : 0; diff --git a/src/XrdCrypto/XrdCryptosslCipher.hh b/src/XrdCrypto/XrdCryptosslCipher.hh index 6473ef82995..e8fdd92d930 100644 --- a/src/XrdCrypto/XrdCryptosslCipher.hh +++ b/src/XrdCrypto/XrdCryptosslCipher.hh @@ -53,7 +53,7 @@ private: int lIV; const EVP_CIPHER *cipher; EVP_CIPHER_CTX *ctx; - DH *fDH; + EVP_PKEY *fDH; bool deflength; bool valid; diff --git a/src/XrdCrypto/XrdCryptosslRSA.cc b/src/XrdCrypto/XrdCryptosslRSA.cc index baf441a84cd..1ce9c8d2f8e 100644 --- a/src/XrdCrypto/XrdCryptosslRSA.cc +++ b/src/XrdCrypto/XrdCryptosslRSA.cc @@ -42,6 +42,9 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif #if OPENSSL_VERSION_NUMBER < 0x10100000L static RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) @@ -64,6 +67,22 @@ static void RSA_get0_key(const RSA *r, } #endif +static int XrdCheckRSA (EVP_PKEY *pkey) { + int rc; +#if OPENSSL_VERSION_NUMBER < 0x10101000L + RSA *rsa = EVP_PKEY_get0_RSA(pkey); + if (rsa) + rc = RSA_check_key(rsa); + else + rc = -2; +#else + EVP_PKEY_CTX *ckctx = EVP_PKEY_CTX_new(pkey, 0); + rc = EVP_PKEY_check(ckctx); + EVP_PKEY_CTX_free(ckctx); +#endif + return rc; +} + //_____________________________________________________________________________ XrdCryptosslRSA::XrdCryptosslRSA(int bits, int exp) { @@ -76,12 +95,6 @@ XrdCryptosslRSA::XrdCryptosslRSA(int bits, int exp) publen = -1; prilen = -1; - // Create container, first - if (!(fEVP = EVP_PKEY_new())) { - DEBUG("cannot allocate new public key container"); - return; - } - // Minimum is XrdCryptoMinRSABits bits = (bits >= XrdCryptoMinRSABits) ? bits : XrdCryptoMinRSABits; @@ -92,38 +105,39 @@ XrdCryptosslRSA::XrdCryptosslRSA(int bits, int exp) DEBUG("bits: "<= 0x30000000L + EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pkctx, e); + BN_free(e); +#else + EVP_PKEY_CTX_set_rsa_keygen_pubexp(pkctx, e); +#endif + EVP_PKEY_keygen(pkctx, &fEVP); + EVP_PKEY_CTX_free(pkctx); + // Update status flag - if (RSA_generate_key_ex(fRSA, bits, e, NULL) == 1) { - if (RSA_check_key(fRSA) != 0) { + if (fEVP) { + if (XrdCheckRSA(fEVP) == 1) { status = kComplete; - DEBUG("basic length: "<= 0x30000000L + BIGNUM *d = BN_new(); + bool publiconly = + (EVP_PKEY_get_bn_param(r.fEVP, OSSL_PKEY_PARAM_RSA_D, &d) != 1); + BN_free(d); +#else + const BIGNUM *d = 0; + RSA_get0_key(EVP_PKEY_get0_RSA(r.fEVP), 0, 0, &d); bool publiconly = (d == 0); +#endif // // Bio for exporting the pub key BIO *bcpy = BIO_new(BIO_s_mem()); @@ -217,7 +238,7 @@ XrdCryptosslRSA::XrdCryptosslRSA(const XrdCryptosslRSA &r) : XrdCryptoRSA() } else { if ((fEVP = PEM_read_bio_PrivateKey(bcpy,0,0,0))) { // Check consistency - if (RSA_check_key(EVP_PKEY_get0_RSA(fEVP)) != 0) { + if (XrdCheckRSA(fEVP) == 1) { // Update status status = kComplete; } @@ -245,9 +266,9 @@ int XrdCryptosslRSA::GetOutlen(int lin) { // Get minimal length of output buffer - int lcmax = RSA_size(EVP_PKEY_get0_RSA(fEVP)) - 42; + int lcmax = EVP_PKEY_size(fEVP) - 42; - return ((lin / lcmax) + 1) * RSA_size(EVP_PKEY_get0_RSA(fEVP)); + return ((lin / lcmax) + 1) * EVP_PKEY_size(fEVP); } //_____________________________________________________________________________ @@ -493,17 +514,20 @@ int XrdCryptosslRSA::EncryptPrivate(const char *in, int lin, char *out, int lout // // Private encoding ... - int lcmax = RSA_size(EVP_PKEY_get0_RSA(fEVP)) - 11; // Magic number (= 2*sha1_outlen + 2) - int lout = 0; - int len = lin; + size_t lcmax = EVP_PKEY_size(fEVP) - 11; // Magic number (= 2*sha1_outlen + 2) + size_t lout = 0; + size_t len = lin; int kk = 0; int ke = 0; - while (len > 0 && ke <= (loutmax - lout)) { - int lc = (len > lcmax) ? lcmax : len ; - if ((lout = RSA_private_encrypt(lc, (unsigned char *)&in[kk], - (unsigned char *)&out[ke], - EVP_PKEY_get0_RSA(fEVP), RSA_PKCS1_PADDING)) < 0) { + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(fEVP, 0); + EVP_PKEY_sign_init(ctx); + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING); + while (len > 0 && ke <= int(loutmax - lout)) { + size_t lc = (len > lcmax) ? lcmax : len; + if (EVP_PKEY_sign(ctx, (unsigned char *)&out[ke], &lout, + (unsigned char *)&in[kk], lc) <= 0) { + EVP_PKEY_CTX_free(ctx); char serr[120]; ERR_error_string(ERR_get_error(), serr); DEBUG("error: " < 0 && ke > (loutmax - lout)) + EVP_PKEY_CTX_free(ctx); + if (len > 0 && ke > int(loutmax - lout)) DEBUG("buffer truncated"); lout = ke; - // Return return lout; } @@ -544,17 +568,20 @@ int XrdCryptosslRSA::EncryptPublic(const char *in, int lin, char *out, int loutm // // Public encoding ... - int lcmax = RSA_size(EVP_PKEY_get0_RSA(fEVP)) - 42; // Magic number (= 2*sha1_outlen + 2) - int lout = 0; - int len = lin; + size_t lcmax = EVP_PKEY_size(fEVP) - 42; // Magic number (= 2*sha1_outlen + 2) + size_t lout = 0; + size_t len = lin; int kk = 0; int ke = 0; - while (len > 0 && ke <= (loutmax - lout)) { - int lc = (len > lcmax) ? lcmax : len ; - if ((lout = RSA_public_encrypt(lc, (unsigned char *)&in[kk], - (unsigned char *)&out[ke], - EVP_PKEY_get0_RSA(fEVP), RSA_PKCS1_OAEP_PADDING)) < 0) { + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(fEVP, 0); + EVP_PKEY_encrypt_init(ctx); + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING); + while (len > 0 && ke <= int(loutmax - lout)) { + size_t lc = (len > lcmax) ? lcmax : len; + if (EVP_PKEY_encrypt(ctx, (unsigned char *)&out[ke], &lout, + (unsigned char *)&in[kk], lc) <= 0) { + EVP_PKEY_CTX_free(ctx); char serr[120]; ERR_error_string(ERR_get_error(), serr); DEBUG("error: " < 0 && ke > (loutmax - lout)) + EVP_PKEY_CTX_free(ctx); + if (len > 0 && ke > int(loutmax - lout)) DEBUG("buffer truncated"); lout = ke; - // Return return lout; } @@ -593,18 +620,21 @@ int XrdCryptosslRSA::DecryptPrivate(const char *in, int lin, char *out, int lout return -1; } - int lout = 0; - int len = lin; - int lcmax = RSA_size(EVP_PKEY_get0_RSA(fEVP)); + size_t lout = 0; + size_t len = lin; + size_t lcmax = EVP_PKEY_size(fEVP); int kk = 0; int ke = 0; // // Private decoding ... - while (len > 0 && ke <= (loutmax - lout)) { - if ((lout = RSA_private_decrypt(lcmax, (unsigned char *)&in[kk], - (unsigned char *)&out[ke], - EVP_PKEY_get0_RSA(fEVP), RSA_PKCS1_OAEP_PADDING)) < 0) { + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(fEVP, 0); + EVP_PKEY_decrypt_init(ctx); + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING); + while (len > 0 && ke <= int(loutmax - lout)) { + if (EVP_PKEY_decrypt(ctx, (unsigned char *)&out[ke], &lout, + (unsigned char *)&in[kk], lcmax) <= 0) { + EVP_PKEY_CTX_free(ctx); char serr[120]; ERR_error_string(ERR_get_error(), serr); DEBUG("error: " < 0 && ke > (loutmax - lout)) + EVP_PKEY_CTX_free(ctx); + if (len > 0 && ke > int(loutmax - lout)) PRINT("buffer truncated"); lout = ke; @@ -642,18 +673,21 @@ int XrdCryptosslRSA::DecryptPublic(const char *in, int lin, char *out, int loutm return -1; } - int lout = 0; - int len = lin; - int lcmax = RSA_size(EVP_PKEY_get0_RSA(fEVP)); + size_t lout = 0; + size_t len = lin; + size_t lcmax = EVP_PKEY_size(fEVP); int kk = 0; int ke = 0; // // Private decoding ... - while (len > 0 && ke <= (loutmax - lout)) { - if ((lout = RSA_public_decrypt(lcmax, (unsigned char *)&in[kk], - (unsigned char *)&out[ke], - EVP_PKEY_get0_RSA(fEVP), RSA_PKCS1_PADDING)) < 0) { + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(fEVP, 0); + EVP_PKEY_verify_recover_init(ctx); + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING); + while (len > 0 && ke <= int(loutmax - lout)) { + if (EVP_PKEY_verify_recover(ctx, (unsigned char *)&out[ke], &lout, + (unsigned char *)&in[kk], lcmax) <= 0) { + EVP_PKEY_CTX_free(ctx); char serr[120]; ERR_error_string(ERR_get_error(), serr); PRINT("error: " < 0 && ke > (loutmax - lout)) + EVP_PKEY_CTX_free(ctx); + if (len > 0 && ke > int(loutmax - lout)) PRINT("buffer truncated"); lout = ke; diff --git a/src/XrdCrypto/XrdCryptosslX509.cc b/src/XrdCrypto/XrdCryptosslX509.cc index 19a6e57ef39..ec844b125cf 100644 --- a/src/XrdCrypto/XrdCryptosslX509.cc +++ b/src/XrdCrypto/XrdCryptosslX509.cc @@ -53,6 +53,22 @@ static RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) } #endif +static int XrdCheckRSA (EVP_PKEY *pkey) { + int rc; +#if OPENSSL_VERSION_NUMBER < 0x10101000L + RSA *rsa = EVP_PKEY_get0_RSA(pkey); + if (rsa) + rc = RSA_check_key(rsa); + else + rc = -2; +#else + EVP_PKEY_CTX *ckctx = EVP_PKEY_CTX_new(pkey, 0); + rc = EVP_PKEY_check(ckctx); + EVP_PKEY_CTX_free(ckctx); +#endif + return rc; +} + #define BIO_PRINT(b,c) \ BUF_MEM *bptr; \ BIO_get_mem_ptr(b, &bptr); \ @@ -159,7 +175,7 @@ XrdCryptosslX509::XrdCryptosslX509(const char *cf, const char *kf) if ((evpp = PEM_read_PrivateKey(fk,0,0,0))) { DEBUG("RSA key completed "); // Test consistency - if (RSA_check_key(EVP_PKEY_get0_RSA(evpp)) != 0) { + if (XrdCheckRSA(evpp) == 1) { // Save it in pki pki = new XrdCryptosslRSA(evpp); } diff --git a/src/XrdCrypto/XrdCryptosslgsiAux.cc b/src/XrdCrypto/XrdCryptosslgsiAux.cc index a1d5b8da079..6cc10f246aa 100644 --- a/src/XrdCrypto/XrdCryptosslgsiAux.cc +++ b/src/XrdCrypto/XrdCryptosslgsiAux.cc @@ -115,6 +115,22 @@ static RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) } #endif +static int XrdCheckRSA (EVP_PKEY *pkey) { + int rc; +#if OPENSSL_VERSION_NUMBER < 0x10101000L + RSA *rsa = EVP_PKEY_get0_RSA(pkey); + if (rsa) + rc = RSA_check_key(rsa); + else + rc = -2; +#else + EVP_PKEY_CTX *ckctx = EVP_PKEY_CTX_new(pkey, 0); + rc = EVP_PKEY_check(ckctx); + EVP_PKEY_CTX_free(ckctx); +#endif + return rc; +} + int XrdCryptosslX509Asn1PrintInfo(int tag, int xclass, int constructed, int indent); int XrdCryptosslX509FillUnknownExt(XRDGSI_CONST unsigned char **pp, long length); int XrdCryptosslX509FillVOMS(XRDGSI_CONST unsigned char **pp, @@ -303,7 +319,7 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, } fclose(fk); // Check key consistency - if ((RSA_check_key(EVP_PKEY_get0_RSA(ekEEC)) == 0)) { + if (XrdCheckRSA(ekEEC) != 1) { PRINT("inconsistent key loaded"); EVP_PKEY_free(ekEEC); X509_free(xEEC); @@ -320,42 +336,32 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, } // // Create the new PKI for the proxy (exponent 65537) - RSA *kPX = RSA_new(); - if (!kPX) { - PRINT("proxy key could not be generated - return"); - EVP_PKEY_free(ekEEC); - X509_free(xEEC); - return -kErrPX_GenerateKey; - } BIGNUM *e = BN_new(); if (!e) { PRINT("proxy key could not be generated - return"); - RSA_free(kPX); EVP_PKEY_free(ekEEC); X509_free(xEEC); return -kErrPX_GenerateKey; } BN_set_word(e, 0x10001); - if (RSA_generate_key_ex(kPX, bits, e, NULL) != 1) { - PRINT("proxy key could not be generated - return"); - BN_free(e); - RSA_free(kPX); - EVP_PKEY_free(ekEEC); - X509_free(xEEC); - return -kErrPX_GenerateKey; - } + EVP_PKEY *ekPX = 0; + EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, 0); + EVP_PKEY_keygen_init(pkctx); + EVP_PKEY_CTX_set_rsa_keygen_bits(pkctx, bits); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pkctx, e); BN_free(e); - // - // Set the key into the request - EVP_PKEY *ekPX = EVP_PKEY_new(); +#else + EVP_PKEY_CTX_set_rsa_keygen_pubexp(pkctx, e); +#endif + EVP_PKEY_keygen(pkctx, &ekPX); + EVP_PKEY_CTX_free(pkctx); if (!ekPX) { - PRINT("could not create a EVP_PKEY * instance - return"); - RSA_free(kPX); + PRINT("proxy key could not be generated - return"); EVP_PKEY_free(ekEEC); X509_free(xEEC); - return -kErrPX_NoResources; + return -kErrPX_GenerateKey; } - EVP_PKEY_assign_RSA(ekPX, kPX); X509_REQ_set_pubkey(preq, ekPX); // // Generate a serial number. Specification says that this *should* @@ -597,7 +603,7 @@ int XrdCryptosslX509CreateProxy(const char *fnc, const char *fnk, fclose(fp); rc = -kErrPX_ProxyFile; } - else if (!rc && PEM_write_RSAPrivateKey(fp, kPX, 0, 0, 0, 0, 0) != 1) { + else if (!rc && PEM_write_PrivateKey(fp, ekPX, 0, 0, 0, 0, 0) != 1) { PRINT("error while writing proxy private key"); fclose(fp); rc = -kErrPX_ProxyFile; @@ -664,33 +670,30 @@ int XrdCryptosslX509CreateProxyReq(XrdCryptoX509 *xcpi, bits = (bits < 512) ? 512 : bits; // // Create the new PKI for the proxy (exponent 65537) - RSA *kro = RSA_new(); - if (!kro) { - PRINT("proxy key could not be generated - return"); - return -kErrPX_GenerateKey; - } BIGNUM *e = BN_new(); if (!e) { PRINT("proxy key could not be generated - return"); - RSA_free(kro); return -kErrPX_GenerateKey; } BN_set_word(e, 0x10001); - if (RSA_generate_key_ex(kro, bits, e, NULL) != 1) { - RSA_free(kro); - BN_free(e); - PRINT("proxy key could not be generated - return"); - return -kErrPX_GenerateKey; - } + EVP_PKEY *ekro = 0; + EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, 0); + EVP_PKEY_keygen_init(pkctx); + EVP_PKEY_CTX_set_rsa_keygen_bits(pkctx, bits); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pkctx, e); BN_free(e); +#else + EVP_PKEY_CTX_set_rsa_keygen_pubexp(pkctx, e); +#endif + EVP_PKEY_keygen(pkctx, &ekro); + EVP_PKEY_CTX_free(pkctx); // // Set the key into the request - EVP_PKEY *ekro = EVP_PKEY_new(); if (!ekro) { - PRINT("could not create a EVP_PKEY * instance - return"); - return -kErrPX_NoResources; + PRINT("proxy key could not be generated - return"); + return -kErrPX_GenerateKey; } - EVP_PKEY_assign_RSA(ekro, kro); X509_REQ_set_pubkey(xro, ekro); // // Generate a serial number. Specification says that this *should* @@ -898,6 +901,13 @@ int XrdCryptosslX509SignProxyReq(XrdCryptoX509 *xcpi, XrdCryptoRSA *kcpi, return -kErrPX_BadEECkey; } // Point to the cerificate +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY *ekpi = EVP_PKEY_dup((EVP_PKEY *)(kcpi->Opaque())); + if (!ekpi) { + PRINT("could not create a EVP_PKEY * instance - return"); + return -kErrPX_NoResources; + } +#else RSA *kpi = EVP_PKEY_get0_RSA((EVP_PKEY *)(kcpi->Opaque())); // // Set the key into the request @@ -907,6 +917,7 @@ int XrdCryptosslX509SignProxyReq(XrdCryptoX509 *xcpi, XrdCryptoRSA *kcpi, return -kErrPX_NoResources; } EVP_PKEY_set1_RSA(ekpi, kpi); +#endif // Get request in raw form X509_REQ *xri = (X509_REQ *)(xcri->Opaque()); diff --git a/src/XrdHttp/XrdHttpUtils.cc b/src/XrdHttp/XrdHttpUtils.cc index e4a0b2f36aa..78fa4f26ab8 100644 --- a/src/XrdHttp/XrdHttpUtils.cc +++ b/src/XrdHttp/XrdHttpUtils.cc @@ -230,8 +230,14 @@ void calcHashes( const char *key) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MAC *mac; + EVP_MAC_CTX *ctx; + size_t len; +#else HMAC_CTX *ctx; unsigned int len; +#endif unsigned char mdbuf[EVP_MAX_MD_SIZE]; char buf[64]; struct tm tms; @@ -250,6 +256,54 @@ void calcHashes( return; } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + + mac = EVP_MAC_fetch(0, "sha256", 0); + ctx = EVP_MAC_CTX_new(mac); + + if (!ctx) { + return; + } + + + EVP_MAC_init(ctx, (const unsigned char *) key, strlen(key), 0); + + + if (fn) + EVP_MAC_update(ctx, (const unsigned char *) fn, + strlen(fn) + 1); + + EVP_MAC_update(ctx, (const unsigned char *) &request, + sizeof (request)); + + if (secent->name) + EVP_MAC_update(ctx, (const unsigned char *) secent->name, + strlen(secent->name) + 1); + + if (secent->vorg) + EVP_MAC_update(ctx, (const unsigned char *) secent->vorg, + strlen(secent->vorg) + 1); + + if (secent->host) + EVP_MAC_update(ctx, (const unsigned char *) secent->host, + strlen(secent->host) + 1); + + if (secent->moninfo) + EVP_MAC_update(ctx, (const unsigned char *) secent->moninfo, + strlen(secent->moninfo) + 1); + + localtime_r(&tim, &tms); + strftime(buf, sizeof (buf), "%s", &tms); + EVP_MAC_update(ctx, (const unsigned char *) buf, + strlen(buf) + 1); + + EVP_MAC_final(ctx, mdbuf, &len, EVP_MAX_MD_SIZE); + + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + +#else + ctx = HMAC_CTX_new(); if (!ctx) { @@ -279,7 +333,7 @@ void calcHashes( if (secent->host) HMAC_Update(ctx, (const unsigned char *) secent->host, strlen(secent->host) + 1); - + if (secent->moninfo) HMAC_Update(ctx, (const unsigned char *) secent->moninfo, strlen(secent->moninfo) + 1); @@ -291,9 +345,11 @@ void calcHashes( HMAC_Final(ctx, mdbuf, &len); - Tobase64(mdbuf, len / 2, hash); - HMAC_CTX_free(ctx); + +#endif + + Tobase64(mdbuf, len / 2, hash); } int compareHash( diff --git a/src/XrdSec/XrdSecProtect.cc b/src/XrdSec/XrdSecProtect.cc index 409fb27c1cd..252752172a5 100644 --- a/src/XrdSec/XrdSecProtect.cc +++ b/src/XrdSec/XrdSecProtect.cc @@ -38,7 +38,8 @@ #define COMMON_DIGEST_FOR_OPENSSL #include "CommonCrypto/CommonDigest.h" #else -#include "openssl/sha.h" +#include +#include #endif #include "XrdVersion.hh" @@ -52,6 +53,21 @@ #include "XrdSys/XrdSysPlatform.hh" #include "XrdSys/XrdSysPthread.hh" +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static EVP_MD_CTX* EVP_MD_CTX_new() { + EVP_MD_CTX *ctx = (EVP_MD_CTX *)OPENSSL_malloc(sizeof(EVP_MD_CTX)); + if (ctx) EVP_MD_CTX_init(ctx); + return ctx; +} + +static void EVP_MD_CTX_free(EVP_MD_CTX *ctx) { + if (ctx) { + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); + } +} +#endif + /******************************************************************************/ /* S t r u c t X r d S e c R e q */ /******************************************************************************/ @@ -146,22 +162,30 @@ kXR_write, kXR_signIgnore, kXR_signIgnore, kXR_signNeeded, kXR_signNeeded, bool XrdSecProtect::GetSHA2(unsigned char *hBuff, struct iovec *iovP, int iovN) { - SHA256_CTX sha256; + bool ret = false; + EVP_MD_CTX *mdctx = EVP_MD_CTX_new(); + const EVP_MD *md = EVP_get_digestbyname("sha256"); // Initialize the hash calculattion // - if (0 == SHA256_Init(&sha256)) return false; + if (1 != EVP_DigestInit_ex(mdctx, md, 0)) goto err; // Go through the iovec updating the hash // for (int i = 0; i < iovN; i++) - {if (1 != SHA256_Update(&sha256, iovP[i].iov_base, iovP[i].iov_len)) - return false; - } + { + if (1 != EVP_DigestUpdate(mdctx, iovP[i].iov_base, iovP[i].iov_len)) + goto err; + } // Compute final hash and return result // - return (1 == SHA256_Final(hBuff, &sha256)); + if (1 != EVP_DigestFinal_ex(mdctx, hBuff, 0)) goto err; + + ret = true; + err: + EVP_MD_CTX_free (mdctx); + return ret; } /******************************************************************************/ diff --git a/src/XrdTls/XrdTlsContext.cc b/src/XrdTls/XrdTlsContext.cc index a1435d9c70b..6a7cfc09a16 100644 --- a/src/XrdTls/XrdTlsContext.cc +++ b/src/XrdTls/XrdTlsContext.cc @@ -387,7 +387,9 @@ void InitTLS() // This is strictly a one-time call! OpenSSL_add_all_algorithms(); SSL_load_error_strings(); OpenSSL_add_all_ciphers(); +#if OPENSSL_VERSION_NUMBER < 0x30000000L ERR_load_BIO_strings(); +#endif ERR_load_crypto_strings(); // Set callbacks if we need to do this