00001
00002
00003 const char *XrdCryptosslCipherCVSID = "$Id: XrdCryptosslCipher.cc 30949 2009-11-02 16:37:58Z ganis $";
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <string.h>
00020
00021 #include <XrdSut/XrdSutRndm.hh>
00022 #include <XrdCrypto/XrdCryptosslTrace.hh>
00023 #include <XrdCrypto/XrdCryptosslCipher.hh>
00024
00025
00026 #include <openssl/bio.h>
00027 #include <openssl/pem.h>
00028
00029
00030
00031
00032
00033
00034
00035
00036 bool XrdCryptosslCipher::IsSupported(const char *cip)
00037 {
00038
00039
00040 return (EVP_get_cipherbyname(cip) != 0);
00041 }
00042
00043
00044 XrdCryptosslCipher::XrdCryptosslCipher(const char *t, int l)
00045 {
00046
00047
00048
00049
00050
00051 valid = 0;
00052 fIV = 0;
00053 lIV = 0;
00054 cipher = 0;
00055 fDH = 0;
00056 deflength = 1;
00057
00058
00059 char cipnam[64] = {"bf-cbc"};
00060 if (t && strcmp(t,"default")) {
00061 strcpy(cipnam,t);
00062 cipnam[63] = 0;
00063 }
00064 cipher = EVP_get_cipherbyname(cipnam);
00065
00066 if (cipher) {
00067
00068 EVP_CIPHER_CTX_init(&ctx);
00069
00070 l = (l > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : l;
00071 int ldef = EVP_CIPHER_key_length(cipher);
00072 int lgen = (l > ldef) ? l : ldef;
00073
00074 char *ktmp = XrdSutRndm::GetBuffer(lgen);
00075 if (ktmp) {
00076 valid = 1;
00077
00078 if (l && l != ldef) {
00079 EVP_CipherInit(&ctx, cipher, 0, 0, 1);
00080 EVP_CIPHER_CTX_set_key_length(&ctx,l);
00081 EVP_CipherInit(&ctx, 0, (unsigned char *)ktmp, 0, 1);
00082 if (l == EVP_CIPHER_CTX_key_length(&ctx)) {
00083
00084 SetBuffer(l,ktmp);
00085 deflength = 0;
00086 }
00087 }
00088 if (!Length()) {
00089 EVP_CipherInit(&ctx, cipher, (unsigned char *)ktmp, 0, 1);
00090 SetBuffer(ldef,ktmp);
00091 }
00092
00093 SetType(cipnam);
00094
00095 delete[] ktmp;
00096 }
00097 }
00098
00099
00100 if (valid)
00101 GenerateIV();
00102 }
00103
00104
00105 XrdCryptosslCipher::XrdCryptosslCipher(const char *t, int l,
00106 const char *k, int liv, const char *iv)
00107 {
00108
00109
00110
00111
00112 valid = 0;
00113 fIV = 0;
00114 lIV = 0;
00115 fDH = 0;
00116 cipher = 0;
00117 deflength = 1;
00118
00119
00120 char cipnam[64] = {"bf-cbc"};
00121 if (t && strcmp(t,"default")) {
00122 strcpy(cipnam,t);
00123 cipnam[63] = 0;
00124 }
00125 cipher = EVP_get_cipherbyname(cipnam);
00126
00127 if (cipher) {
00128
00129 EVP_CIPHER_CTX_init(&ctx);
00130
00131 SetBuffer(l,k);
00132 if (l != EVP_CIPHER_key_length(cipher))
00133 deflength = 0;
00134
00135 SetType(cipnam);
00136
00137 valid = 1;
00138 }
00139
00140
00141 if (valid) {
00142
00143
00144 SetIV(liv,iv);
00145
00146 if (deflength) {
00147 EVP_CipherInit(&ctx, cipher, (unsigned char *)Buffer(), 0, 1);
00148 } else {
00149 EVP_CipherInit(&ctx, cipher, 0, 0, 1);
00150 EVP_CIPHER_CTX_set_key_length(&ctx,Length());
00151 EVP_CipherInit(&ctx, 0, (unsigned char *)Buffer(), 0, 1);
00152 }
00153 }
00154 }
00155
00156
00157 XrdCryptosslCipher::XrdCryptosslCipher(XrdSutBucket *bck)
00158 {
00159
00160
00161
00162 valid = 0;
00163 fIV = 0;
00164 lIV = 0;
00165 fDH = 0;
00166 cipher = 0;
00167 deflength = 1;
00168
00169 if (bck && bck->size > 0) {
00170
00171
00172 EVP_CIPHER_CTX_init(&ctx);
00173
00174 valid = 1;
00175
00176 kXR_int32 ltyp = 0;
00177 kXR_int32 livc = 0;
00178 kXR_int32 lbuf = 0;
00179 kXR_int32 lp = 0;
00180 kXR_int32 lg = 0;
00181 kXR_int32 lpub = 0;
00182 kXR_int32 lpri = 0;
00183 char *bp = bck->buffer;
00184 int cur = 0;
00185 memcpy(<yp,bp+cur,sizeof(kXR_int32));
00186 cur += sizeof(kXR_int32);
00187 memcpy(&livc,bp+cur,sizeof(kXR_int32));
00188 cur += sizeof(kXR_int32);
00189 memcpy(&lbuf,bp+cur,sizeof(kXR_int32));
00190 cur += sizeof(kXR_int32);
00191 memcpy(&lp,bp+cur,sizeof(kXR_int32));
00192 cur += sizeof(kXR_int32);
00193 memcpy(&lg,bp+cur,sizeof(kXR_int32));
00194 cur += sizeof(kXR_int32);
00195 memcpy(&lpub,bp+cur,sizeof(kXR_int32));
00196 cur += sizeof(kXR_int32);
00197 memcpy(&lpri,bp+cur,sizeof(kXR_int32));
00198 cur += sizeof(kXR_int32);
00199
00200 if (ltyp) {
00201 char *buf = new char[ltyp+1];
00202 if (buf) {
00203 memcpy(buf,bp+cur,ltyp);
00204 buf[ltyp] = 0;
00205 cipher = EVP_get_cipherbyname(buf);
00206 if (!cipher)
00207 cipher = EVP_get_cipherbyname("bf-cbc");
00208 if (cipher) {
00209
00210 SetType(buf);
00211 } else {
00212 valid = 0;
00213 }
00214 delete[] buf;
00215 } else
00216 valid = 0;
00217 cur += ltyp;
00218 }
00219
00220 if (livc) {
00221 char *buf = new char[livc];
00222 if (buf) {
00223 memcpy(buf,bp+cur,livc);
00224 cur += livc;
00225
00226 SetIV(livc,buf);
00227 delete[] buf;
00228 } else
00229 valid = 0;
00230 cur += livc;
00231 }
00232
00233 if (lbuf) {
00234 char *buf = new char[lbuf];
00235 if (buf) {
00236 memcpy(buf,bp+cur,lbuf);
00237
00238 UseBuffer(lbuf,buf);
00239 if (cipher && lbuf != EVP_CIPHER_key_length(cipher))
00240 deflength = 0;
00241 } else
00242 valid = 0;
00243 cur += lbuf;
00244 }
00245
00246 if (lp > 0 || lg > 0 || lpub > 0 || lpri > 0) {
00247 if ((fDH = DH_new())) {
00248 char *buf = 0;
00249
00250 if (lp > 0) {
00251 buf = new char[lp+1];
00252 if (buf) {
00253 memcpy(buf,bp+cur,lp);
00254 buf[lp] = 0;
00255 BN_hex2bn(&(fDH->p),buf);
00256 delete[] buf;
00257 } else
00258 valid = 0;
00259 cur += lp;
00260 }
00261
00262 if (lg > 0) {
00263 buf = new char[lg+1];
00264 if (buf) {
00265 memcpy(buf,bp+cur,lg);
00266 buf[lg] = 0;
00267 BN_hex2bn(&(fDH->g),buf);
00268 delete[] buf;
00269 } else
00270 valid = 0;
00271 cur += lg;
00272 }
00273
00274 if (lpub > 0) {
00275 buf = new char[lpub+1];
00276 if (buf) {
00277 memcpy(buf,bp+cur,lpub);
00278 buf[lpub] = 0;
00279 BN_hex2bn(&(fDH->pub_key),buf);
00280 delete[] buf;
00281 } else
00282 valid = 0;
00283 cur += lpub;
00284 }
00285
00286 if (lpri > 0) {
00287 buf = new char[lpri+1];
00288 if (buf) {
00289 memcpy(buf,bp+cur,lpri);
00290 buf[lpri] = 0;
00291 BN_hex2bn(&(fDH->priv_key),buf);
00292 delete[] buf;
00293 } else
00294 valid = 0;
00295 cur += lpri;
00296 }
00297 int dhrc = 0;
00298 DH_check(fDH,&dhrc);
00299 if (dhrc == 0)
00300 valid = 1;
00301 } else
00302 valid = 0;
00303 }
00304 }
00305
00306
00307 if (valid) {
00308 if (deflength) {
00309 EVP_CipherInit(&ctx, cipher, (unsigned char *)Buffer(), 0, 1);
00310 } else {
00311 EVP_CipherInit(&ctx, cipher, 0, 0, 1);
00312 EVP_CIPHER_CTX_set_key_length(&ctx,Length());
00313 EVP_CipherInit(&ctx, 0, (unsigned char *)Buffer(), 0, 1);
00314 }
00315 }
00316 }
00317
00318
00319 XrdCryptosslCipher::XrdCryptosslCipher(int bits, char *pub,
00320 int lpub, const char *t)
00321 {
00322
00323
00324
00325
00326
00327
00328
00329
00330 EPNAME("sslCipher::XrdCryptosslCipher");
00331
00332 valid = 0;
00333 fIV = 0;
00334 lIV = 0;
00335 fDH = 0;
00336 cipher = 0;
00337 deflength = 1;
00338
00339 if (!pub) {
00340 DEBUG("generate DH full key");
00341
00342
00343 bits = (bits < kDHMINBITS) ? kDHMINBITS : bits;
00344
00345
00346 if ((fDH = DH_generate_parameters(bits,DH_GENERATOR_5,0,0))) {
00347 int prc = 0;
00348 DH_check(fDH,&prc);
00349 if (prc == 0) {
00350
00351
00352 if (DH_generate_key(fDH)) {
00353 valid = 1;
00354 } else {
00355 DH_free(fDH);
00356 }
00357 }
00358 }
00359
00360 } else {
00361 DEBUG("initialize cipher from key-agreement buffer");
00362
00363 char *ktmp = 0;
00364 int ltmp = 0;
00365
00366 BIGNUM *bnpub = 0;
00367 char *pb = strstr(pub,"---BPUB---");
00368 char *pe = strstr(pub,"---EPUB--");
00369 if (pb && pe) {
00370 lpub = (int)(pb-pub);
00371 pb += 10;
00372 *pe = 0;
00373 BN_hex2bn(&bnpub, pb);
00374 *pe = '-';
00375 }
00376 if (bnpub) {
00377
00378
00379 BIO *biop = BIO_new(BIO_s_mem());
00380 if (biop) {
00381
00382
00383 BIO_write(biop,pub,lpub);
00384
00385
00386 if ((fDH = DH_new())) {
00387
00388
00389 PEM_read_bio_DHparams(biop,&fDH,0,0);
00390 int prc = 0;
00391 DH_check(fDH,&prc);
00392 if (prc == 0) {
00393
00394
00395 if (DH_generate_key(fDH)) {
00396
00397 ktmp = new char[DH_size(fDH)];
00398 memset(ktmp, 0, DH_size(fDH));
00399 if (ktmp) {
00400 if ((ltmp = DH_compute_key((unsigned char *)ktmp,
00401 bnpub,fDH)) > 0)
00402 valid = 1;
00403 }
00404 }
00405 }
00406 }
00407 BIO_free(biop);
00408 }
00409 }
00410
00411
00412 if (valid) {
00413
00414
00415 char cipnam[64] = {"bf-cbc"};
00416 if (t && strcmp(t,"default")) {
00417 strcpy(cipnam,t);
00418 cipnam[63] = 0;
00419 }
00420 if ((cipher = EVP_get_cipherbyname(cipnam))) {
00421
00422 EVP_CIPHER_CTX_init(&ctx);
00423
00424 ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp;
00425 int ldef = EVP_CIPHER_key_length(cipher);
00426
00427 if (ltmp != ldef) {
00428 EVP_CipherInit(&ctx, cipher, 0, 0, 1);
00429 EVP_CIPHER_CTX_set_key_length(&ctx,ltmp);
00430 EVP_CipherInit(&ctx, 0, (unsigned char *)ktmp, 0, 1);
00431 if (ltmp == EVP_CIPHER_CTX_key_length(&ctx)) {
00432
00433 SetBuffer(ltmp,ktmp);
00434 deflength = 0;
00435 }
00436 }
00437 if (!Length()) {
00438 EVP_CipherInit(&ctx, cipher, (unsigned char *)ktmp, 0, 1);
00439 SetBuffer(ldef,ktmp);
00440 }
00441
00442 SetType(cipnam);
00443 }
00444 }
00445
00446 if (ktmp) delete[] ktmp; ktmp = 0;
00447 }
00448
00449
00450 if (!valid)
00451 Cleanup();
00452 }
00453
00454
00455 XrdCryptosslCipher::XrdCryptosslCipher(const XrdCryptosslCipher &c)
00456 {
00457
00458
00459
00460 deflength = c.deflength;
00461 valid = c.valid;
00462
00463 lIV = 0;
00464 fIV = 0;
00465 SetIV(c.lIV,c.fIV);
00466
00467 cipher = c.cipher;
00468
00469 EVP_CIPHER_CTX_init(&ctx);
00470
00471 SetBuffer(c.Length(),c.Buffer());
00472
00473 SetType(c.Type());
00474
00475 fDH = 0;
00476 if (valid && c.fDH) {
00477 valid = 0;
00478 if ((fDH = DH_new())) {
00479 if (c.fDH->p) fDH->p = BN_dup(c.fDH->p);
00480 if (c.fDH->g) fDH->g = BN_dup(c.fDH->g);
00481 if (c.fDH->pub_key) fDH->pub_key = BN_dup(c.fDH->pub_key);
00482 if (c.fDH->priv_key) fDH->priv_key = BN_dup(c.fDH->priv_key);
00483 int dhrc = 0;
00484 DH_check(fDH,&dhrc);
00485 if (dhrc == 0)
00486 valid = 1;
00487 }
00488 }
00489 }
00490
00491
00492 XrdCryptosslCipher::~XrdCryptosslCipher()
00493 {
00494
00495
00496
00497 if (fIV)
00498 delete[] fIV;
00499
00500
00501 if (valid)
00502 EVP_CIPHER_CTX_cleanup(&ctx);
00503 Cleanup();
00504 }
00505
00506
00507 void XrdCryptosslCipher::Cleanup()
00508 {
00509
00510
00511
00512 if (fDH) {
00513 DH_free(fDH);
00514 fDH = 0;
00515 }
00516 }
00517
00518
00519 bool XrdCryptosslCipher::Finalize(char *pub, int lpub, const char *t)
00520 {
00521
00522
00523
00524
00525
00526 EPNAME("sslCipher::Finalize");
00527
00528 if (!fDH) {
00529 DEBUG("DH undefined: this cipher cannot be finalized"
00530 " by this method");
00531 return 0;
00532 }
00533
00534 char *ktmp = 0;
00535 int ltmp = 0;
00536 if (pub) {
00537
00538
00539 BIGNUM *bnpub = 0;
00540 char *pb = strstr(pub,"---BPUB---");
00541 char *pe = strstr(pub,"---EPUB--");
00542 if (pb && pe) {
00543 lpub = (int)(pb-pub);
00544 pb += 10;
00545 *pe = 0;
00546 BN_hex2bn(&bnpub, pb);
00547 *pe = '-';
00548 }
00549 if (bnpub) {
00550
00551 ktmp = new char[DH_size(fDH)];
00552 memset(ktmp, 0, DH_size(fDH));
00553 if (ktmp) {
00554 if ((ltmp =
00555 DH_compute_key((unsigned char *)ktmp,bnpub,fDH)) > 0)
00556 valid = 1;
00557 }
00558 }
00559
00560
00561 if (valid) {
00562
00563 char cipnam[64] = {"bf-cbc"};
00564 if (t && strcmp(t,"default")) {
00565 strcpy(cipnam,t);
00566 cipnam[63] = 0;
00567 }
00568 if ((cipher = EVP_get_cipherbyname(cipnam))) {
00569
00570 EVP_CIPHER_CTX_init(&ctx);
00571
00572 ltmp = (ltmp > EVP_MAX_KEY_LENGTH) ? EVP_MAX_KEY_LENGTH : ltmp;
00573 int ldef = EVP_CIPHER_key_length(cipher);
00574
00575 if (ltmp != ldef) {
00576 EVP_CipherInit(&ctx, cipher, 0, 0, 1);
00577 EVP_CIPHER_CTX_set_key_length(&ctx,ltmp);
00578 EVP_CipherInit(&ctx, 0, (unsigned char *)ktmp, 0, 1);
00579 if (ltmp == EVP_CIPHER_CTX_key_length(&ctx)) {
00580
00581 SetBuffer(ltmp,ktmp);
00582 deflength = 0;
00583 }
00584 }
00585 if (!Length()) {
00586 EVP_CipherInit(&ctx, cipher, (unsigned char *)ktmp, 0, 1);
00587 SetBuffer(ldef,ktmp);
00588 }
00589
00590 SetType(cipnam);
00591 }
00592 }
00593
00594 if (ktmp) delete[] ktmp; ktmp = 0;
00595 }
00596
00597
00598 if (!valid)
00599 Cleanup();
00600
00601
00602 return valid;
00603 }
00604
00605
00606 int XrdCryptosslCipher::Publen()
00607 {
00608
00609 static int lhdr = strlen("-----BEGIN DH PARAMETERS-----"
00610 "-----END DH PARAMETERS-----") + 3;
00611 if (fDH) {
00612
00613 int l = 2*DH_size(fDH);
00614 if (l < 22) l = 22;
00615
00616 l += lhdr;
00617
00618 return (l+20);
00619 } else
00620 return 0;
00621 }
00622
00623
00624 char *XrdCryptosslCipher::Public(int &lpub)
00625 {
00626
00627
00628
00629 static int lhend = strlen("-----END DH PARAMETERS-----");
00630
00631 if (fDH) {
00632
00633
00634 char *phex = BN_bn2hex(fDH->pub_key);
00635 int lhex = strlen(phex);
00636
00637
00638 BIO *biop = BIO_new(BIO_s_mem());
00639 if (biop) {
00640 int ltmp = Publen() + lhex + 20;
00641 char *pub = new char[ltmp];
00642 if (pub) {
00643
00644 PEM_write_bio_DHparams(biop,fDH);
00645
00646 BIO_read(biop,(void *)pub,ltmp);
00647 BIO_free(biop);
00648
00649 char *p = strstr(pub,"-----END DH PARAMETERS-----");
00650
00651 lpub = (int)(p - pub) + lhend + 1;
00652 if (phex && p) {
00653
00654 p += (lhend+1);
00655
00656 strncpy(p,"---BPUB---",10);
00657 p += 10;
00658
00659 strncpy(p,phex,lhex);
00660 OPENSSL_free(phex);
00661
00662 p += lhex;
00663 strncpy(p,"---EPUB---",10);
00664
00665 lpub += (20 + lhex);
00666 } else {
00667 if (phex) OPENSSL_free(phex);
00668 }
00669
00670 return pub;
00671 }
00672 } else {
00673 if (phex) OPENSSL_free(phex);
00674 }
00675 }
00676
00677 lpub = 0;
00678 return (char *)0;
00679 }
00680
00681
00682 void XrdCryptosslCipher::PrintPublic(BIGNUM *pub)
00683 {
00684
00685
00686
00687
00688 BIO *biop = BIO_new(BIO_s_mem());
00689 if (biop) {
00690
00691 DSA *dsa = DSA_new();
00692 if (dsa) {
00693 dsa->pub_key = BN_dup(pub);
00694
00695 PEM_write_bio_DSA_PUBKEY(biop,dsa);
00696
00697 int lpub = Publen();
00698 char *bpub = new char[lpub];
00699 if (bpub) {
00700 BIO_read(biop,(void *)bpub,lpub);
00701 cerr << bpub << endl;
00702 delete[] bpub;
00703 }
00704 DSA_free(dsa);
00705 }
00706 BIO_free(biop);
00707 }
00708 }
00709
00710
00711 XrdSutBucket *XrdCryptosslCipher::AsBucket()
00712 {
00713
00714
00715
00716
00717 XrdSutBucket *buck = (XrdSutBucket *)0;
00718
00719 if (valid) {
00720
00721
00722 kXR_int32 lbuf = Length();
00723 kXR_int32 ltyp = Type() ? strlen(Type()) : 0;
00724 kXR_int32 livc = lIV;
00725 char *cp = (fDH && fDH->p) ? BN_bn2hex(fDH->p) : 0;
00726 char *cg = (fDH && fDH->g) ? BN_bn2hex(fDH->g) : 0;
00727 char *cpub = (fDH && fDH->pub_key) ? BN_bn2hex(fDH->pub_key) : 0;
00728 char *cpri = (fDH && fDH->priv_key) ? BN_bn2hex(fDH->priv_key) : 0;
00729 kXR_int32 lp = cp ? strlen(cp) : 0;
00730 kXR_int32 lg = cg ? strlen(cg) : 0;
00731 kXR_int32 lpub = cpub ? strlen(cpub) : 0;
00732 kXR_int32 lpri = cpri ? strlen(cpri) : 0;
00733 int ltot = 7*sizeof(kXR_int32) + ltyp + Length() + livc +
00734 lp + lg + lpub + lpri;
00735 char *newbuf = new char[ltot];
00736 if (newbuf) {
00737 int cur = 0;
00738 memcpy(newbuf+cur,<yp,sizeof(kXR_int32));
00739 cur += sizeof(kXR_int32);
00740 memcpy(newbuf+cur,&livc,sizeof(kXR_int32));
00741 cur += sizeof(kXR_int32);
00742 memcpy(newbuf+cur,&lbuf,sizeof(kXR_int32));
00743 cur += sizeof(kXR_int32);
00744 memcpy(newbuf+cur,&lp,sizeof(kXR_int32));
00745 cur += sizeof(kXR_int32);
00746 memcpy(newbuf+cur,&lg,sizeof(kXR_int32));
00747 cur += sizeof(kXR_int32);
00748 memcpy(newbuf+cur,&lpub,sizeof(kXR_int32));
00749 cur += sizeof(kXR_int32);
00750 memcpy(newbuf+cur,&lpri,sizeof(kXR_int32));
00751 cur += sizeof(kXR_int32);
00752 if (Type()) {
00753 memcpy(newbuf+cur,Type(),ltyp);
00754 cur += ltyp;
00755 }
00756 if (fIV) {
00757 memcpy(newbuf+cur,fIV,livc);
00758 cur += livc;
00759 }
00760 if (Buffer()) {
00761 memcpy(newbuf+cur,Buffer(),lbuf);
00762 cur += lbuf;
00763 }
00764 if (cp) {
00765 memcpy(newbuf+cur,cp,lp);
00766 cur += lp;
00767 OPENSSL_free(cp);
00768 }
00769 if (cg) {
00770 memcpy(newbuf+cur,cg,lg);
00771 cur += lg;
00772 OPENSSL_free(cg);
00773 }
00774 if (cpub) {
00775 memcpy(newbuf+cur,cpub,lpub);
00776 cur += lpub;
00777 OPENSSL_free(cpub);
00778 }
00779 if (cpri) {
00780 memcpy(newbuf+cur,cpri,lpri);
00781 cur += lpri;
00782 OPENSSL_free(cpri);
00783 }
00784
00785 buck = new XrdSutBucket(newbuf,ltot,kXRS_cipher);
00786 }
00787 }
00788
00789 return buck;
00790 }
00791
00792
00793 void XrdCryptosslCipher::SetIV(int l, const char *iv)
00794 {
00795
00796
00797 if (fIV) {
00798 delete[] fIV;
00799 fIV = 0;
00800 lIV = 0;
00801 }
00802
00803 if (iv && l > 0) {
00804 fIV = new char[l];
00805 if (fIV) {
00806 memcpy(fIV,iv,l);
00807 lIV = l;
00808 }
00809 }
00810 }
00811
00812
00813 char *XrdCryptosslCipher::RefreshIV(int &l)
00814 {
00815
00816
00817
00818 GenerateIV();
00819
00820
00821 l = lIV;
00822 return fIV;
00823 }
00824
00825
00826 void XrdCryptosslCipher::GenerateIV()
00827 {
00828
00829
00830
00831 if (fIV) {
00832 delete[] fIV;
00833 fIV = 0;
00834 lIV = 0;
00835 }
00836
00837
00838 fIV = XrdSutRndm::GetBuffer(EVP_MAX_IV_LENGTH);
00839 if (fIV)
00840 lIV = EVP_MAX_IV_LENGTH;
00841 }
00842
00843
00844 int XrdCryptosslCipher::Encrypt(const char *in, int lin, char *out)
00845 {
00846
00847
00848
00849
00850
00851 return EncDec(1, in, lin, out);
00852 }
00853
00854
00855 int XrdCryptosslCipher::Decrypt(const char *in, int lin, char *out)
00856 {
00857
00858
00859
00860
00861
00862 return EncDec(0, in, lin, out);
00863 }
00864
00865
00866 int XrdCryptosslCipher::EncDec(int enc, const char *in, int lin, char *out)
00867 {
00868
00869
00870
00871
00872 EPNAME("Cipher::EncDec");
00873
00874 int lout = 0;
00875
00876
00877 if (!in || lin <= 0 || !out) {
00878 DEBUG("wrong inputs arguments");
00879 if (!in) DEBUG("in: "<<in);
00880 if (lin <= 0) DEBUG("lin: "<<lin);
00881 if (!out) DEBUG("out: "<<out);
00882 return 0;
00883 }
00884
00885
00886 unsigned char iv[EVP_MAX_IV_LENGTH];
00887 if (fIV) {
00888 memcpy((void *)iv,fIV,EVP_MAX_IV_LENGTH);
00889 } else {
00890
00891 memset((void *)iv,0,EVP_MAX_IV_LENGTH);
00892 }
00893
00894
00895 if (deflength) {
00896
00897 if (!EVP_CipherInit(&ctx, cipher, (unsigned char *)Buffer(), iv, enc)) {
00898 DEBUG("error initializing");
00899 return 0;
00900 }
00901 } else {
00902
00903 if (!EVP_CipherInit(&ctx, cipher, 0, 0, enc)) {
00904 DEBUG("error initializing - 1");
00905 return 0;
00906 }
00907
00908 EVP_CIPHER_CTX_set_key_length(&ctx,Length());
00909
00910 if (!EVP_CipherInit(&ctx, 0, (unsigned char *)Buffer(), iv, enc)) {
00911 DEBUG("error initializing - 2");
00912 return 0;
00913 }
00914 }
00915
00916
00917 int ltmp = 0;
00918 if (!EVP_CipherUpdate(&ctx, (unsigned char *)&out[0], <mp,
00919 (unsigned char *)in, lin)) {
00920 DEBUG("error encrypting");
00921 return 0;
00922 }
00923 lout = ltmp;
00924 if (!EVP_CipherFinal(&ctx, (unsigned char *)&out[lout], <mp)) {
00925 DEBUG("error finalizing");
00926 return 0;
00927 }
00928
00929
00930 lout += ltmp;
00931 return lout;
00932 }
00933
00934
00935 int XrdCryptosslCipher::EncOutLength(int l)
00936 {
00937
00938
00939 return (l+EVP_CIPHER_CTX_block_size(&ctx));
00940 }
00941
00942
00943 int XrdCryptosslCipher::DecOutLength(int l)
00944 {
00945
00946
00947 int lout = l+EVP_CIPHER_CTX_block_size(&ctx)+1;
00948 lout = (lout <= 0) ? l : lout;
00949 return lout;
00950 }