Loading...
Searching...
No Matches
XrdCryptosslCipher Class Reference

`#include <XrdCryptosslCipher.hh>`

Inheritance diagram for XrdCryptosslCipher:
Collaboration diagram for XrdCryptosslCipher:

## Public Member Functions

| XrdCryptosslCipher (bool padded, int len, char *pub, int lpub, const char *t)
| XrdCryptosslCipher (const char *t, int l, const char *k, int liv, const char *iv)
| XrdCryptosslCipher (const char *t, int l=0)
| XrdCryptosslCipher (const XrdCryptosslCipher &c)
| XrdCryptosslCipher (XrdSutBucket *b)
virtual | ~XrdCryptosslCipher ()
XrdSutBucket * | AsBucket ()
void | Cleanup ()
int | DecOutLength (int l)
int | Decrypt (const char *bin, int lin, char *out)
int | EncOutLength (int l)
int | Encrypt (const char *bin, int lin, char *out)
bool | Finalize (bool padded, char *pub, int lpub, const char *t)
bool | IsDefaultLength () const
bool | IsValid ()
char * | IV (int &l) const
int | MaxIVLength () const
char * | Public (int &lpub)
char * | RefreshIV (int &l)
void | SetIV (int l, const char *iv)
Public Member Functions inherited from XrdCryptoCipher
| XrdCryptoCipher ()
virtual | ~XrdCryptoCipher ()
int | Decrypt (XrdSutBucket &buck, bool useiv=true)
int | Encrypt (XrdSutBucket &buck, bool useiv=true)
bool | Finalize (char *pub, int lpub, const char *t)
Public Member Functions inherited from XrdCryptoBasic
| XrdCryptoBasic (const char *t=0, int l=0, const char *b=0)
virtual | ~XrdCryptoBasic ()
char * | AsHexString ()
virtual char * | Buffer () const
virtual int | FromHex (const char *hex)
virtual int | Length () const
virtual int | SetBuffer (int l, const char *b)
virtual int | SetLength (int l)
virtual int | SetType (const char *t)
virtual char * | Type () const
virtual void | UseBuffer (int l, const char *b)

## Static Public Member Functions

static bool | IsSupported (const char *cip)

## Detailed Description

Definition at line 54 of file XrdCryptosslCipher.hh.

## Constructor & Destructor Documentation

## XrdCryptosslCipher() [1/5]

XrdCryptosslCipher::XrdCryptosslCipher | ( | const char * | t,
|  | int | l = 0 )

Definition at line 223 of file XrdCryptosslCipher.cc.

{
// Main Constructor
// Complete initialization of a cipher of type t and length l
// The initialization vector is also created
// Used to create ciphers
valid = 0;
ctx = 0;
fIV = 0;
lIV = 0;
cipher = 0;
fDH = 0;
deflength = 1;
// Check and set type
char cipnam[64] = {"bf-cbc"};
if (t && strcmp(t,"default")) {
strcpy(cipnam,t);
cipnam[63] = 0;
}
cipher = EVP_get_cipherbyname(cipnam);
if (cipher) {
// Determine key length
l = (l > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : l;
int ldef = EVP_CIPHER_key_length(cipher);
int lgen = (l > ldef) ? l : ldef;
// Generate and set a new key
char *ktmp = XrdSutRndm::GetBuffer(lgen);
if (ktmp) {
// Init context
ctx = EVP_CIPHER_CTX_new();
if (ctx) {
valid = 1;
// Try setting the key length
if (l && l != ldef) {
EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
EVP_CIPHER_CTX_set_key_length(ctx,l);
EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1);
if (l == EVP_CIPHER_CTX_key_length(ctx)) {
// Use the l bytes at ktmp
SetBuffer(l,ktmp);
deflength = 0;
}
}
if (!Length()) {
EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1);
SetBuffer(ldef,ktmp);
}
// Set also the type
SetType(cipnam);
}
// Cleanup
delete[] ktmp;
}
}
// Finally, generate and set a new IV
if (valid)
GenerateIV();
}
XrdCryptoBasic::SetBuffer
virtual int SetBuffer(int l, const char *b)
Definition XrdCryptoBasic.cc:188
XrdCryptoBasic::Length
virtual int Length() const
Definition XrdCryptoBasic.hh:58
XrdCryptoBasic::SetType
virtual int SetType(const char *t)
Definition XrdCryptoBasic.cc:221
XrdSutRndm::GetBuffer
static char * GetBuffer(int len, int opt=-1)
Definition XrdSutRndm.cc:179

References XrdSutRndm::GetBuffer(), XrdCryptoBasic::Length(), XrdCryptoBasic::SetBuffer(), and XrdCryptoBasic::SetType().

Referenced by XrdCryptosslCipher().

Here is the call graph for this function:
Here is the caller graph for this function:

## XrdCryptosslCipher() [2/5]

XrdCryptosslCipher::XrdCryptosslCipher | ( | const char * | t,
|  | int | l,
|  | const char * | k,
|  | int | liv,
|  | const char * | iv )

Definition at line 287 of file XrdCryptosslCipher.cc.

{
// Constructor.
// Initialize a cipher of type t and length l using the key at k and
// the initialization vector at iv.
// Used to import ciphers.
valid = 0;
ctx = 0;
fIV = 0;
lIV = 0;
fDH = 0;
cipher = 0;
deflength = 1;
// Check and set type
char cipnam[64] = {"bf-cbc"};
if (t && strcmp(t,"default")) {
strcpy(cipnam,t);
cipnam[63] = 0;
}
cipher = EVP_get_cipherbyname(cipnam);
if (cipher) {
// Init context
ctx = EVP_CIPHER_CTX_new();
if (ctx) {
// Set the key
SetBuffer(l,k);
if (l != EVP_CIPHER_key_length(cipher))
deflength = 0;
// Set also the type
SetType(cipnam);
// Set validity flag
valid = 1;
}
}
//
// Init cipher
if (valid) {
//
// Set the IV
SetIV(liv,iv);
if (deflength) {
EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)Buffer(), 0, 1);
} else {
EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
EVP_CIPHER_CTX_set_key_length(ctx,Length());
EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)Buffer(), 0, 1);
}
}
}
XrdCryptoBasic::Buffer
virtual char * Buffer() const
Definition XrdCryptoBasic.hh:59
XrdCryptosslCipher::SetIV
void SetIV(int l, const char *iv)
Definition XrdCryptosslCipher.cc:1219

References XrdCryptoBasic::Buffer(), XrdCryptoBasic::Length(), XrdCryptoBasic::SetBuffer(), SetIV(), and XrdCryptoBasic::SetType().

Here is the call graph for this function:

## XrdCryptosslCipher() [3/5]

XrdCryptosslCipher::XrdCryptosslCipher | ( | XrdSutBucket * | b | ) |

Definition at line 342 of file XrdCryptosslCipher.cc.

{
// Constructor from bucket.
// Initialize a cipher of type t and length l using the key at k
// Used to import ciphers.
valid = 0;
ctx = 0;
fIV = 0;
lIV = 0;
fDH = 0;
cipher = 0;
deflength = 1;
if (bck && bck->size > 0) {
valid = 1;
kXR_int32 ltyp = 0;
kXR_int32 livc = 0;
kXR_int32 lbuf = 0;
kXR_int32 lp = 0;
kXR_int32 lg = 0;
kXR_int32 lpub = 0;
kXR_int32 lpri = 0;
char *bp = bck->buffer;
int cur = 0;
memcpy(&ltyp,bp+cur,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(&livc,bp+cur,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(&lbuf,bp+cur,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(&lp,bp+cur,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(&lg,bp+cur,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(&lpub,bp+cur,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(&lpri,bp+cur,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
// Type
if (ltyp) {
char *buf = new char[ltyp+1];
if (buf) {
memcpy(buf,bp+cur,ltyp);
buf[ltyp] = 0;
cipher = EVP_get_cipherbyname(buf);
if (!cipher)
cipher = EVP_get_cipherbyname("bf-cbc");
if (cipher) {
// Set the type
SetType(buf);
} else {
valid = 0;
}
delete[] buf;
} else
valid = 0;
cur += ltyp;
}
// IV
if (livc) {
char *buf = new char[livc];
if (buf) {
memcpy(buf,bp+cur,livc);
cur += livc;
// Set the IV
SetIV(livc,buf);
delete[] buf;
} else
valid = 0;
cur += livc;
}
// buffer
if (lbuf) {
char *buf = new char[lbuf];
if (buf) {
memcpy(buf,bp+cur,lbuf);
// Set the buffer
UseBuffer(lbuf,buf);
if (cipher && lbuf != EVP_CIPHER_key_length(cipher))
deflength = 0;
} else
valid = 0;
cur += lbuf;
}
// DH, if any
if (lp > 0 || lg > 0 || lpub > 0 || lpri > 0) {
char *buf = 0;
BIGNUM *p = NULL, *g = NULL;
BIGNUM *pub = NULL, *pri = NULL;
// p
if (lp > 0) {
buf = new char[lp+1];
if (buf) {
memcpy(buf,bp+cur,lp);
buf[lp] = 0;
BN_hex2bn(&p,buf);
delete[] buf;
} else
valid = 0;
cur += lp;
}
// g
if (lg > 0) {
buf = new char[lg+1];
if (buf) {
memcpy(buf,bp+cur,lg);
buf[lg] = 0;
BN_hex2bn(&g,buf);
delete[] buf;
} else
valid = 0;
cur += lg;
}
// pub_key
if (lpub > 0) {
buf = new char[lpub+1];
if (buf) {
memcpy(buf,bp+cur,lpub);
buf[lpub] = 0;
BN_hex2bn(&pub,buf);
delete[] buf;
} else
valid = 0;
cur += lpub;
}
// priv_key
if (lpri > 0) {
buf = new char[lpri+1];
if (buf) {
memcpy(buf,bp+cur,lpri);
buf[lpri] = 0;
BN_hex2bn(&pri,buf);
delete[] buf;
} else
valid = 0;
cur += lpri;
}
#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;
}
}
//
// Init cipher
if (valid) {
// Init context
ctx = EVP_CIPHER_CTX_new();
if (ctx) {
if (deflength) {
EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)Buffer(), 0, 1);
} else {
EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
EVP_CIPHER_CTX_set_key_length(ctx,Length());
EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)Buffer(), 0, 1);
}
} else
valid = 0;
}
if (!valid) {
Cleanup();
}
}
kXR_int32
int kXR_int32
Definition XPtypes.hh:89
XrdCheckDH
static int XrdCheckDH(EVP_PKEY *pkey)
Definition XrdCryptosslCipher.cc:184
DH_set0_key
static int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
Definition XrdCryptosslCipher.cc:130
DH_set0_pqg
static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
Definition XrdCryptosslCipher.cc:96
XrdCryptoBasic::UseBuffer
virtual void UseBuffer(int l, const char *b)
Definition XrdCryptoBasic.hh:67
XrdCryptosslCipher::Cleanup
void Cleanup()
Definition XrdCryptosslCipher.cc:839

References XrdCryptoBasic::Buffer(), XrdSutBucket::buffer, Cleanup(), DH_set0_key(), DH_set0_pqg(), XrdCryptoBasic::Length(), SetIV(), XrdCryptoBasic::SetType(), XrdSutBucket::size, XrdCryptoBasic::UseBuffer(), and XrdCheckDH().

Here is the call graph for this function:

## XrdCryptosslCipher() [4/5]

XrdCryptosslCipher::XrdCryptosslCipher | ( | bool | padded,
|  | int | len,
|  | char * | pub,
|  | int | lpub,
|  | const char * | t )

Definition at line 531 of file XrdCryptosslCipher.cc.

{
// Constructor for key agreement.
// If pub is not defined, generates a DH full key,
// the public part and parameters can be retrieved using Public().
// 'bits' is ignored (DH key is generated once)
// If pub is defined with the public part and parameters of the
// counterpart fully initialize a cipher with that information.
// Sets also the name to 't', if different from the default one.
// Used for key agreement.
EPNAME("sslCipher::XrdCryptosslCipher");
valid = 0;
ctx = 0;
fIV = 0;
lIV = 0;
fDH = 0;
cipher = 0;
deflength = 1;
if (!pub) {
DEBUG("generate DH parameters");
EVP_PKEY *dhparms = getFixedDHParams();
//
// Important historical context:
// - We used to generate DH params on every server startup (commented
// out below). This was prohibitively costly to do on startup for
// DH parameters large enough to be considered secure.
// - OpenSSL 3.0 improved the DH parameter generation to avoid leaking
// the first bit of the session key (see https://github.com/openssl/openssl/issues/9792
// for more information). However, a side-effect is that the new
// parameters are not recognized as valid in OpenSSL 1.0.2.
// - Since we can't control old client versions and new servers can't
// generate compatible DH parameters, we switch to a fixed, much stronger
// set of DH parameters (3072 bits).
//
// The impact is that we continue leaking the first bit of the session key
// (meaning it's effectively 127 bits not 128 bits -- still plenty secure)
// but upgrade the DH parameters to something more modern (3072; previously,
// it was 512 bits which was not considered secure). The downside
// of fixed DH parameters is that if a nation-state attacked our selected
// parameters (using technology not currently available), we would have
// to upgrade all servers with a new set of DH parameters.
//
/*
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, kDHMINBITS);
EVP_PKEY_CTX_set_dh_paramgen_generator(pkctx, 5);
EVP_PKEY_paramgen(pkctx, &dhParam);
EVP_PKEY_CTX_free(pkctx);
*/
DEBUG("configure DH parameters");
//
// Set params for DH object
EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new(dhparms, 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;
}
} else {
DEBUG("initialize cipher from key-agreement buffer");
//
char *ktmp = 0;
size_t ltmp = 0;
// Extract string with bignumber
BIGNUM *bnpub = 0;
char *pb = strstr(pub,"---BPUB---");
char *pe = strstr(pub,"---EPUB--"); // one less (pub not null-terminated)
if (pb && pe) {
lpub = (int)(pb-pub);
pb += 10;
*pe = 0;
BN_hex2bn(&bnpub, pb);
*pe = '-';
}
if (bnpub) {
//
// Prepare to decode the input buffer
BIO *biop = BIO_new(BIO_s_mem());
if (biop) {
//
// Write buffer into BIO
BIO_write(biop,pub,lpub);
//
// Read params from BIO
EVP_PKEY *dhParam = 0;
PEM_read_bio_Parameters(biop, &dhParam);
if (dhParam) {
if (XrdCheckDH(dhParam) == 1) {
//
// generate DH key
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
ltmp = EVP_PKEY_size(fDH);
ktmp = new char[ltmp];
memset(ktmp, 0, ltmp);
if (ktmp) {
// Create peer public key
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_PKEY *peer = 0;
OSSL_PARAM *params1 = 0;
EVP_PKEY_todata( dhParam, EVP_PKEY_KEY_PARAMETERS, &params1 );
OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, bnpub);
OSSL_PARAM *params2 = OSSL_PARAM_BLD_to_param(bld);
OSSL_PARAM_BLD_free(bld);
OSSL_PARAM *params = OSSL_PARAM_merge( params1, params2 );
pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
EVP_PKEY_fromdata_init(pkctx);
EVP_PKEY_fromdata(pkctx, &peer, EVP_PKEY_KEYPAIR, params);
EVP_PKEY_CTX_free(pkctx);
OSSL_PARAM_free(params);
OSSL_PARAM_free(params1);
OSSL_PARAM_free(params2);
#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, &ltmp);
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;
}
}
}
}
EVP_PKEY_free(dhParam);
}
BIO_free(biop);
}
BN_free( bnpub );
}
//
// If a valid key has been computed, set the cipher
if (valid) {
// Init context
ctx = EVP_CIPHER_CTX_new();
if (ctx) {
// Check and set type
char cipnam[64] = {"bf-cbc"};
if (t && strcmp(t,"default")) {
strcpy(cipnam,t);
cipnam[63] = 0;
}
if ((cipher = EVP_get_cipherbyname(cipnam))) {
// At most EVP_MAX_KEY_LENGTH bytes
ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp;
int ldef = EVP_CIPHER_key_length(cipher);
// Try setting the key length
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 ((int)ltmp == EVP_CIPHER_CTX_key_length(ctx)) {
// Use the ltmp bytes at ktmp
SetBuffer(ltmp,ktmp);
deflength = 0;
}
}
if (!Length()) {
EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1);
SetBuffer(ldef,ktmp);
}
// Set also the type
SetType(cipnam);
}
} else
valid = 0;
}
// Cleanup
if (ktmp) {delete[] ktmp; ktmp = 0;}
}
// Cleanup, if invalid
if (!valid)
Cleanup();
}
DEBUG
#define DEBUG(x)
Definition XrdBwmTrace.hh:54
EPNAME
#define EPNAME(x)
Definition XrdBwmTrace.hh:56
getFixedDHParams
static EVP_PKEY * getFixedDHParams()
Definition XrdCryptosslCipher.cc:169

References Cleanup(), DEBUG, DH_set0_key(), EPNAME, getFixedDHParams(), XrdCryptoBasic::Length(), XrdCryptoBasic::SetBuffer(), XrdCryptoBasic::SetType(), and XrdCheckDH().

Here is the call graph for this function:

## XrdCryptosslCipher() [5/5]

XrdCryptosslCipher::XrdCryptosslCipher | ( | const XrdCryptosslCipher & | c | ) |

Definition at line 745 of file XrdCryptosslCipher.cc.

: XrdCryptoCipher()
{
// Copy Constructor
// Basics
deflength = c.deflength;
valid = c.valid;
ctx = 0;
// IV
lIV = 0;
fIV = 0;
SetIV(c.lIV,c.fIV);
// Cipher
cipher = c.cipher;
// Set the key
SetBuffer(c.Length(),c.Buffer());
// Set also the type
SetType(c.Type());
// DH
fDH = 0;
if (valid && c.fDH) {
valid = 0;
#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(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(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;
}
}
if (valid) {
// Init context
ctx = EVP_CIPHER_CTX_new();
if (!ctx)
valid = 0;
}
if (!valid) {
Cleanup();
}
}
EVP_PKEY_get0_DH
static DH * EVP_PKEY_get0_DH(EVP_PKEY *pkey)
Definition XrdCryptosslCipher.cc:77
DH_get0_key
static void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
Definition XrdCryptosslCipher.cc:121
DH_get0_pqg
static void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
Definition XrdCryptosslCipher.cc:85
XrdCryptoBasic::Type
virtual char * Type() const
Definition XrdCryptoBasic.hh:60
XrdCryptoCipher::XrdCryptoCipher
XrdCryptoCipher()
Definition XrdCryptoCipher.hh:50

References XrdCryptoCipher::XrdCryptoCipher(), XrdCryptosslCipher(), XrdCryptoBasic::Buffer(), Cleanup(), DH_get0_key(), DH_get0_pqg(), DH_set0_key(), DH_set0_pqg(), EVP_PKEY_get0_DH(), XrdCryptoBasic::Length(), XrdCryptoBasic::SetBuffer(), SetIV(), XrdCryptoBasic::SetType(), XrdCryptoBasic::Type(), and XrdCheckDH().

Here is the call graph for this function:

## ~XrdCryptosslCipher()

XrdCryptosslCipher::~XrdCryptosslCipher | ( |  | ) |

virtual

Definition at line 824 of file XrdCryptosslCipher.cc.

{
// Destructor.
// Cleanup IV
if (fIV)
delete[] fIV;
// Cleanups
if (valid)
EVP_CIPHER_CTX_free(ctx);
Cleanup();
}

References Cleanup().

Here is the call graph for this function:

## Member Function Documentation

## AsBucket()

XrdSutBucket * XrdCryptosslCipher::AsBucket | ( |  | ) |

virtual

Reimplemented from XrdCryptoCipher.

Definition at line 1116 of file XrdCryptosslCipher.cc.

{
// Return pointer to a bucket created using the internal information
// serialized
// The bucket is responsible for the allocated memory
XrdSutBucket *buck = (XrdSutBucket *)0;
if (valid) {
// Serialize .. total length
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(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;
kXR_int32 lpri = cpri ? strlen(cpri) : 0;
int ltot = 7*sizeof(kXR_int32) + ltyp + Length() + livc +
lp + lg + lpub + lpri;
char *newbuf = new char[ltot];
if (newbuf) {
int cur = 0;
memcpy(newbuf+cur,&ltyp,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(newbuf+cur,&livc,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(newbuf+cur,&lbuf,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(newbuf+cur,&lp,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(newbuf+cur,&lg,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(newbuf+cur,&lpub,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
memcpy(newbuf+cur,&lpri,sizeof(kXR_int32));
cur += sizeof(kXR_int32);
if (Type()) {
memcpy(newbuf+cur,Type(),ltyp);
cur += ltyp;
}
if (fIV) {
memcpy(newbuf+cur,fIV,livc);
cur += livc;
}
if (Buffer()) {
memcpy(newbuf+cur,Buffer(),lbuf);
cur += lbuf;
}
if (cp) {
memcpy(newbuf+cur,cp,lp);
cur += lp;
OPENSSL_free(cp);
}
if (cg) {
memcpy(newbuf+cur,cg,lg);
cur += lg;
OPENSSL_free(cg);
}
if (cpub) {
memcpy(newbuf+cur,cpub,lpub);
cur += lpub;
OPENSSL_free(cpub);
}
if (cpri) {
memcpy(newbuf+cur,cpri,lpri);
cur += lpri;
OPENSSL_free(cpri);
}
// The bucket now
buck = new XrdSutBucket(newbuf,ltot,kXRS_cipher);
}
}
return buck;
}
kXRS_cipher
@ kXRS_cipher
Definition XrdSutAux.hh:62

References XrdCryptoBasic::Buffer(), DH_get0_key(), DH_get0_pqg(), EVP_PKEY_get0_DH(), kXRS_cipher, XrdCryptoBasic::Length(), and XrdCryptoBasic::Type().

Here is the call graph for this function:

## Cleanup()

void XrdCryptosslCipher::Cleanup | ( |  | ) |

Definition at line 839 of file XrdCryptosslCipher.cc.

{
// Cleanup temporary memory
// Cleanup IV
if (fDH) {
EVP_PKEY_free(fDH);
fDH = 0;
}
}

Referenced by XrdCryptosslCipher(), XrdCryptosslCipher(), XrdCryptosslCipher(), ~XrdCryptosslCipher(), and Finalize().

Here is the caller graph for this function:

## DecOutLength()

int XrdCryptosslCipher::DecOutLength | ( | int | l | ) |

virtual

Reimplemented from XrdCryptoCipher.

Definition at line 1371 of file XrdCryptosslCipher.cc.

{
// Required buffer size for decrypting l bytes
int lout = l+EVP_CIPHER_CTX_block_size(ctx)+1;
lout = (lout <= 0) ? l : lout;
return lout;
}

## Decrypt()

int XrdCryptosslCipher::Decrypt | ( | const char * | bin,
|  | int | lin,
|  | char * | out )

virtual

Reimplemented from XrdCryptoCipher.

Definition at line 1281 of file XrdCryptosslCipher.cc.

{
// Decrypt lin bytes at in with local cipher.
// The outbut buffer must be provided by the caller for at least
// DecOutLength(lin) bytes.
// Returns number of meaningful bytes in out, or 0 in case of problems
return EncDec(0, in, lin, out);
}

## EncOutLength()

int XrdCryptosslCipher::EncOutLength | ( | int | l | ) |

virtual

Reimplemented from XrdCryptoCipher.

Definition at line 1363 of file XrdCryptosslCipher.cc.

{
// Required buffer size for encrypting l bytes
return (l+EVP_CIPHER_CTX_block_size(ctx));
}

## Encrypt()

int XrdCryptosslCipher::Encrypt | ( | const char * | bin,
|  | int | lin,
|  | char * | out )

virtual

Reimplemented from XrdCryptoCipher.

Definition at line 1270 of file XrdCryptosslCipher.cc.

{
// Encrypt lin bytes at in with local cipher.
// The outbut buffer must be provided by the caller for at least
// EncOutLength(lin) bytes.
// Returns number of meaningful bytes in out, or 0 in case of problems
return EncDec(1, in, lin, out);
}

## Finalize()

bool XrdCryptosslCipher::Finalize | ( | bool | padded,
|  | char * | pub,
|  | int | lpub,
|  | const char * | t )

virtual

Reimplemented from XrdCryptoCipher.

Definition at line 851 of file XrdCryptosslCipher.cc.

{
// Finalize cipher during key agreement. Should be called
// for a cipher build with special constructor defining member fDH.
// The buffer pub should contain the public part of the counterpart.
// Sets also the name to 't', if different from the default one.
// Used for key agreement.
EPNAME("sslCipher::Finalize");
if (!fDH) {
DEBUG("DH undefined: this cipher cannot be finalized"
" by this method");
return 0;
}
char *ktmp = 0;
size_t ltmp = 0;
valid = 0;
if (pub) {
//
// Extract string with bignumber
BIGNUM *bnpub = 0;
char *pb = static_cast<char*>(memmem(pub, lpub, "---BPUB---", 10));
char *pe = static_cast<char*>(memmem(pub, lpub, "---EPUB--", 9));
if (pb && pe) {
//lpub = (int)(pb-pub);
pb += 10;
*pe = 0;
BN_hex2bn(&bnpub, pb);
*pe = '-';
}
if (bnpub) {
// Now we can compute the cipher
ltmp = EVP_PKEY_size(fDH);
ktmp = new char[ltmp];
if (ktmp) {
memset(ktmp, 0, ltmp);
// Create peer public key
EVP_PKEY_CTX *pkctx;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_PKEY *peer = nullptr;
OSSL_PARAM *params1 = nullptr;
EVP_PKEY_todata(fDH, EVP_PKEY_KEY_PARAMETERS, &params1);
OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, bnpub);
OSSL_PARAM *params2 = OSSL_PARAM_BLD_to_param(bld);
OSSL_PARAM_BLD_free(bld);
OSSL_PARAM *params = OSSL_PARAM_merge(params1, params2);
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);
OSSL_PARAM_free(params1);
OSSL_PARAM_free(params2);
OSSL_PARAM_free(params);
EVP_PKEY_CTX_free(pkctx);
#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, &ltmp);
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;
}
}
BN_free(bnpub);
bnpub=0;
}
//
// If a valid key has been computed, set the cipher
if (valid) {
// Check and set type
char cipnam[64] = {"bf-cbc"};
if (t && strcmp(t,"default")) {
strcpy(cipnam,t);
cipnam[63] = 0;
}
if ((cipher = EVP_get_cipherbyname(cipnam))) {
// At most EVP_MAX_KEY_LENGTH bytes
ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp;
int ldef = EVP_CIPHER_key_length(cipher);
// Try setting the key length
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 ((int)ltmp == EVP_CIPHER_CTX_key_length(ctx)) {
// Use the ltmp bytes at ktmp
SetBuffer(ltmp,ktmp);
deflength = 0;
}
}
if (!Length()) {
EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1);
SetBuffer(ldef,ktmp);
}
// Set also the type
SetType(cipnam);
}
}
// Cleanup
if (ktmp) {delete[] ktmp; ktmp = 0;}
}
// Cleanup, if invalid
if (!valid) {
EVP_CIPHER_CTX_free(ctx);
Cleanup();
}
// We are done
return valid;
}

References Cleanup(), DEBUG, DH_set0_key(), EPNAME, XrdCryptoBasic::Length(), XrdCryptoBasic::SetBuffer(), and XrdCryptoBasic::SetType().

Here is the call graph for this function:

## IsDefaultLength()

bool XrdCryptosslCipher::IsDefaultLength | ( |  | ) | const

inline virtual

Reimplemented from XrdCryptoCipher.

Definition at line 97 of file XrdCryptosslCipher.hh.

{ return deflength; }

## IsSupported()

bool XrdCryptosslCipher::IsSupported | ( | const char * | cip | ) |

static

Definition at line 215 of file XrdCryptosslCipher.cc.

{
// Check if the specified cipher is supported
return (EVP_get_cipherbyname(cip) != 0);
}

Referenced by XrdCryptosslFactory::SupportedCipher().

Here is the caller graph for this function:

## IsValid()

bool XrdCryptosslCipher::IsValid | ( |  | ) |

inline virtual

Reimplemented from XrdCryptoCipher.

Definition at line 84 of file XrdCryptosslCipher.hh.

{ return valid; }

## IV()

char * XrdCryptosslCipher::IV | ( | int & | l | ) | const

inline virtual

Reimplemented from XrdCryptoCipher.

Definition at line 96 of file XrdCryptosslCipher.hh.

{ l = lIV; return fIV; }

## MaxIVLength()

int XrdCryptosslCipher::MaxIVLength | ( |  | ) | const

virtual

Reimplemented from XrdCryptoCipher.

Definition at line 1381 of file XrdCryptosslCipher.cc.

{
// Return the max cipher IV length
return (lIV > 0) ? lIV : EVP_MAX_IV_LENGTH;
}

## Public()

char * XrdCryptosslCipher::Public | ( | int & | lpub | ) |

virtual

Reimplemented from XrdCryptoCipher.

Definition at line 1005 of file XrdCryptosslCipher.cc.

{
// Return buffer with the public part of the DH key and the shared
// parameters; lpub contains the length of the meaningful bytes.
// Buffer should be deleted by the caller.
static int lhend = strlen("-----END DH PARAMETERS-----");
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(EVP_PKEY_get0_DH(fDH), &pub, NULL);
char *phex = BN_bn2hex(pub);
#endif
int lhex = strlen(phex);
//
// Prepare bio to export info buffer
BIO *biop = BIO_new(BIO_s_mem());
if (biop) {
int ltmp = Publen() + lhex + 20;
char *pub = new char[ltmp];
if (pub) {
// Write parms first
PEM_write_bio_Parameters(biop, fDH);
// Read key from BIO to buf
BIO_read(biop,(void *)pub,ltmp);
BIO_free(biop);
// Add public key
char *p = strstr(pub,"-----END DH PARAMETERS-----");
// Buffer length up to now
lpub = (int)(p - pub) + lhend + 1;
if (phex && p) {
// position at the end
p += (lhend+1);
// Begin of public key hex
memcpy(p,"---BPUB---",10);
p += 10;
// Calculate and write public key hex
memcpy(p,phex,lhex);
OPENSSL_free(phex);
// End of public key hex
p += lhex;
memcpy(p,"---EPUB---",10);
// Calculate total length
lpub += (20 + lhex);
} else {
if (phex) OPENSSL_free(phex);
}
// return
return pub;
}
} else {
if (phex) OPENSSL_free(phex);
}
}
lpub = 0;
return (char *)0;
}

References DH_get0_key(), and EVP_PKEY_get0_DH().

Here is the call graph for this function:

## RefreshIV()

char * XrdCryptosslCipher::RefreshIV | ( | int & | l | ) |

virtual

Reimplemented from XrdCryptoCipher.

Definition at line 1239 of file XrdCryptosslCipher.cc.

{
// Regenerate IV and return it
// Generate a new IV
GenerateIV();
// Set output
l = lIV;
return fIV;
}

## SetIV()

void XrdCryptosslCipher::SetIV | ( | int | l,
|  | const char * | iv )

virtual

Reimplemented from XrdCryptoCipher.

Definition at line 1219 of file XrdCryptosslCipher.cc.

{
// Set IV from l bytes at iv. If !iv, sets the IV length.
if (fIV) {
delete[] fIV;
fIV = 0;
lIV = 0;
}
if (l > 0) {
if (iv) {
fIV = new char[l];
if (fIV) memcpy(fIV,iv,l);
}
lIV = l;
}
}

Referenced by XrdCryptosslCipher(), XrdCryptosslCipher(), and XrdCryptosslCipher().

Here is the caller graph for this function:

The documentation for this class was generated from the following files:

- XrdCryptosslCipher.hh
- XrdCryptosslCipher.cc