XRootD
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.
55 static const char dh_param_enc[] =
56 R"(
57 -----BEGIN DH PARAMETERS-----
58 MIIBiAKCAYEAzcEAf3ZCkm0FxJLgKd1YoT16Hietl7QV8VgJNc5CYKmRu/gKylxT
59 MVZJqtUmoh2IvFHCfbTGEmZM5LdVaZfMLQf7yXjecg0nSGklYZeQQ3P0qshFLbI9
60 u3z1XhEeCbEZPq84WWwXacSAAxwwRRrN5nshgAavqvyDiGNi+GqYpqGPb9JE38R3
61 GJ51FTPutZlvQvEycjCbjyajhpItBB+XvIjWj2GQyvi+cqB0WrPQAsxCOPrBTCZL
62 OjM0NfJ7PQfllw3RDQev2u1Q+Rt8QyScJQCFUj/SWoxpw2ydpWdgAkrqTmdVYrev
63 x5AoXE52cVIC8wfOxaaJ4cBpnJui3Y0jZcOQj0FtC0wf4WcBpHnLLBzKSOQwbxts
64 WE8LkskPnwwrup/HqWimFFg40bC9F5Lm3CTDCb45mtlBxi3DydIbRLFhGAjlKzV3
65 s9G3opHwwfgXpFf3+zg7NPV3g1//HLgWCvooOvMqaO+X7+lXczJJLMafEaarcAya
66 Kyo8PGKIAORrAgEF
67 -----END DH PARAMETERS-----
68 )";
69 
70 // ---------------------------------------------------------------------------//
71 //
72 // Cipher interface
73 //
74 // ---------------------------------------------------------------------------//
75 
76 #if OPENSSL_VERSION_NUMBER < 0x10100000L
77 static 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 
85 static 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 
96 static 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 
121 static 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 
130 static 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 
149 static 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 
169 static 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 
184 static 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 //_____________________________________________________________________________
215 bool XrdCryptosslCipher::IsSupported(const char *cip)
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 //____________________________________________________________________________
531 XrdCryptosslCipher::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 //____________________________________________________________________________
746  : XrdCryptoCipher()
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 //_____________________________________________________________________________
987 int 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 //_____________________________________________________________________________
1072 void 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 //____________________________________________________________________________
1219 void 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 //____________________________________________________________________________
1252 void 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 //____________________________________________________________________________
1270 int 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 //____________________________________________________________________________
1281 int 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 //____________________________________________________________________________
1292 int 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)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
static DH * EVP_PKEY_get0_DH(EVP_PKEY *pkey)
static EVP_PKEY * getFixedDHParams()
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 int SetBuffer(int l, const char *b)
virtual int Length() const
virtual char * Type() 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
Definition: XrdSutBucket.hh:47
static char * GetBuffer(int len, int opt=-1)
Definition: XrdSutRndm.cc:179