XRootD
Loading...
Searching...
No Matches
XrdCryptosslCipher.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d C r y p t o S s l C i p h e r . c c */
4/* */
5/* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* Produced by Gerri Ganis for CERN */
7/* */
8/* This file is part of the XRootD software suite. */
9/* */
10/* XRootD is free software: you can redistribute it and/or modify it under */
11/* the terms of the GNU Lesser General Public License as published by the */
12/* Free Software Foundation, either version 3 of the License, or (at your */
13/* option) any later version. */
14/* */
15/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
16/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
17/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
18/* License for more details. */
19/* */
20/* You should have received a copy of the GNU Lesser General Public License */
21/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
22/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
23/* */
24/* The copyright holder's institutional names and contributor's names may not */
25/* be used to endorse or promote products derived from this software without */
26/* specific prior written permission of the institution or contributor. */
27/******************************************************************************/
28
29/* ************************************************************************** */
30/* */
31/* OpenSSL implementation of XrdCryptoCipher */
32/* */
33/* ************************************************************************** */
34#include <cstring>
35#include <cassert>
36
37#include "XrdSut/XrdSutRndm.hh"
40
41//#include <openssl/dsa.h>
42#include <openssl/bio.h>
43#include <openssl/pem.h>
44#include <openssl/dh.h>
45#if OPENSSL_VERSION_NUMBER >= 0x30000000L
46#include <openssl/core_names.h>
47#include <openssl/param_build.h>
48#endif
49
50// Hardcoded DH parameters that are acceptable to both OpenSSL 3.0 (RHEL9)
51// and 1.0.2 (RHEL7). OpenSSL 3.0 reworked the DH parameter generation algorithm
52// and now produces DH params that don't pass OpenSSL 1.0.2's parameter verification
53// function (`DH_check`). Accordingly, since these are safe to reuse, we generated
54// a single set of parameters for the server to always utilize.
55static const char dh_param_enc[] =
56R"(
57-----BEGIN DH PARAMETERS-----
58MIIBiAKCAYEAzcEAf3ZCkm0FxJLgKd1YoT16Hietl7QV8VgJNc5CYKmRu/gKylxT
59MVZJqtUmoh2IvFHCfbTGEmZM5LdVaZfMLQf7yXjecg0nSGklYZeQQ3P0qshFLbI9
60u3z1XhEeCbEZPq84WWwXacSAAxwwRRrN5nshgAavqvyDiGNi+GqYpqGPb9JE38R3
61GJ51FTPutZlvQvEycjCbjyajhpItBB+XvIjWj2GQyvi+cqB0WrPQAsxCOPrBTCZL
62OjM0NfJ7PQfllw3RDQev2u1Q+Rt8QyScJQCFUj/SWoxpw2ydpWdgAkrqTmdVYrev
63x5AoXE52cVIC8wfOxaaJ4cBpnJui3Y0jZcOQj0FtC0wf4WcBpHnLLBzKSOQwbxts
64WE8LkskPnwwrup/HqWimFFg40bC9F5Lm3CTDCb45mtlBxi3DydIbRLFhGAjlKzV3
65s9G3opHwwfgXpFf3+zg7NPV3g1//HLgWCvooOvMqaO+X7+lXczJJLMafEaarcAya
66Kyo8PGKIAORrAgEF
67-----END DH PARAMETERS-----
68)";
69
70// ---------------------------------------------------------------------------//
71//
72// Cipher interface
73//
74// ---------------------------------------------------------------------------//
75
76#if OPENSSL_VERSION_NUMBER < 0x10100000L
77static DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey)
78{
79 if (pkey->type != EVP_PKEY_DH) {
80 return NULL;
81 }
82 return pkey->pkey.dh;
83}
84
85static void DH_get0_pqg(const DH *dh,
86 const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
87{
88 if (p != NULL)
89 *p = dh->p;
90 if (q != NULL)
91 *q = dh->q;
92 if (g != NULL)
93 *g = dh->g;
94}
95
96static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
97{
98 /* If the fields p and g in d are NULL, the corresponding input
99 * parameters MUST be non-NULL. q may remain NULL.
100 */
101 if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL))
102 return 0;
103 if (p != NULL) {
104 BN_free(dh->p);
105 dh->p = p;
106 }
107 if (q != NULL) {
108 BN_free(dh->q);
109 dh->q = q;
110 }
111 if (g != NULL) {
112 BN_free(dh->g);
113 dh->g = g;
114 }
115 if (q != NULL) {
116 dh->length = BN_num_bits(q);
117 }
118 return 1;
119}
120
121static void DH_get0_key(const DH *dh,
122 const BIGNUM **pub_key, const BIGNUM **priv_key)
123{
124 if (pub_key != NULL)
125 *pub_key = dh->pub_key;
126 if (priv_key != NULL)
127 *priv_key = dh->priv_key;
128}
129
130static int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
131{
132 /* If the field pub_key in dh is NULL, the corresponding input
133 * parameters MUST be non-NULL. The priv_key field may
134 * be left NULL.
135 */
136 if (dh->pub_key == NULL && pub_key == NULL)
137 return 0;
138 if (pub_key != NULL) {
139 BN_free(dh->pub_key);
140 dh->pub_key = pub_key;
141 }
142 if (priv_key != NULL) {
143 BN_free(dh->priv_key);
144 dh->priv_key = priv_key;
145 }
146 return 1;
147}
148
149static int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
150{
151 /* If the field pub_key in d is NULL, the corresponding input
152 * parameters MUST be non-NULL. The priv_key field may
153 * be left NULL.
154 */
155 if (d->pub_key == NULL && pub_key == NULL)
156 return 0;
157 if (pub_key != NULL) {
158 BN_free(d->pub_key);
159 d->pub_key = pub_key;
160 }
161 if (priv_key != NULL) {
162 BN_free(d->priv_key);
163 d->priv_key = priv_key;
164 }
165 return 1;
166}
167#endif
168
169static EVP_PKEY *getFixedDHParams() {
170 static EVP_PKEY *dhparms = [] {
171 EVP_PKEY *dhParam = 0;
172
173 BIO *biop = BIO_new(BIO_s_mem());
174 BIO_write(biop, dh_param_enc, strlen(dh_param_enc));
175 PEM_read_bio_Parameters(biop, &dhParam);
176 BIO_free(biop);
177 return dhParam;
178 }();
179
180 assert(dhparms);
181 return dhparms;
182}
183
184static int XrdCheckDH (EVP_PKEY *pkey) {
185 // If the DH parameters we received are our fixed set we know they
186 // are acceptable. The parameter check requires computation and more
187 // with openssl 3 than previously. So skip if DH params are known.
188 const EVP_PKEY *dhparms = getFixedDHParams();
189#if OPENSSL_VERSION_NUMBER >= 0x30000000L
190 const bool skipcheck = EVP_PKEY_parameters_eq(pkey, dhparms);
191#else
192 const bool skipcheck = EVP_PKEY_cmp_parameters(pkey, dhparms);
193#endif
194 if (skipcheck) return 1;
195
196 int rc;
197#if OPENSSL_VERSION_NUMBER < 0x10101000L
198 DH *dh = EVP_PKEY_get0_DH(pkey);
199 if (dh) {
200 DH_check(dh, &rc);
201 rc = (rc == 0 ? 1 : 0);
202 }
203 else {
204 rc = -2;
205 }
206#else
207 EVP_PKEY_CTX *ckctx = EVP_PKEY_CTX_new(pkey, 0);
208 rc = EVP_PKEY_param_check(ckctx);
209 EVP_PKEY_CTX_free(ckctx);
210#endif
211 return rc;
212}
213
214//_____________________________________________________________________________
216{
217 // Check if the specified cipher is supported
218
219 return (EVP_get_cipherbyname(cip) != 0);
220}
221
222//____________________________________________________________________________
224{
225 // Main Constructor
226 // Complete initialization of a cipher of type t and length l
227 // The initialization vector is also created
228 // Used to create ciphers
229
230 valid = 0;
231 ctx = 0;
232 fIV = 0;
233 lIV = 0;
234 cipher = 0;
235 fDH = 0;
236 deflength = 1;
237
238 // Check and set type
239 char cipnam[64] = {"bf-cbc"};
240 if (t && strcmp(t,"default")) {
241 strcpy(cipnam,t);
242 cipnam[63] = 0;
243 }
244 cipher = EVP_get_cipherbyname(cipnam);
245
246 if (cipher) {
247 // Determine key length
248 l = (l > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : l;
249 int ldef = EVP_CIPHER_key_length(cipher);
250 int lgen = (l > ldef) ? l : ldef;
251 // Generate and set a new key
252 char *ktmp = XrdSutRndm::GetBuffer(lgen);
253 if (ktmp) {
254 // Init context
255 ctx = EVP_CIPHER_CTX_new();
256 if (ctx) {
257 valid = 1;
258 // Try setting the key length
259 if (l && l != ldef) {
260 EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
261 EVP_CIPHER_CTX_set_key_length(ctx,l);
262 EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1);
263 if (l == EVP_CIPHER_CTX_key_length(ctx)) {
264 // Use the l bytes at ktmp
265 SetBuffer(l,ktmp);
266 deflength = 0;
267 }
268 }
269 if (!Length()) {
270 EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1);
271 SetBuffer(ldef,ktmp);
272 }
273 // Set also the type
274 SetType(cipnam);
275 }
276 // Cleanup
277 delete[] ktmp;
278 }
279 }
280
281 // Finally, generate and set a new IV
282 if (valid)
283 GenerateIV();
284}
285
286//____________________________________________________________________________
288 const char *k, int liv, const char *iv)
289{
290 // Constructor.
291 // Initialize a cipher of type t and length l using the key at k and
292 // the initialization vector at iv.
293 // Used to import ciphers.
294 valid = 0;
295 ctx = 0;
296 fIV = 0;
297 lIV = 0;
298 fDH = 0;
299 cipher = 0;
300 deflength = 1;
301
302 // Check and set type
303 char cipnam[64] = {"bf-cbc"};
304 if (t && strcmp(t,"default")) {
305 strcpy(cipnam,t);
306 cipnam[63] = 0;
307 }
308 cipher = EVP_get_cipherbyname(cipnam);
309
310 if (cipher) {
311 // Init context
312 ctx = EVP_CIPHER_CTX_new();
313 if (ctx) {
314 // Set the key
315 SetBuffer(l,k);
316 if (l != EVP_CIPHER_key_length(cipher))
317 deflength = 0;
318 // Set also the type
319 SetType(cipnam);
320 // Set validity flag
321 valid = 1;
322 }
323 }
324 //
325 // Init cipher
326 if (valid) {
327 //
328 // Set the IV
329 SetIV(liv,iv);
330
331 if (deflength) {
332 EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)Buffer(), 0, 1);
333 } else {
334 EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
335 EVP_CIPHER_CTX_set_key_length(ctx,Length());
336 EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)Buffer(), 0, 1);
337 }
338 }
339}
340
341//____________________________________________________________________________
343{
344 // Constructor from bucket.
345 // Initialize a cipher of type t and length l using the key at k
346 // Used to import ciphers.
347 valid = 0;
348 ctx = 0;
349 fIV = 0;
350 lIV = 0;
351 fDH = 0;
352 cipher = 0;
353 deflength = 1;
354
355 if (bck && bck->size > 0) {
356
357 valid = 1;
358
359 kXR_int32 ltyp = 0;
360 kXR_int32 livc = 0;
361 kXR_int32 lbuf = 0;
362 kXR_int32 lp = 0;
363 kXR_int32 lg = 0;
364 kXR_int32 lpub = 0;
365 kXR_int32 lpri = 0;
366 char *bp = bck->buffer;
367 int cur = 0;
368 memcpy(&ltyp,bp+cur,sizeof(kXR_int32));
369 cur += sizeof(kXR_int32);
370 memcpy(&livc,bp+cur,sizeof(kXR_int32));
371 cur += sizeof(kXR_int32);
372 memcpy(&lbuf,bp+cur,sizeof(kXR_int32));
373 cur += sizeof(kXR_int32);
374 memcpy(&lp,bp+cur,sizeof(kXR_int32));
375 cur += sizeof(kXR_int32);
376 memcpy(&lg,bp+cur,sizeof(kXR_int32));
377 cur += sizeof(kXR_int32);
378 memcpy(&lpub,bp+cur,sizeof(kXR_int32));
379 cur += sizeof(kXR_int32);
380 memcpy(&lpri,bp+cur,sizeof(kXR_int32));
381 cur += sizeof(kXR_int32);
382 // Type
383 if (ltyp) {
384 char *buf = new char[ltyp+1];
385 if (buf) {
386 memcpy(buf,bp+cur,ltyp);
387 buf[ltyp] = 0;
388 cipher = EVP_get_cipherbyname(buf);
389 if (!cipher)
390 cipher = EVP_get_cipherbyname("bf-cbc");
391 if (cipher) {
392 // Set the type
393 SetType(buf);
394 } else {
395 valid = 0;
396 }
397 delete[] buf;
398 } else
399 valid = 0;
400 cur += ltyp;
401 }
402 // IV
403 if (livc) {
404 char *buf = new char[livc];
405 if (buf) {
406 memcpy(buf,bp+cur,livc);
407 cur += livc;
408 // Set the IV
409 SetIV(livc,buf);
410 delete[] buf;
411 } else
412 valid = 0;
413 cur += livc;
414 }
415 // buffer
416 if (lbuf) {
417 char *buf = new char[lbuf];
418 if (buf) {
419 memcpy(buf,bp+cur,lbuf);
420 // Set the buffer
421 UseBuffer(lbuf,buf);
422 if (cipher && lbuf != EVP_CIPHER_key_length(cipher))
423 deflength = 0;
424 } else
425 valid = 0;
426 cur += lbuf;
427 }
428 // DH, if any
429 if (lp > 0 || lg > 0 || lpub > 0 || lpri > 0) {
430 char *buf = 0;
431 BIGNUM *p = NULL, *g = NULL;
432 BIGNUM *pub = NULL, *pri = NULL;
433 // p
434 if (lp > 0) {
435 buf = new char[lp+1];
436 if (buf) {
437 memcpy(buf,bp+cur,lp);
438 buf[lp] = 0;
439 BN_hex2bn(&p,buf);
440 delete[] buf;
441 } else
442 valid = 0;
443 cur += lp;
444 }
445 // g
446 if (lg > 0) {
447 buf = new char[lg+1];
448 if (buf) {
449 memcpy(buf,bp+cur,lg);
450 buf[lg] = 0;
451 BN_hex2bn(&g,buf);
452 delete[] buf;
453 } else
454 valid = 0;
455 cur += lg;
456 }
457 // pub_key
458 if (lpub > 0) {
459 buf = new char[lpub+1];
460 if (buf) {
461 memcpy(buf,bp+cur,lpub);
462 buf[lpub] = 0;
463 BN_hex2bn(&pub,buf);
464 delete[] buf;
465 } else
466 valid = 0;
467 cur += lpub;
468 }
469 // priv_key
470 if (lpri > 0) {
471 buf = new char[lpri+1];
472 if (buf) {
473 memcpy(buf,bp+cur,lpri);
474 buf[lpri] = 0;
475 BN_hex2bn(&pri,buf);
476 delete[] buf;
477 } else
478 valid = 0;
479 cur += lpri;
480 }
481#if OPENSSL_VERSION_NUMBER >= 0x30000000L
482 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
483 if (p) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p);
484 if (g) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g);
485 if (pub) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub);
486 if (pri) OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, pri);
487 OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld);
488 OSSL_PARAM_BLD_free(bld);
489 if (p) BN_free(p);
490 if (g) BN_free(g);
491 if (pub) BN_free(pub);
492 if (pri) BN_free(pri);
493 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
494 EVP_PKEY_fromdata_init(pkctx);
495 EVP_PKEY_fromdata(pkctx, &fDH, EVP_PKEY_KEYPAIR, params);
496 EVP_PKEY_CTX_free(pkctx);
497 OSSL_PARAM_free(params);
498#else
499 DH* dh = DH_new();
500 DH_set0_pqg(dh, p, NULL, g);
501 DH_set0_key(dh, pub, pri);
502 fDH = EVP_PKEY_new();
503 EVP_PKEY_assign_DH(fDH, dh);
504#endif
505 if (XrdCheckDH(fDH) != 1)
506 valid = 0;
507 }
508 }
509 //
510 // Init cipher
511 if (valid) {
512 // Init context
513 ctx = EVP_CIPHER_CTX_new();
514 if (ctx) {
515 if (deflength) {
516 EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)Buffer(), 0, 1);
517 } else {
518 EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
519 EVP_CIPHER_CTX_set_key_length(ctx,Length());
520 EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)Buffer(), 0, 1);
521 }
522 } else
523 valid = 0;
524 }
525 if (!valid) {
526 Cleanup();
527 }
528}
529
530//____________________________________________________________________________
531XrdCryptosslCipher::XrdCryptosslCipher(bool padded, int bits, char *pub,
532 int lpub, const char *t)
533{
534 // Constructor for key agreement.
535 // If pub is not defined, generates a DH full key,
536 // the public part and parameters can be retrieved using Public().
537 // 'bits' is ignored (DH key is generated once)
538 // If pub is defined with the public part and parameters of the
539 // counterpart fully initialize a cipher with that information.
540 // Sets also the name to 't', if different from the default one.
541 // Used for key agreement.
542 EPNAME("sslCipher::XrdCryptosslCipher");
543
544 valid = 0;
545 ctx = 0;
546 fIV = 0;
547 lIV = 0;
548 fDH = 0;
549 cipher = 0;
550 deflength = 1;
551
552 if (!pub) {
553
554 DEBUG("generate DH parameters");
555 EVP_PKEY *dhparms = getFixedDHParams();
556//
557// Important historical context:
558// - We used to generate DH params on every server startup (commented
559// out below). This was prohibitively costly to do on startup for
560// DH parameters large enough to be considered secure.
561// - OpenSSL 3.0 improved the DH parameter generation to avoid leaking
562// the first bit of the session key (see https://github.com/openssl/openssl/issues/9792
563// for more information). However, a side-effect is that the new
564// parameters are not recognized as valid in OpenSSL 1.0.2.
565// - Since we can't control old client versions and new servers can't
566// generate compatible DH parameters, we switch to a fixed, much stronger
567// set of DH parameters (3072 bits).
568//
569// The impact is that we continue leaking the first bit of the session key
570// (meaning it's effectively 127 bits not 128 bits -- still plenty secure)
571// but upgrade the DH parameters to something more modern (3072; previously,
572// it was 512 bits which was not considered secure). The downside
573// of fixed DH parameters is that if a nation-state attacked our selected
574// parameters (using technology not currently available), we would have
575// to upgrade all servers with a new set of DH parameters.
576//
577
578/*
579 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
580 EVP_PKEY_paramgen_init(pkctx);
581 EVP_PKEY_CTX_set_dh_paramgen_prime_len(pkctx, kDHMINBITS);
582 EVP_PKEY_CTX_set_dh_paramgen_generator(pkctx, 5);
583 EVP_PKEY_paramgen(pkctx, &dhParam);
584 EVP_PKEY_CTX_free(pkctx);
585*/
586
587 DEBUG("configure DH parameters");
588 //
589 // Set params for DH object
590 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new(dhparms, 0);
591 EVP_PKEY_keygen_init(pkctx);
592 EVP_PKEY_keygen(pkctx, &fDH);
593 EVP_PKEY_CTX_free(pkctx);
594 if (fDH) {
595 // Init context
596 ctx = EVP_CIPHER_CTX_new();
597 if (ctx)
598 valid = 1;
599 }
600
601 } else {
602 DEBUG("initialize cipher from key-agreement buffer");
603 //
604 char *ktmp = 0;
605 size_t ltmp = 0;
606 // Extract string with bignumber
607 BIGNUM *bnpub = 0;
608 char *pb = strstr(pub,"---BPUB---");
609 char *pe = strstr(pub,"---EPUB--"); // one less (pub not null-terminated)
610 if (pb && pe) {
611 lpub = (int)(pb-pub);
612 pb += 10;
613 *pe = 0;
614 BN_hex2bn(&bnpub, pb);
615 *pe = '-';
616 }
617 if (bnpub) {
618 //
619 // Prepare to decode the input buffer
620 BIO *biop = BIO_new(BIO_s_mem());
621 if (biop) {
622 //
623 // Write buffer into BIO
624 BIO_write(biop,pub,lpub);
625 //
626 // Read params from BIO
627 EVP_PKEY *dhParam = 0;
628 PEM_read_bio_Parameters(biop, &dhParam);
629 if (dhParam) {
630 if (XrdCheckDH(dhParam) == 1) {
631 //
632 // generate DH key
633 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new(dhParam, 0);
634 EVP_PKEY_keygen_init(pkctx);
635 EVP_PKEY_keygen(pkctx, &fDH);
636 EVP_PKEY_CTX_free(pkctx);
637 if (fDH) {
638 // Now we can compute the cipher
639 ltmp = EVP_PKEY_size(fDH);
640 ktmp = new char[ltmp];
641 memset(ktmp, 0, ltmp);
642 if (ktmp) {
643 // Create peer public key
644#if OPENSSL_VERSION_NUMBER >= 0x30000000L
645 EVP_PKEY *peer = 0;
646 OSSL_PARAM *params1 = 0;
647 EVP_PKEY_todata( dhParam, EVP_PKEY_KEY_PARAMETERS, &params1 );
648 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
649 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, bnpub);
650 OSSL_PARAM *params2 = OSSL_PARAM_BLD_to_param(bld);
651 OSSL_PARAM_BLD_free(bld);
652 OSSL_PARAM *params = OSSL_PARAM_merge( params1, params2 );
653 pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
654 EVP_PKEY_fromdata_init(pkctx);
655 EVP_PKEY_fromdata(pkctx, &peer, EVP_PKEY_KEYPAIR, params);
656 EVP_PKEY_CTX_free(pkctx);
657 OSSL_PARAM_free(params);
658 OSSL_PARAM_free(params1);
659 OSSL_PARAM_free(params2);
660#else
661 DH* dh = DH_new();
662 DH_set0_key(dh, BN_dup(bnpub), NULL);
663 EVP_PKEY *peer = EVP_PKEY_new();
664 EVP_PKEY_assign_DH(peer, dh);
665#endif
666 // Derive shared secret
667 pkctx = EVP_PKEY_CTX_new(fDH, 0);
668 EVP_PKEY_derive_init(pkctx);
669#if OPENSSL_VERSION_NUMBER >= 0x10101000L
670 EVP_PKEY_CTX_set_dh_pad(pkctx, padded);
671#endif
672 EVP_PKEY_derive_set_peer(pkctx, peer);
673 EVP_PKEY_derive(pkctx, (unsigned char *)ktmp, &ltmp);
674 EVP_PKEY_CTX_free(pkctx);
675 EVP_PKEY_free(peer);
676 if (ltmp > 0) {
677#if OPENSSL_VERSION_NUMBER < 0x10101000L
678 if (padded) {
679 int pad = EVP_PKEY_size(fDH) - ltmp;
680 if (pad > 0) {
681 memmove(ktmp + pad, ktmp, ltmp);
682 memset(ktmp, 0, pad);
683 ltmp += pad;
684 }
685 }
686#endif
687 valid = 1;
688 }
689 }
690 }
691 }
692 EVP_PKEY_free(dhParam);
693 }
694 BIO_free(biop);
695 }
696 BN_free( bnpub );
697 }
698 //
699 // If a valid key has been computed, set the cipher
700 if (valid) {
701 // Init context
702 ctx = EVP_CIPHER_CTX_new();
703 if (ctx) {
704 // Check and set type
705 char cipnam[64] = {"bf-cbc"};
706 if (t && strcmp(t,"default")) {
707 strcpy(cipnam,t);
708 cipnam[63] = 0;
709 }
710 if ((cipher = EVP_get_cipherbyname(cipnam))) {
711 // At most EVP_MAX_KEY_LENGTH bytes
712 ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp;
713 int ldef = EVP_CIPHER_key_length(cipher);
714 // Try setting the key length
715 if ((int)ltmp != ldef) {
716 EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
717 EVP_CIPHER_CTX_set_key_length(ctx,ltmp);
718 EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1);
719 if ((int)ltmp == EVP_CIPHER_CTX_key_length(ctx)) {
720 // Use the ltmp bytes at ktmp
721 SetBuffer(ltmp,ktmp);
722 deflength = 0;
723 }
724 }
725 if (!Length()) {
726 EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1);
727 SetBuffer(ldef,ktmp);
728 }
729 // Set also the type
730 SetType(cipnam);
731 }
732 } else
733 valid = 0;
734 }
735 // Cleanup
736 if (ktmp) {delete[] ktmp; ktmp = 0;}
737 }
738
739 // Cleanup, if invalid
740 if (!valid)
741 Cleanup();
742}
743
744//____________________________________________________________________________
747{
748 // Copy Constructor
749
750 // Basics
751 deflength = c.deflength;
752 valid = c.valid;
753 ctx = 0;
754 // IV
755 lIV = 0;
756 fIV = 0;
757 SetIV(c.lIV,c.fIV);
758
759 // Cipher
760 cipher = c.cipher;
761 // Set the key
762 SetBuffer(c.Length(),c.Buffer());
763 // Set also the type
764 SetType(c.Type());
765 // DH
766 fDH = 0;
767 if (valid && c.fDH) {
768 valid = 0;
769#if OPENSSL_VERSION_NUMBER >= 0x30000000L
770 BIGNUM *p = BN_new();
771 BIGNUM *g = BN_new();
772 BIGNUM *pub = BN_new();
773 BIGNUM *pri = BN_new();
774 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
775 if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_FFC_P, &p) == 1)
776 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p);
777 if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_FFC_G, &g) == 1)
778 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g);
779 if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_PUB_KEY, &pub) == 1)
780 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub);
781 if (EVP_PKEY_get_bn_param(c.fDH, OSSL_PKEY_PARAM_PRIV_KEY, &pri) == 1)
782 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, pri);
783 OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld);
784 OSSL_PARAM_BLD_free(bld);
785 BN_free(p);
786 BN_free(g);
787 BN_free(pub);
788 BN_free(pri);
789 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
790 EVP_PKEY_fromdata_init(pkctx);
791 EVP_PKEY_fromdata(pkctx, &fDH, EVP_PKEY_KEYPAIR, params);
792 EVP_PKEY_CTX_free(pkctx);
793 OSSL_PARAM_free(params);
794#else
795 DH* dh = DH_new();
796 if (dh) {
797 const BIGNUM *p, *g;
798 DH_get0_pqg(EVP_PKEY_get0_DH(c.fDH), &p, NULL, &g);
799 DH_set0_pqg(dh, p ? BN_dup(p) : NULL, NULL, g ? BN_dup(g) : NULL);
800 const BIGNUM *pub, *pri;
801 DH_get0_key(EVP_PKEY_get0_DH(c.fDH), &pub, &pri);
802 DH_set0_key(dh, pub ? BN_dup(pub) : NULL, pri ? BN_dup(pri) : NULL);
803 fDH = EVP_PKEY_new();
804 EVP_PKEY_assign_DH(fDH, dh);
805 }
806#endif
807 if (fDH) {
808 if (XrdCheckDH(fDH) == 1)
809 valid = 1;
810 }
811 }
812 if (valid) {
813 // Init context
814 ctx = EVP_CIPHER_CTX_new();
815 if (!ctx)
816 valid = 0;
817 }
818 if (!valid) {
819 Cleanup();
820 }
821}
822
823//____________________________________________________________________________
825{
826 // Destructor.
827
828 // Cleanup IV
829 if (fIV)
830 delete[] fIV;
831
832 // Cleanups
833 if (valid)
834 EVP_CIPHER_CTX_free(ctx);
835 Cleanup();
836}
837
838//____________________________________________________________________________
840{
841 // Cleanup temporary memory
842
843 // Cleanup IV
844 if (fDH) {
845 EVP_PKEY_free(fDH);
846 fDH = 0;
847 }
848}
849
850//____________________________________________________________________________
852 char *pub, int lpub, const char *t)
853{
854 // Finalize cipher during key agreement. Should be called
855 // for a cipher build with special constructor defining member fDH.
856 // The buffer pub should contain the public part of the counterpart.
857 // Sets also the name to 't', if different from the default one.
858 // Used for key agreement.
859 EPNAME("sslCipher::Finalize");
860
861 if (!fDH) {
862 DEBUG("DH undefined: this cipher cannot be finalized"
863 " by this method");
864 return 0;
865 }
866
867 char *ktmp = 0;
868 size_t ltmp = 0;
869 valid = 0;
870 if (pub) {
871 //
872 // Extract string with bignumber
873 BIGNUM *bnpub = 0;
874 char *pb = static_cast<char*>(memmem(pub, lpub, "---BPUB---", 10));
875 char *pe = static_cast<char*>(memmem(pub, lpub, "---EPUB--", 9));
876 if (pb && pe) {
877 //lpub = (int)(pb-pub);
878 pb += 10;
879 *pe = 0;
880 BN_hex2bn(&bnpub, pb);
881 *pe = '-';
882 }
883 if (bnpub) {
884 // Now we can compute the cipher
885 ltmp = EVP_PKEY_size(fDH);
886 ktmp = new char[ltmp];
887 if (ktmp) {
888 memset(ktmp, 0, ltmp);
889 // Create peer public key
890 EVP_PKEY_CTX *pkctx;
891#if OPENSSL_VERSION_NUMBER >= 0x30000000L
892 EVP_PKEY *peer = nullptr;
893 OSSL_PARAM *params1 = nullptr;
894 EVP_PKEY_todata(fDH, EVP_PKEY_KEY_PARAMETERS, &params1);
895 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
896 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, bnpub);
897 OSSL_PARAM *params2 = OSSL_PARAM_BLD_to_param(bld);
898 OSSL_PARAM_BLD_free(bld);
899 OSSL_PARAM *params = OSSL_PARAM_merge(params1, params2);
900 pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
901 EVP_PKEY_fromdata_init(pkctx);
902 EVP_PKEY_fromdata(pkctx, &peer, EVP_PKEY_PUBLIC_KEY, params);
903 OSSL_PARAM_free(params1);
904 OSSL_PARAM_free(params2);
905 OSSL_PARAM_free(params);
906 EVP_PKEY_CTX_free(pkctx);
907#else
908 DH* dh = DH_new();
909 DH_set0_key(dh, BN_dup(bnpub), NULL);
910 EVP_PKEY *peer = EVP_PKEY_new();
911 EVP_PKEY_assign_DH(peer, dh);
912#endif
913 // Derive shared secret
914 pkctx = EVP_PKEY_CTX_new(fDH, 0);
915 EVP_PKEY_derive_init(pkctx);
916#if OPENSSL_VERSION_NUMBER >= 0x10101000L
917 EVP_PKEY_CTX_set_dh_pad(pkctx, padded);
918#endif
919 EVP_PKEY_derive_set_peer(pkctx, peer);
920 EVP_PKEY_derive(pkctx, (unsigned char *)ktmp, &ltmp);
921 EVP_PKEY_CTX_free(pkctx);
922 EVP_PKEY_free(peer);
923 if (ltmp > 0) {
924#if OPENSSL_VERSION_NUMBER < 0x10101000L
925 if (padded) {
926 int pad = EVP_PKEY_size(fDH) - ltmp;
927 if (pad > 0) {
928 memmove(ktmp + pad, ktmp, ltmp);
929 memset(ktmp, 0, pad);
930 ltmp += pad;
931 }
932 }
933#endif
934 valid = 1;
935 }
936 }
937 BN_free(bnpub);
938 bnpub=0;
939 }
940 //
941 // If a valid key has been computed, set the cipher
942 if (valid) {
943 // Check and set type
944 char cipnam[64] = {"bf-cbc"};
945 if (t && strcmp(t,"default")) {
946 strcpy(cipnam,t);
947 cipnam[63] = 0;
948 }
949 if ((cipher = EVP_get_cipherbyname(cipnam))) {
950 // At most EVP_MAX_KEY_LENGTH bytes
951 ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp;
952 int ldef = EVP_CIPHER_key_length(cipher);
953 // Try setting the key length
954 if ((int)ltmp != ldef) {
955 EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, 1);
956 EVP_CIPHER_CTX_set_key_length(ctx,ltmp);
957 EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)ktmp, 0, 1);
958 if ((int)ltmp == EVP_CIPHER_CTX_key_length(ctx)) {
959 // Use the ltmp bytes at ktmp
960 SetBuffer(ltmp,ktmp);
961 deflength = 0;
962 }
963 }
964 if (!Length()) {
965 EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)ktmp, 0, 1);
966 SetBuffer(ldef,ktmp);
967 }
968 // Set also the type
969 SetType(cipnam);
970 }
971 }
972 // Cleanup
973 if (ktmp) {delete[] ktmp; ktmp = 0;}
974 }
975
976 // Cleanup, if invalid
977 if (!valid) {
978 EVP_CIPHER_CTX_free(ctx);
979 Cleanup();
980 }
981
982 // We are done
983 return valid;
984}
985
986//_____________________________________________________________________________
987int XrdCryptosslCipher::Publen()
988{
989 // Minimum length of export format of public key
990 static int lhdr = strlen("-----BEGIN DH PARAMETERS-----"
991 "-----END DH PARAMETERS-----") + 3;
992 if (fDH) {
993 // minimum length of the core is 22 bytes
994 int l = 2 * EVP_PKEY_size(fDH);
995 if (l < 22) l = 22;
996 // for headers
997 l += lhdr;
998 // some margin
999 return (l+20);
1000 } else
1001 return 0;
1002}
1003
1004//_____________________________________________________________________________
1006{
1007 // Return buffer with the public part of the DH key and the shared
1008 // parameters; lpub contains the length of the meaningful bytes.
1009 // Buffer should be deleted by the caller.
1010 static int lhend = strlen("-----END DH PARAMETERS-----");
1011
1012 if (fDH) {
1013 //
1014 // Calculate and write public key hex
1015#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1016 BIGNUM *pub = BN_new();
1017 EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_PUB_KEY, &pub);
1018 char *phex = BN_bn2hex(pub);
1019 BN_free(pub);
1020#else
1021 const BIGNUM *pub;
1022 DH_get0_key(EVP_PKEY_get0_DH(fDH), &pub, NULL);
1023 char *phex = BN_bn2hex(pub);
1024#endif
1025 int lhex = strlen(phex);
1026 //
1027 // Prepare bio to export info buffer
1028 BIO *biop = BIO_new(BIO_s_mem());
1029 if (biop) {
1030 int ltmp = Publen() + lhex + 20;
1031 char *pub = new char[ltmp];
1032 if (pub) {
1033 // Write parms first
1034 PEM_write_bio_Parameters(biop, fDH);
1035 // Read key from BIO to buf
1036 BIO_read(biop,(void *)pub,ltmp);
1037 BIO_free(biop);
1038 // Add public key
1039 char *p = strstr(pub,"-----END DH PARAMETERS-----");
1040 // Buffer length up to now
1041 lpub = (int)(p - pub) + lhend + 1;
1042 if (phex && p) {
1043 // position at the end
1044 p += (lhend+1);
1045 // Begin of public key hex
1046 memcpy(p,"---BPUB---",10);
1047 p += 10;
1048 // Calculate and write public key hex
1049 memcpy(p,phex,lhex);
1050 OPENSSL_free(phex);
1051 // End of public key hex
1052 p += lhex;
1053 memcpy(p,"---EPUB---",10);
1054 // Calculate total length
1055 lpub += (20 + lhex);
1056 } else {
1057 if (phex) OPENSSL_free(phex);
1058 }
1059 // return
1060 return pub;
1061 }
1062 } else {
1063 if (phex) OPENSSL_free(phex);
1064 }
1065 }
1066
1067 lpub = 0;
1068 return (char *)0;
1069}
1070
1071//_____________________________________________________________________________
1072void XrdCryptosslCipher::PrintPublic(BIGNUM *pub)
1073{
1074 // Print public part
1075
1076 //
1077 // Prepare bio to export info buffer
1078 BIO *biop = BIO_new(BIO_s_mem());
1079 if (biop) {
1080 // Use a DSA structure to export the public part
1081#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1082 EVP_PKEY *dsa = 0;
1083 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
1084 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub);
1085 OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld);
1086 OSSL_PARAM_BLD_free(bld);
1087 EVP_PKEY_CTX *pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, 0);
1088 EVP_PKEY_fromdata_init(pkctx);
1089 EVP_PKEY_fromdata(pkctx, &dsa, EVP_PKEY_PUBLIC_KEY, params);
1090 EVP_PKEY_CTX_free(pkctx);
1091 OSSL_PARAM_free(params);
1092#else
1093 EVP_PKEY *dsa = EVP_PKEY_new();
1094 DSA *fdsa = DSA_new();
1095 DSA_set0_key(fdsa, BN_dup(pub), NULL);
1096 EVP_PKEY_assign_DSA(dsa, fdsa);
1097#endif
1098 if (dsa) {
1099 // Write public key to BIO
1100 PEM_write_bio_PUBKEY(biop, dsa);
1101 // Read key from BIO to buf
1102 int lpub = Publen();
1103 char *bpub = new char[lpub];
1104 if (bpub) {
1105 BIO_read(biop,(void *)bpub,lpub);
1106 std::cerr << bpub << std::endl;
1107 delete[] bpub;
1108 }
1109 EVP_PKEY_free(dsa);
1110 }
1111 BIO_free(biop);
1112 }
1113}
1114
1115//_____________________________________________________________________________
1117{
1118 // Return pointer to a bucket created using the internal information
1119 // serialized
1120 // The bucket is responsible for the allocated memory
1121
1122 XrdSutBucket *buck = (XrdSutBucket *)0;
1123
1124 if (valid) {
1125
1126 // Serialize .. total length
1127 kXR_int32 lbuf = Length();
1128 kXR_int32 ltyp = Type() ? strlen(Type()) : 0;
1129 kXR_int32 livc = lIV;
1130#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1131 BIGNUM *p = BN_new();
1132 BIGNUM *g = BN_new();
1133 BIGNUM *pub = BN_new();
1134 BIGNUM *pri = BN_new();
1135 EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_FFC_P, &p);
1136 EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_FFC_G, &g);
1137 EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_PUB_KEY, &pub);
1138 EVP_PKEY_get_bn_param(fDH, OSSL_PKEY_PARAM_PRIV_KEY, &pri);
1139#else
1140 const BIGNUM *p, *g;
1141 const BIGNUM *pub, *pri;
1142 DH_get0_pqg(EVP_PKEY_get0_DH(fDH), &p, NULL, &g);
1143 DH_get0_key(EVP_PKEY_get0_DH(fDH), &pub, &pri);
1144#endif
1145 char *cp = BN_bn2hex(p);
1146 char *cg = BN_bn2hex(g);
1147 char *cpub = BN_bn2hex(pub);
1148 char *cpri = BN_bn2hex(pri);
1149#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1150 BN_free(p);
1151 BN_free(g);
1152 BN_free(pub);
1153 BN_free(pri);
1154#endif
1155 kXR_int32 lp = cp ? strlen(cp) : 0;
1156 kXR_int32 lg = cg ? strlen(cg) : 0;
1157 kXR_int32 lpub = cpub ? strlen(cpub) : 0;
1158 kXR_int32 lpri = cpri ? strlen(cpri) : 0;
1159 int ltot = 7*sizeof(kXR_int32) + ltyp + Length() + livc +
1160 lp + lg + lpub + lpri;
1161 char *newbuf = new char[ltot];
1162 if (newbuf) {
1163 int cur = 0;
1164 memcpy(newbuf+cur,&ltyp,sizeof(kXR_int32));
1165 cur += sizeof(kXR_int32);
1166 memcpy(newbuf+cur,&livc,sizeof(kXR_int32));
1167 cur += sizeof(kXR_int32);
1168 memcpy(newbuf+cur,&lbuf,sizeof(kXR_int32));
1169 cur += sizeof(kXR_int32);
1170 memcpy(newbuf+cur,&lp,sizeof(kXR_int32));
1171 cur += sizeof(kXR_int32);
1172 memcpy(newbuf+cur,&lg,sizeof(kXR_int32));
1173 cur += sizeof(kXR_int32);
1174 memcpy(newbuf+cur,&lpub,sizeof(kXR_int32));
1175 cur += sizeof(kXR_int32);
1176 memcpy(newbuf+cur,&lpri,sizeof(kXR_int32));
1177 cur += sizeof(kXR_int32);
1178 if (Type()) {
1179 memcpy(newbuf+cur,Type(),ltyp);
1180 cur += ltyp;
1181 }
1182 if (fIV) {
1183 memcpy(newbuf+cur,fIV,livc);
1184 cur += livc;
1185 }
1186 if (Buffer()) {
1187 memcpy(newbuf+cur,Buffer(),lbuf);
1188 cur += lbuf;
1189 }
1190 if (cp) {
1191 memcpy(newbuf+cur,cp,lp);
1192 cur += lp;
1193 OPENSSL_free(cp);
1194 }
1195 if (cg) {
1196 memcpy(newbuf+cur,cg,lg);
1197 cur += lg;
1198 OPENSSL_free(cg);
1199 }
1200 if (cpub) {
1201 memcpy(newbuf+cur,cpub,lpub);
1202 cur += lpub;
1203 OPENSSL_free(cpub);
1204 }
1205 if (cpri) {
1206 memcpy(newbuf+cur,cpri,lpri);
1207 cur += lpri;
1208 OPENSSL_free(cpri);
1209 }
1210 // The bucket now
1211 buck = new XrdSutBucket(newbuf,ltot,kXRS_cipher);
1212 }
1213 }
1214
1215 return buck;
1216}
1217
1218//____________________________________________________________________________
1219void XrdCryptosslCipher::SetIV(int l, const char *iv)
1220{
1221 // Set IV from l bytes at iv. If !iv, sets the IV length.
1222
1223 if (fIV) {
1224 delete[] fIV;
1225 fIV = 0;
1226 lIV = 0;
1227 }
1228
1229 if (l > 0) {
1230 if (iv) {
1231 fIV = new char[l];
1232 if (fIV) memcpy(fIV,iv,l);
1233 }
1234 lIV = l;
1235 }
1236}
1237
1238//____________________________________________________________________________
1240{
1241 // Regenerate IV and return it
1242
1243 // Generate a new IV
1244 GenerateIV();
1245
1246 // Set output
1247 l = lIV;
1248 return fIV;
1249}
1250
1251//____________________________________________________________________________
1252void XrdCryptosslCipher::GenerateIV()
1253{
1254 // Generate IV
1255
1256 // Cleanup existing one, if any
1257 if (fIV) {
1258 delete[] fIV;
1259 fIV = 0;
1260 lIV = 0;
1261 }
1262
1263 // Generate a new one, using crypt-like chars
1264 fIV = XrdSutRndm::GetBuffer(EVP_MAX_IV_LENGTH, 3);
1265 if (fIV)
1266 lIV = EVP_MAX_IV_LENGTH;
1267}
1268
1269//____________________________________________________________________________
1270int XrdCryptosslCipher::Encrypt(const char *in, int lin, char *out)
1271{
1272 // Encrypt lin bytes at in with local cipher.
1273 // The outbut buffer must be provided by the caller for at least
1274 // EncOutLength(lin) bytes.
1275 // Returns number of meaningful bytes in out, or 0 in case of problems
1276
1277 return EncDec(1, in, lin, out);
1278}
1279
1280//____________________________________________________________________________
1281int XrdCryptosslCipher::Decrypt(const char *in, int lin, char *out)
1282{
1283 // Decrypt lin bytes at in with local cipher.
1284 // The outbut buffer must be provided by the caller for at least
1285 // DecOutLength(lin) bytes.
1286 // Returns number of meaningful bytes in out, or 0 in case of problems
1287
1288 return EncDec(0, in, lin, out);
1289}
1290
1291//____________________________________________________________________________
1292int XrdCryptosslCipher::EncDec(int enc, const char *in, int lin, char *out)
1293{
1294 // Encrypt (enc = 1)/ Decrypt (enc = 0) lin bytes at in with local cipher.
1295 // The outbut buffer must be provided by the caller for at least
1296 // EncOutLength(lin) or DecOutLength(lin) bytes.
1297 // Returns number of meaningful bytes in out, or 0 in case of problems
1298 EPNAME("Cipher::EncDec");
1299
1300 int lout = 0;
1301
1302 const char *action = (enc == 1) ? "encrypting" : "decrypting";
1303
1304 // Check inputs
1305 if (!in || lin <= 0 || !out) {
1306 DEBUG("wrong inputs arguments");
1307 if (!in) DEBUG("in: NULL");
1308 if (lin <= 0) DEBUG("lin: "<<lin);
1309 if (!out) DEBUG("out: NULL");
1310 return 0;
1311 }
1312
1313 // Set iv to the one in use
1314 unsigned char iv[EVP_MAX_IV_LENGTH];
1315 if (fIV) {
1316 memcpy((void *)iv,fIV,EVP_MAX_IV_LENGTH);
1317 } else {
1318 // We use 0's
1319 memset((void *)iv,0,EVP_MAX_IV_LENGTH);
1320 }
1321
1322 // Action depend on the length of the key wrt default length
1323 if (deflength) {
1324 // Init ctx, set key (default length) and set IV
1325 if (!EVP_CipherInit_ex(ctx, cipher, 0, (unsigned char *)Buffer(), iv, enc)) {
1326 DEBUG("error initializing");
1327 return 0;
1328 }
1329 } else {
1330 // Init ctx
1331 if (!EVP_CipherInit_ex(ctx, cipher, 0, 0, 0, enc)) {
1332 DEBUG("error initializing - 1");
1333 return 0;
1334 }
1335 // Set key length
1336 EVP_CIPHER_CTX_set_key_length(ctx,Length());
1337 // Set key and IV
1338 if (!EVP_CipherInit_ex(ctx, 0, 0, (unsigned char *)Buffer(), iv, enc)) {
1339 DEBUG("error initializing - 2");
1340 return 0;
1341 }
1342 }
1343
1344 // Encrypt / Decrypt
1345 int ltmp = 0;
1346 if (!EVP_CipherUpdate(ctx, (unsigned char *)&out[0], &ltmp,
1347 (unsigned char *)in, lin)) {
1348 DEBUG("error " << action);
1349 return 0;
1350 }
1351 lout = ltmp;
1352 if (!EVP_CipherFinal_ex(ctx, (unsigned char *)&out[lout], &ltmp)) {
1353 DEBUG("error finalizing");
1354 return 0;
1355 }
1356
1357 // Results
1358 lout += ltmp;
1359 return lout;
1360}
1361
1362//____________________________________________________________________________
1364{
1365 // Required buffer size for encrypting l bytes
1366
1367 return (l+EVP_CIPHER_CTX_block_size(ctx));
1368}
1369
1370//____________________________________________________________________________
1372{
1373 // Required buffer size for decrypting l bytes
1374
1375 int lout = l+EVP_CIPHER_CTX_block_size(ctx)+1;
1376 lout = (lout <= 0) ? l : lout;
1377 return lout;
1378}
1379
1380//____________________________________________________________________________
1382{
1383 // Return the max cipher IV length
1384
1385 return (lIV > 0) ? lIV : EVP_MAX_IV_LENGTH;
1386}
int kXR_int32
Definition XPtypes.hh:89
#define DEBUG(x)
#define EPNAME(x)
static EVP_PKEY * getFixedDHParams()
static DH * EVP_PKEY_get0_DH(EVP_PKEY *pkey)
static void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
static void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
static const char dh_param_enc[]
static int XrdCheckDH(EVP_PKEY *pkey)
static int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
static int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
@ kXRS_cipher
Definition XrdSutAux.hh:62
virtual char * Type() const
virtual int SetBuffer(int l, const char *b)
virtual int Length() const
virtual char * Buffer() const
virtual int SetType(const char *t)
virtual void UseBuffer(int l, const char *b)
void SetIV(int l, const char *iv)
XrdSutBucket * AsBucket()
int Encrypt(const char *bin, int lin, char *out)
XrdCryptosslCipher(const char *t, int l=0)
static bool IsSupported(const char *cip)
int Decrypt(const char *bin, int lin, char *out)
char * Public(int &lpub)
bool Finalize(bool padded, char *pub, int lpub, const char *t)
kXR_int32 size
static char * GetBuffer(int len, int opt=-1)