XRootD
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 ()
XrdSutBucketAsBucket ()
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 119 of file XrdCryptosslCipher.cc.

120{
121 // Main Constructor
122 // Complete initialization of a cipher of type t and length l
123 // The initialization vector is also created
124 // Used to create ciphers
125
126 valid = 0;
127 ctx = 0;
128 fIV = 0;
129 lIV = 0;
130 cipher = 0;
131 fDH = 0;
132 deflength = 1;
133
134 // Check and set type
135 char cipnam[64] = {"bf-cbc"};
136 if (t && strcmp(t,"default")) {
137 strcpy(cipnam,t);
138 cipnam[63] = 0;
139 }
140 cipher = EVP_get_cipherbyname(cipnam);
141
142 if (cipher) {
143 // Determine key length
144 l = (l > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : l;
145 int ldef = EVP_CIPHER_key_length(cipher);
146 int lgen = (l > ldef) ? l : ldef;
147 // Generate and set a new key
148 char *ktmp = XrdSutRndm::GetBuffer(lgen);
149 if (ktmp) {
150 // Init context
151 ctx = EVP_CIPHER_CTX_new();
152 if (ctx) {
153 valid = 1;
154 // Try setting the key length
155 if (l && l != ldef) {
156 EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
157 EVP_CIPHER_CTX_set_key_length(ctx,l);
158 EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1);
159 if (l == EVP_CIPHER_CTX_key_length(ctx)) {
160 // Use the l bytes at ktmp
161 SetBuffer(l,ktmp);
162 deflength = 0;
163 }
164 }
165 if (!Length()) {
166 EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1);
167 SetBuffer(ldef,ktmp);
168 }
169 // Set also the type
170 SetType(cipnam);
171 }
172 // Cleanup
173 delete[] ktmp;
174 }
175 }
176
177 // Finally, generate and set a new IV
178 if (valid)
179 GenerateIV();
180}
virtual int SetBuffer(int l, const char *b)
virtual int Length() const
virtual int SetType(const char *t)
static char * GetBuffer(int len, int opt=-1)

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 183 of file XrdCryptosslCipher.cc.

185{
186 // Constructor.
187 // Initialize a cipher of type t and length l using the key at k and
188 // the initialization vector at iv.
189 // Used to import ciphers.
190 valid = 0;
191 ctx = 0;
192 fIV = 0;
193 lIV = 0;
194 fDH = 0;
195 cipher = 0;
196 deflength = 1;
197
198 // Check and set type
199 char cipnam[64] = {"bf-cbc"};
200 if (t && strcmp(t,"default")) {
201 strcpy(cipnam,t);
202 cipnam[63] = 0;
203 }
204 cipher = EVP_get_cipherbyname(cipnam);
205
206 if (cipher) {
207 // Init context
208 ctx = EVP_CIPHER_CTX_new();
209 if (ctx) {
210 // Set the key
211 SetBuffer(l,k);
212 if (l != EVP_CIPHER_key_length(cipher))
213 deflength = 0;
214 // Set also the type
215 SetType(cipnam);
216 // Set validity flag
217 valid = 1;
218 }
219 }
220 //
221 // Init cipher
222 if (valid) {
223 //
224 // Set the IV
225 SetIV(liv,iv);
226
227 if (deflength) {
228 EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)Buffer(), 0, 1);
229 } else {
230 EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
231 EVP_CIPHER_CTX_set_key_length(ctx,Length());
232 EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)Buffer(), 0, 1);
233 }
234 }
235}
virtual char * Buffer() const
void SetIV(int l, const char *iv)

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 238 of file XrdCryptosslCipher.cc.

239{
240 // Constructor from bucket.
241 // Initialize a cipher of type t and length l using the key at k
242 // Used to import ciphers.
243 valid = 0;
244 ctx = 0;
245 fIV = 0;
246 lIV = 0;
247 fDH = 0;
248 cipher = 0;
249 deflength = 1;
250
251 if (bck && bck->size > 0) {
252
253 valid = 1;
254
255 kXR_int32 ltyp = 0;
256 kXR_int32 livc = 0;
257 kXR_int32 lbuf = 0;
258 kXR_int32 lp = 0;
259 kXR_int32 lg = 0;
260 kXR_int32 lpub = 0;
261 kXR_int32 lpri = 0;
262 char *bp = bck->buffer;
263 int cur = 0;
264 memcpy(&ltyp,bp+cur,sizeof(kXR_int32));
265 cur += sizeof(kXR_int32);
266 memcpy(&livc,bp+cur,sizeof(kXR_int32));
267 cur += sizeof(kXR_int32);
268 memcpy(&lbuf,bp+cur,sizeof(kXR_int32));
269 cur += sizeof(kXR_int32);
270 memcpy(&lp,bp+cur,sizeof(kXR_int32));
271 cur += sizeof(kXR_int32);
272 memcpy(&lg,bp+cur,sizeof(kXR_int32));
273 cur += sizeof(kXR_int32);
274 memcpy(&lpub,bp+cur,sizeof(kXR_int32));
275 cur += sizeof(kXR_int32);
276 memcpy(&lpri,bp+cur,sizeof(kXR_int32));
277 cur += sizeof(kXR_int32);
278 // Type
279 if (ltyp) {
280 char *buf = new char[ltyp+1];
281 if (buf) {
282 memcpy(buf,bp+cur,ltyp);
283 buf[ltyp] = 0;
284 cipher = EVP_get_cipherbyname(buf);
285 if (!cipher)
286 cipher = EVP_get_cipherbyname("bf-cbc");
287 if (cipher) {
288 // Set the type
289 SetType(buf);
290 } else {
291 valid = 0;
292 }
293 delete[] buf;
294 } else
295 valid = 0;
296 cur += ltyp;
297 }
298 // IV
299 if (livc) {
300 char *buf = new char[livc];
301 if (buf) {
302 memcpy(buf,bp+cur,livc);
303 cur += livc;
304 // Set the IV
305 SetIV(livc,buf);
306 delete[] buf;
307 } else
308 valid = 0;
309 cur += livc;
310 }
311 // buffer
312 if (lbuf) {
313 char *buf = new char[lbuf];
314 if (buf) {
315 memcpy(buf,bp+cur,lbuf);
316 // Set the buffer
317 UseBuffer(lbuf,buf);
318 if (cipher && lbuf != EVP_CIPHER_key_length(cipher))
319 deflength = 0;
320 } else
321 valid = 0;
322 cur += lbuf;
323 }
324 // DH, if any
325 if (lp > 0 || lg > 0 || lpub > 0 || lpri > 0) {
326 char *buf = 0;
327 BIGNUM *p = NULL, *g = NULL;
328 BIGNUM *pub = NULL, *pri = NULL;
329 // p
330 if (lp > 0) {
331 buf = new char[lp+1];
332 if (buf) {
333 memcpy(buf,bp+cur,lp);
334 buf[lp] = 0;
335 BN_hex2bn(&p,buf);
336 delete[] buf;
337 } else
338 valid = 0;
339 cur += lp;
340 }
341 // g
342 if (lg > 0) {
343 buf = new char[lg+1];
344 if (buf) {
345 memcpy(buf,bp+cur,lg);
346 buf[lg] = 0;
347 BN_hex2bn(&g,buf);
348 delete[] buf;
349 } else
350 valid = 0;
351 cur += lg;
352 }
353 // pub_key
354 if (lpub > 0) {
355 buf = new char[lpub+1];
356 if (buf) {
357 memcpy(buf,bp+cur,lpub);
358 buf[lpub] = 0;
359 BN_hex2bn(&pub,buf);
360 delete[] buf;
361 } else
362 valid = 0;
363 cur += lpub;
364 }
365 // priv_key
366 if (lpri > 0) {
367 buf = new char[lpri+1];
368 if (buf) {
369 memcpy(buf,bp+cur,lpri);
370 buf[lpri] = 0;
371 BN_hex2bn(&pri,buf);
372 delete[] buf;
373 } else
374 valid = 0;
375 cur += lpri;
376 }
377#if OPENSSL_VERSION_NUMBER >= 0x30000000L
378 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
379 if (p) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p);
380 if (g) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g);
381 if (pub) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub);
382 if (pri) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, pri);
383 OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld);
384 OSSL_PARAM_BLD_free(bld);
385 if (p) BN_free(p);
386 if (g) BN_free(g);
387 if (pub) BN_free(pub);
388 if (pri) BN_free(pri);
389 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
390 EVP_PKEY_fromdata_init(pkctx);
391 EVP_PKEY_fromdata(pkctx, &fDH, EVP_PKEY_KEYPAIR, params);
392 EVP_PKEY_CTX_free(pkctx);
393 OSSL_PARAM_free(params);
394#else
395 DH* dh = DH_new();
396 DH_set0_pqg(dh, p, NULL, g);
397 DH_set0_key(dh, pub, pri);
398 fDH = EVP_PKEY_new();
399 EVP_PKEY_assign_DH(fDH, dh);
400#endif
401 if (XrdCheckDH(fDH) != 1)
402 valid = 0;
403 }
404 }
405 //
406 // Init cipher
407 if (valid) {
408 // Init context
409 ctx = EVP_CIPHER_CTX_new();
410 if (ctx) {
411 if (deflength) {
412 EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)Buffer(), 0, 1);
413 } else {
414 EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
415 EVP_CIPHER_CTX_set_key_length(ctx,Length());
416 EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)Buffer(), 0, 1);
417 }
418 } else
419 valid = 0;
420 }
421 if (!valid) {
422 Cleanup();
423 }
424}
int kXR_int32
Definition XPtypes.hh:89
static int XrdCheckDH(EVP_PKEY *pkey)
virtual void UseBuffer(int l, const char *b)

References XrdCryptoBasic::Buffer(), XrdSutBucket::buffer, Cleanup(), 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 427 of file XrdCryptosslCipher.cc.

429{
430 // Constructor for key agreement.
431 // If pub is not defined, generates a DH full key,
432 // the public part and parameters can be retrieved using Public().
433 // 'bits' is ignored (DH key is generated once)
434 // If pub is defined with the public part and parameters of the
435 // counterpart fully initialize a cipher with that information.
436 // Sets also the name to 't', if different from the default one.
437 // Used for key agreement.
438 EPNAME("sslCipher::XrdCryptosslCipher");
439
440 valid = 0;
441 ctx = 0;
442 fIV = 0;
443 lIV = 0;
444 fDH = 0;
445 cipher = 0;
446 deflength = 1;
447
448 if (!pub) {
449
450 DEBUG("generate DH parameters");
451 EVP_PKEY *dhparms = getFixedDHParams();
452//
453// Important historical context:
454// - We used to generate DH params on every server startup (commented
455// out below). This was prohibitively costly to do on startup for
456// DH parameters large enough to be considered secure.
457// - OpenSSL 3.0 improved the DH parameter generation to avoid leaking
458// the first bit of the session key (see https://github.com/openssl/openssl/issues/9792
459// for more information). However, a side-effect is that the new
460// parameters are not recognized as valid in OpenSSL 1.0.2.
461// - Since we can't control old client versions and new servers can't
462// generate compatible DH parameters, we switch to a fixed, much stronger
463// set of DH parameters (3072 bits).
464//
465// The impact is that we continue leaking the first bit of the session key
466// (meaning it's effectively 127 bits not 128 bits -- still plenty secure)
467// but upgrade the DH parameters to something more modern (3072; previously,
468// it was 512 bits which was not considered secure). The downside
469// of fixed DH parameters is that if a nation-state attacked our selected
470// parameters (using technology not currently available), we would have
471// to upgrade all servers with a new set of DH parameters.
472//
473
474/*
475 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
476 EVP_PKEY_paramgen_init(pkctx);
477 EVP_PKEY_CTX_set_dh_paramgen_prime_len(pkctx, kDHMINBITS);
478 EVP_PKEY_CTX_set_dh_paramgen_generator(pkctx, 5);
479 EVP_PKEY_paramgen(pkctx, &dhParam);
480 EVP_PKEY_CTX_free(pkctx);
481*/
482
483 DEBUG("configure DH parameters");
484 //
485 // Set params for DH object
486 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new(dhparms, 0);
487 EVP_PKEY_keygen_init(pkctx);
488 EVP_PKEY_keygen(pkctx, &fDH);
489 EVP_PKEY_CTX_free(pkctx);
490 if (fDH) {
491 // Init context
492 ctx = EVP_CIPHER_CTX_new();
493 if (ctx)
494 valid = 1;
495 }
496
497 } else {
498 DEBUG("initialize cipher from key-agreement buffer");
499 //
500 char *ktmp = 0;
501 size_t ltmp = 0;
502 // Extract string with bignumber
503 BIGNUM *bnpub = 0;
504 char *pb = strstr(pub,"---BPUB---");
505 char *pe = strstr(pub,"---EPUB--"); // one less (pub not null-terminated)
506 if (pb && pe) {
507 lpub = (int)(pb-pub);
508 pb += 10;
509 *pe = 0;
510 BN_hex2bn(&bnpub, pb);
511 *pe = '-';
512 }
513 if (bnpub) {
514 //
515 // Prepare to decode the input buffer
516 BIO *biop = BIO_new(BIO_s_mem());
517 if (biop) {
518 //
519 // Write buffer into BIO
520 BIO_write(biop,pub,lpub);
521 //
522 // Read params from BIO
523 EVP_PKEY *dhParam = 0;
524 PEM_read_bio_Parameters(biop, &dhParam);
525 if (dhParam) {
526 if (XrdCheckDH(dhParam) == 1) {
527 //
528 // generate DH key
529 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new(dhParam, 0);
530 EVP_PKEY_keygen_init(pkctx);
531 EVP_PKEY_keygen(pkctx, &fDH);
532 EVP_PKEY_CTX_free(pkctx);
533 if (fDH) {
534 // Now we can compute the cipher
535 ltmp = EVP_PKEY_size(fDH);
536 ktmp = new char[ltmp];
537 memset(ktmp, 0, ltmp);
538 if (ktmp) {
539 // Create peer public key
540#if OPENSSL_VERSION_NUMBER >= 0x30000000L
541 EVP_PKEY *peer = 0;
542 OSSL_PARAM *params1 = 0;
543 EVP_PKEY_todata( dhParam, EVP_PKEY_KEY_PARAMETERS, &params1 );
544 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
545 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, bnpub);
546 OSSL_PARAM *params2 = OSSL_PARAM_BLD_to_param(bld);
547 OSSL_PARAM_BLD_free(bld);
548 OSSL_PARAM *params = OSSL_PARAM_merge( params1, params2 );
549 pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
550 EVP_PKEY_fromdata_init(pkctx);
551 EVP_PKEY_fromdata(pkctx, &peer, EVP_PKEY_KEYPAIR, params);
552 EVP_PKEY_CTX_free(pkctx);
553 OSSL_PARAM_free(params);
554 OSSL_PARAM_free(params1);
555 OSSL_PARAM_free(params2);
556#else
557 DH* dh = DH_new();
558 DH_set0_key(dh, BN_dup(bnpub), NULL);
559 EVP_PKEY *peer = EVP_PKEY_new();
560 EVP_PKEY_assign_DH(peer, dh);
561#endif
562 // Derive shared secret
563 pkctx = EVP_PKEY_CTX_new(fDH, 0);
564 EVP_PKEY_derive_init(pkctx);
565 EVP_PKEY_CTX_set_dh_pad(pkctx, padded);
566 EVP_PKEY_derive_set_peer(pkctx, peer);
567 EVP_PKEY_derive(pkctx, (unsigned char *)ktmp, &ltmp);
568 EVP_PKEY_CTX_free(pkctx);
569 EVP_PKEY_free(peer);
570 if (ltmp > 0) {
571 valid = 1;
572 }
573 }
574 }
575 }
576 EVP_PKEY_free(dhParam);
577 }
578 BIO_free(biop);
579 }
580 BN_free( bnpub );
581 }
582 //
583 // If a valid key has been computed, set the cipher
584 if (valid) {
585 // Init context
586 ctx = EVP_CIPHER_CTX_new();
587 if (ctx) {
588 // Check and set type
589 char cipnam[64] = {"bf-cbc"};
590 if (t && strcmp(t,"default")) {
591 strcpy(cipnam,t);
592 cipnam[63] = 0;
593 }
594 if ((cipher = EVP_get_cipherbyname(cipnam))) {
595 // At most EVP_MAX_KEY_LENGTH bytes
596 ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp;
597 int ldef = EVP_CIPHER_key_length(cipher);
598 // Try setting the key length
599 if ((int)ltmp != ldef) {
600 EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
601 EVP_CIPHER_CTX_set_key_length(ctx,ltmp);
602 EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1);
603 if ((int)ltmp == EVP_CIPHER_CTX_key_length(ctx)) {
604 // Use the ltmp bytes at ktmp
605 SetBuffer(ltmp,ktmp);
606 deflength = 0;
607 }
608 }
609 if (!Length()) {
610 EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1);
611 SetBuffer(ldef,ktmp);
612 }
613 // Set also the type
614 SetType(cipnam);
615 }
616 } else
617 valid = 0;
618 }
619 // Cleanup
620 if (ktmp) {delete[] ktmp; ktmp = 0;}
621 }
622
623 // Cleanup, if invalid
624 if (!valid)
625 Cleanup();
626}
#define DEBUG(x)
#define EPNAME(x)
static EVP_PKEY * getFixedDHParams()

References Cleanup(), DEBUG, 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 629 of file XrdCryptosslCipher.cc.

631{
632 // Copy Constructor
633
634 // Basics
635 deflength = c.deflength;
636 valid = c.valid;
637 ctx = 0;
638 // IV
639 lIV = 0;
640 fIV = 0;
641 SetIV(c.lIV,c.fIV);
642
643 // Cipher
644 cipher = c.cipher;
645 // Set the key
646 SetBuffer(c.Length(),c.Buffer());
647 // Set also the type
648 SetType(c.Type());
649 // DH
650 fDH = 0;
651 if (valid && c.fDH) {
652 valid = 0;
653#if OPENSSL_VERSION_NUMBER >= 0x30000000L
654 BIGNUM *p = BN_new();
655 BIGNUM *g = BN_new();
656 BIGNUM *pub = BN_new();
657 BIGNUM *pri = BN_new();
658 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
659 if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_FFC_P, &p) == 1)
660 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p);
661 if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_FFC_G, &g) == 1)
662 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g);
663 if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_PUB_KEY, &pub) == 1)
664 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub);
665 if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_PRIV_KEY, &pri) == 1)
666 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, pri);
667 OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld);
668 OSSL_PARAM_BLD_free(bld);
669 BN_free(p);
670 BN_free(g);
671 BN_free(pub);
672 BN_free(pri);
673 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
674 EVP_PKEY_fromdata_init(pkctx);
675 EVP_PKEY_fromdata(pkctx, &fDH, EVP_PKEY_KEYPAIR, params);
676 EVP_PKEY_CTX_free(pkctx);
677 OSSL_PARAM_free(params);
678#else
679 DH* dh = DH_new();
680 if (dh) {
681 const BIGNUM *p, *g;
682 DH_get0_pqg(EVP_PKEY_get0_DH(c.fDH), &p, NULL, &g);
683 DH_set0_pqg(dh, p ? BN_dup(p) : NULL, NULL, g ? BN_dup(g) : NULL);
684 const BIGNUM *pub, *pri;
685 DH_get0_key(EVP_PKEY_get0_DH(c.fDH), &pub, &pri);
686 DH_set0_key(dh, pub ? BN_dup(pub) : NULL, pri ? BN_dup(pri) : NULL);
687 fDH = EVP_PKEY_new();
688 EVP_PKEY_assign_DH(fDH, dh);
689 }
690#endif
691 if (fDH) {
692 if (XrdCheckDH(fDH) == 1)
693 valid = 1;
694 }
695 }
696 if (valid) {
697 // Init context
698 ctx = EVP_CIPHER_CTX_new();
699 if (!ctx)
700 valid = 0;
701 }
702 if (!valid) {
703 Cleanup();
704 }
705}
virtual char * Type() const

References XrdCryptoCipher::XrdCryptoCipher(), XrdCryptosslCipher(), XrdCryptoBasic::Buffer(), Cleanup(), 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 708 of file XrdCryptosslCipher.cc.

709{
710 // Destructor.
711
712 // Cleanup IV
713 if (fIV)
714 delete[] fIV;
715
716 // Cleanups
717 if (valid)
718 EVP_CIPHER_CTX_free(ctx);
719 Cleanup();
720}

References Cleanup().

Here is the call graph for this function:

Member Function Documentation

◆ AsBucket()

XrdSutBucket * XrdCryptosslCipher::AsBucket ( )
virtual

Reimplemented from XrdCryptoCipher.

Definition at line 988 of file XrdCryptosslCipher.cc.

989{
990 // Return pointer to a bucket created using the internal information
991 // serialized
992 // The bucket is responsible for the allocated memory
993
994 XrdSutBucket *buck = (XrdSutBucket *)0;
995
996 if (valid) {
997
998 // Serialize .. total length
999 kXR_int32 lbuf = Length();
1000 kXR_int32 ltyp = Type() ? strlen(Type()) : 0;
1001 kXR_int32 livc = lIV;
1002#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1003 BIGNUM *p = BN_new();
1004 BIGNUM *g = BN_new();
1005 BIGNUM *pub = BN_new();
1006 BIGNUM *pri = BN_new();
1007 EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_FFC_P, &p);
1008 EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_FFC_G, &g);
1009 EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_PUB_KEY, &pub);
1010 EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_PRIV_KEY, &pri);
1011#else
1012 const BIGNUM *p, *g;
1013 const BIGNUM *pub, *pri;
1014 DH_get0_pqg(EVP_PKEY_get0_DH(fDH), &p, NULL, &g);
1015 DH_get0_key(EVP_PKEY_get0_DH(fDH), &pub, &pri);
1016#endif
1017 char *cp = BN_bn2hex(p);
1018 char *cg = BN_bn2hex(g);
1019 char *cpub = BN_bn2hex(pub);
1020 char *cpri = BN_bn2hex(pri);
1021#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1022 BN_free(p);
1023 BN_free(g);
1024 BN_free(pub);
1025 BN_free(pri);
1026#endif
1027 kXR_int32 lp = cp ? strlen(cp) : 0;
1028 kXR_int32 lg = cg ? strlen(cg) : 0;
1029 kXR_int32 lpub = cpub ? strlen(cpub) : 0;
1030 kXR_int32 lpri = cpri ? strlen(cpri) : 0;
1031 int ltot = 7*sizeof(kXR_int32) + ltyp + Length() + livc +
1032 lp + lg + lpub + lpri;
1033 char *newbuf = new char[ltot];
1034 if (newbuf) {
1035 int cur = 0;
1036 memcpy(newbuf+cur,&ltyp,sizeof(kXR_int32));
1037 cur += sizeof(kXR_int32);
1038 memcpy(newbuf+cur,&livc,sizeof(kXR_int32));
1039 cur += sizeof(kXR_int32);
1040 memcpy(newbuf+cur,&lbuf,sizeof(kXR_int32));
1041 cur += sizeof(kXR_int32);
1042 memcpy(newbuf+cur,&lp,sizeof(kXR_int32));
1043 cur += sizeof(kXR_int32);
1044 memcpy(newbuf+cur,&lg,sizeof(kXR_int32));
1045 cur += sizeof(kXR_int32);
1046 memcpy(newbuf+cur,&lpub,sizeof(kXR_int32));
1047 cur += sizeof(kXR_int32);
1048 memcpy(newbuf+cur,&lpri,sizeof(kXR_int32));
1049 cur += sizeof(kXR_int32);
1050 if (Type()) {
1051 memcpy(newbuf+cur,Type(),ltyp);
1052 cur += ltyp;
1053 }
1054 if (fIV) {
1055 memcpy(newbuf+cur,fIV,livc);
1056 cur += livc;
1057 }
1058 if (Buffer()) {
1059 memcpy(newbuf+cur,Buffer(),lbuf);
1060 cur += lbuf;
1061 }
1062 if (cp) {
1063 memcpy(newbuf+cur,cp,lp);
1064 cur += lp;
1065 OPENSSL_free(cp);
1066 }
1067 if (cg) {
1068 memcpy(newbuf+cur,cg,lg);
1069 cur += lg;
1070 OPENSSL_free(cg);
1071 }
1072 if (cpub) {
1073 memcpy(newbuf+cur,cpub,lpub);
1074 cur += lpub;
1075 OPENSSL_free(cpub);
1076 }
1077 if (cpri) {
1078 memcpy(newbuf+cur,cpri,lpri);
1079 cur += lpri;
1080 OPENSSL_free(cpri);
1081 }
1082 // The bucket now
1083 buck = new XrdSutBucket(newbuf,ltot,kXRS_cipher);
1084 }
1085 }
1086
1087 return buck;
1088}
@ kXRS_cipher
Definition XrdSutAux.hh:62

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

Here is the call graph for this function:

◆ Cleanup()

void XrdCryptosslCipher::Cleanup ( )

Definition at line 723 of file XrdCryptosslCipher.cc.

724{
725 // Cleanup temporary memory
726
727 // Cleanup IV
728 if (fDH) {
729 EVP_PKEY_free(fDH);
730 fDH = 0;
731 }
732}

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 1243 of file XrdCryptosslCipher.cc.

1244{
1245 // Required buffer size for decrypting l bytes
1246
1247 int lout = l+EVP_CIPHER_CTX_block_size(ctx)+1;
1248 lout = (lout <= 0) ? l : lout;
1249 return lout;
1250}

◆ Decrypt()

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

Reimplemented from XrdCryptoCipher.

Definition at line 1153 of file XrdCryptosslCipher.cc.

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

◆ EncOutLength()

int XrdCryptosslCipher::EncOutLength ( int l)
virtual

Reimplemented from XrdCryptoCipher.

Definition at line 1235 of file XrdCryptosslCipher.cc.

1236{
1237 // Required buffer size for encrypting l bytes
1238
1239 return (l+EVP_CIPHER_CTX_block_size(ctx));
1240}

◆ Encrypt()

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

Reimplemented from XrdCryptoCipher.

Definition at line 1142 of file XrdCryptosslCipher.cc.

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

◆ Finalize()

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

Reimplemented from XrdCryptoCipher.

Definition at line 735 of file XrdCryptosslCipher.cc.

737{
738 // Finalize cipher during key agreement. Should be called
739 // for a cipher build with special constructor defining member fDH.
740 // The buffer pub should contain the public part of the counterpart.
741 // Sets also the name to 't', if different from the default one.
742 // Used for key agreement.
743 EPNAME("sslCipher::Finalize");
744
745 if (!fDH) {
746 DEBUG("DH undefined: this cipher cannot be finalized"
747 " by this method");
748 return 0;
749 }
750
751 char *ktmp = 0;
752 size_t ltmp = 0;
753 valid = 0;
754 if (pub) {
755 //
756 // Extract string with bignumber
757 BIGNUM *bnpub = 0;
758 char *pb = static_cast<char*>(memmem(pub, lpub, "---BPUB---", 10));
759 char *pe = static_cast<char*>(memmem(pub, lpub, "---EPUB--", 9));
760 if (pb && pe) {
761 //lpub = (int)(pb-pub);
762 pb += 10;
763 *pe = 0;
764 BN_hex2bn(&bnpub, pb);
765 *pe = '-';
766 }
767 if (bnpub) {
768 // Now we can compute the cipher
769 ltmp = EVP_PKEY_size(fDH);
770 ktmp = new char[ltmp];
771 if (ktmp) {
772 memset(ktmp, 0, ltmp);
773 // Create peer public key
774 EVP_PKEY_CTX *pkctx;
775#if OPENSSL_VERSION_NUMBER >= 0x30000000L
776 EVP_PKEY *peer = nullptr;
777 OSSL_PARAM *params1 = nullptr;
778 EVP_PKEY_todata(fDH, EVP_PKEY_KEY_PARAMETERS, &params1);
779 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
780 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, bnpub);
781 OSSL_PARAM *params2 = OSSL_PARAM_BLD_to_param(bld);
782 OSSL_PARAM_BLD_free(bld);
783 OSSL_PARAM *params = OSSL_PARAM_merge(params1, params2);
784 pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
785 EVP_PKEY_fromdata_init(pkctx);
786 EVP_PKEY_fromdata(pkctx, &peer, EVP_PKEY_PUBLIC_KEY, params);
787 OSSL_PARAM_free(params1);
788 OSSL_PARAM_free(params2);
789 OSSL_PARAM_free(params);
790 EVP_PKEY_CTX_free(pkctx);
791#else
792 DH* dh = DH_new();
793 DH_set0_key(dh, BN_dup(bnpub), NULL);
794 EVP_PKEY *peer = EVP_PKEY_new();
795 EVP_PKEY_assign_DH(peer, dh);
796#endif
797 // Derive shared secret
798 pkctx = EVP_PKEY_CTX_new(fDH, 0);
799 EVP_PKEY_derive_init(pkctx);
800 EVP_PKEY_CTX_set_dh_pad(pkctx, padded);
801 EVP_PKEY_derive_set_peer(pkctx, peer);
802 EVP_PKEY_derive(pkctx, (unsigned char *)ktmp, &ltmp);
803 EVP_PKEY_CTX_free(pkctx);
804 EVP_PKEY_free(peer);
805 if (ltmp > 0) {
806 valid = 1;
807 }
808 }
809 BN_free(bnpub);
810 bnpub=0;
811 }
812 //
813 // If a valid key has been computed, set the cipher
814 if (valid) {
815 // Check and set type
816 char cipnam[64] = {"bf-cbc"};
817 if (t && strcmp(t,"default")) {
818 strcpy(cipnam,t);
819 cipnam[63] = 0;
820 }
821 if ((cipher = EVP_get_cipherbyname(cipnam))) {
822 // At most EVP_MAX_KEY_LENGTH bytes
823 ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp;
824 int ldef = EVP_CIPHER_key_length(cipher);
825 // Try setting the key length
826 if ((int)ltmp != ldef) {
827 EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
828 EVP_CIPHER_CTX_set_key_length(ctx,ltmp);
829 EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1);
830 if ((int)ltmp == EVP_CIPHER_CTX_key_length(ctx)) {
831 // Use the ltmp bytes at ktmp
832 SetBuffer(ltmp,ktmp);
833 deflength = 0;
834 }
835 }
836 if (!Length()) {
837 EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1);
838 SetBuffer(ldef,ktmp);
839 }
840 // Set also the type
841 SetType(cipnam);
842 }
843 }
844 // Cleanup
845 if (ktmp) {delete[] ktmp; ktmp = 0;}
846 }
847
848 // Cleanup, if invalid
849 if (!valid) {
850 EVP_CIPHER_CTX_free(ctx);
851 Cleanup();
852 }
853
854 // We are done
855 return valid;
856}

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

Here is the call graph for this function:

◆ IsDefaultLength()

bool XrdCryptosslCipher::IsDefaultLength ( ) const
inlinevirtual

Reimplemented from XrdCryptoCipher.

Definition at line 97 of file XrdCryptosslCipher.hh.

97{ return deflength; }

◆ IsSupported()

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

Definition at line 111 of file XrdCryptosslCipher.cc.

112{
113 // Check if the specified cipher is supported
114
115 return (EVP_get_cipherbyname(cip) != 0);
116}

Referenced by XrdCryptosslFactory::SupportedCipher().

Here is the caller graph for this function:

◆ IsValid()

bool XrdCryptosslCipher::IsValid ( )
inlinevirtual

Reimplemented from XrdCryptoCipher.

Definition at line 84 of file XrdCryptosslCipher.hh.

84{ return valid; }

◆ IV()

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

Reimplemented from XrdCryptoCipher.

Definition at line 96 of file XrdCryptosslCipher.hh.

96{ l = lIV; return fIV; }

◆ MaxIVLength()

int XrdCryptosslCipher::MaxIVLength ( ) const
virtual

Reimplemented from XrdCryptoCipher.

Definition at line 1253 of file XrdCryptosslCipher.cc.

1254{
1255 // Return the max cipher IV length
1256
1257 return (lIV > 0) ? lIV : EVP_MAX_IV_LENGTH;
1258}

◆ Public()

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

Reimplemented from XrdCryptoCipher.

Definition at line 877 of file XrdCryptosslCipher.cc.

878{
879 // Return buffer with the public part of the DH key and the shared
880 // parameters; lpub contains the length of the meaningful bytes.
881 // Buffer should be deleted by the caller.
882 static int lhend = strlen("-----END DH PARAMETERS-----");
883
884 if (fDH) {
885 //
886 // Calculate and write public key hex
887#if OPENSSL_VERSION_NUMBER >= 0x30000000L
888 BIGNUM *pub = BN_new();
889 EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_PUB_KEY, &pub);
890 char *phex = BN_bn2hex(pub);
891 BN_free(pub);
892#else
893 const BIGNUM *pub;
894 DH_get0_key(EVP_PKEY_get0_DH(fDH), &pub, NULL);
895 char *phex = BN_bn2hex(pub);
896#endif
897 int lhex = strlen(phex);
898 //
899 // Prepare bio to export info buffer
900 BIO *biop = BIO_new(BIO_s_mem());
901 if (biop) {
902 int ltmp = Publen() + lhex + 20;
903 char *pub = new char[ltmp];
904 if (pub) {
905 // Write parms first
906 PEM_write_bio_Parameters(biop, fDH);
907 // Read key from BIO to buf
908 BIO_read(biop,(void *)pub,ltmp);
909 BIO_free(biop);
910 // Add public key
911 char *p = strstr(pub,"-----END DH PARAMETERS-----");
912 // Buffer length up to now
913 lpub = (int)(p - pub) + lhend + 1;
914 if (phex && p) {
915 // position at the end
916 p += (lhend+1);
917 // Begin of public key hex
918 memcpy(p,"---BPUB---",10);
919 p += 10;
920 // Calculate and write public key hex
921 memcpy(p,phex,lhex);
922 OPENSSL_free(phex);
923 // End of public key hex
924 p += lhex;
925 memcpy(p,"---EPUB---",10);
926 // Calculate total length
927 lpub += (20 + lhex);
928 } else {
929 if (phex) OPENSSL_free(phex);
930 }
931 // return
932 return pub;
933 }
934 } else {
935 if (phex) OPENSSL_free(phex);
936 }
937 }
938
939 lpub = 0;
940 return (char *)0;
941}

◆ RefreshIV()

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

Reimplemented from XrdCryptoCipher.

Definition at line 1111 of file XrdCryptosslCipher.cc.

1112{
1113 // Regenerate IV and return it
1114
1115 // Generate a new IV
1116 GenerateIV();
1117
1118 // Set output
1119 l = lIV;
1120 return fIV;
1121}

◆ SetIV()

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

Reimplemented from XrdCryptoCipher.

Definition at line 1091 of file XrdCryptosslCipher.cc.

1092{
1093 // Set IV from l bytes at iv. If !iv, sets the IV length.
1094
1095 if (fIV) {
1096 delete[] fIV;
1097 fIV = 0;
1098 lIV = 0;
1099 }
1100
1101 if (l > 0) {
1102 if (iv) {
1103 fIV = new char[l];
1104 if (fIV) memcpy(fIV,iv,l);
1105 }
1106 lIV = l;
1107 }
1108}

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: