00001
00002
00003 const char *XrdCryptosslgsiAuxCVSID = "$Id: XrdCryptosslgsiAux.cc 31508 2009-12-02 19:11:01Z brun $";
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <string.h>
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020
00021 #include <openssl/asn1.h>
00022 #include <openssl/asn1_mac.h>
00023 #include <openssl/err.h>
00024 #include <openssl/evp.h>
00025 #include <openssl/pem.h>
00026 #include <openssl/rsa.h>
00027 #include <openssl/x509v3.h>
00028
00029 #include <XrdSut/XrdSutRndm.hh>
00030 #include <XrdCrypto/XrdCryptosslgsiAux.hh>
00031 #include <XrdCrypto/XrdCryptoTrace.hh>
00032 #include <XrdCrypto/XrdCryptosslAux.hh>
00033 #include <XrdCrypto/XrdCryptosslRSA.hh>
00034 #include <XrdCrypto/XrdCryptosslX509.hh>
00035 #include <XrdCrypto/XrdCryptosslX509Req.hh>
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 typedef struct {
00046 ASN1_OBJECT *policyLanguage;
00047 ASN1_OCTET_STRING *policy;
00048 } gsiProxyPolicy_t;
00049
00050 typedef struct {
00051 ASN1_INTEGER *proxyCertPathLengthConstraint;
00052 gsiProxyPolicy_t *proxyPolicy;
00053 } gsiProxyCertInfo_t;
00054
00055
00056
00057
00058 #define ASN1_F_GSIPROXYCERTINFO_NEW 500
00059 #define ASN1_F_D2I_GSIPROXYCERTINFO 501
00060 #define ASN1_F_GSIPROXYPOLICY_NEW 510
00061 #define ASN1_F_D2I_GSIPROXYPOLICY 511
00062
00063
00064
00065
00066
00067 static ASN1_OBJECT *OBJ_txt2obj_fix(const char *s, int no_name)
00068 {
00069 int nid = NID_undef;
00070 ASN1_OBJECT *op=NULL;
00071 unsigned char *buf,*p;
00072 int i, j;
00073
00074 if(!no_name) {
00075 if( ((nid = OBJ_sn2nid(s)) != NID_undef) ||
00076 ((nid = OBJ_ln2nid(s)) != NID_undef) )
00077 return OBJ_nid2obj(nid);
00078 }
00079
00080
00081 i=a2d_ASN1_OBJECT(NULL,0,s,-1);
00082 if (i <= 0) {
00083
00084 ERR_get_error();
00085 return NULL;
00086 }
00087
00088 j = ASN1_object_size(0,i,V_ASN1_OBJECT);
00089
00090 if((buf=(unsigned char *)OPENSSL_malloc(j)) == NULL) return NULL;
00091
00092 p = buf;
00093
00094 ASN1_put_object(&p,0,i,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
00095
00096 a2d_ASN1_OBJECT(p,i,s,-1);
00097
00098 p=buf;
00099 #ifdef R__SSL_GE_098
00100
00101 op = d2i_ASN1_OBJECT(0, const_cast<const unsigned char**>(&p), j);
00102 #else
00103 op=d2i_ASN1_OBJECT(0, &p, i);
00104 #endif
00105 OPENSSL_free(buf);
00106 return op;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115 gsiProxyPolicy_t *gsiProxyPolicy_new()
00116 {
00117
00118 ASN1_CTX c;
00119 gsiProxyPolicy_t *ret;
00120
00121
00122 ret = 0;
00123 M_ASN1_New_Malloc(ret, gsiProxyPolicy_t);
00124
00125 ret->policyLanguage = OBJ_txt2obj_fix("1.3.6.1.5.5.7.21.1", 1);
00126 ret->policy = 0;
00127
00128 return (ret);
00129
00130 M_ASN1_New_Error(ASN1_F_GSIPROXYPOLICY_NEW);
00131 }
00132
00133
00134 void gsiProxyPolicy_free(gsiProxyPolicy_t *pol)
00135 {
00136
00137
00138
00139 if (!pol)
00140 return;
00141
00142
00143 if (pol->policyLanguage)
00144 ASN1_OBJECT_free(pol->policyLanguage);
00145
00146
00147 if (pol->policy)
00148 M_ASN1_OCTET_STRING_free(pol->policy);
00149
00150
00151 OPENSSL_free(pol);
00152 }
00153
00154
00155
00156
00157
00158
00159
00160 #ifdef R__SSL_GE_098
00161 gsiProxyPolicy_t *d2i_gsiProxyPolicy(gsiProxyPolicy_t **pol,
00162 const unsigned char **pp, long length)
00163 #else
00164 gsiProxyPolicy_t *d2i_gsiProxyPolicy(gsiProxyPolicy_t **pol,
00165 unsigned char **pp, long length)
00166 #endif
00167 {
00168
00169
00170
00171 M_ASN1_D2I_vars(pol, gsiProxyPolicy_t *, gsiProxyPolicy_new);
00172
00173
00174 M_ASN1_D2I_Init();
00175 M_ASN1_D2I_start_sequence();
00176
00177
00178 M_ASN1_D2I_get(ret->policyLanguage, d2i_ASN1_OBJECT);
00179
00180
00181 M_ASN1_D2I_get_IMP_opt(ret->policy, d2i_ASN1_OCTET_STRING,
00182 0, V_ASN1_OCTET_STRING);
00183
00184
00185 M_ASN1_D2I_Finish(pol, gsiProxyPolicy_free, ASN1_F_D2I_GSIPROXYPOLICY);
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 int i2d_gsiProxyPolicy(gsiProxyPolicy_t *pol, unsigned char **pp)
00195 {
00196
00197
00198
00199
00200 M_ASN1_I2D_vars(pol);
00201
00202
00203 M_ASN1_I2D_len(pol->policyLanguage, i2d_ASN1_OBJECT);
00204
00205
00206 if (pol->policy) {
00207 M_ASN1_I2D_len(pol->policy, i2d_ASN1_OCTET_STRING);
00208 }
00209
00210
00211 M_ASN1_I2D_seq_total();
00212
00213
00214 M_ASN1_I2D_put(pol->policyLanguage, i2d_ASN1_OBJECT);
00215
00216
00217 if (pol->policy) {
00218 M_ASN1_I2D_put(pol->policy, i2d_ASN1_OCTET_STRING);
00219 }
00220
00221
00222 M_ASN1_I2D_finish();
00223 }
00224
00225
00226
00227
00228 gsiProxyCertInfo_t *gsiProxyCertInfo_new()
00229 {
00230
00231 ASN1_CTX c;
00232 gsiProxyCertInfo_t *ret;
00233
00234
00235 ret = 0;
00236 M_ASN1_New_Malloc(ret, gsiProxyCertInfo_t);
00237 memset(ret, 0, sizeof(gsiProxyCertInfo_t));
00238
00239
00240 ret->proxyCertPathLengthConstraint = 0;
00241 ret->proxyPolicy = gsiProxyPolicy_new();
00242
00243
00244 return (ret);
00245
00246
00247 M_ASN1_New_Error(ASN1_F_GSIPROXYCERTINFO_NEW);
00248 }
00249
00250
00251 void gsiProxyCertInfo_free(gsiProxyCertInfo_t *pci)
00252 {
00253
00254
00255
00256 if (!pci)
00257 return;
00258
00259 if (pci->proxyCertPathLengthConstraint)
00260 ASN1_INTEGER_free(pci->proxyCertPathLengthConstraint);
00261
00262 OPENSSL_free(pci);
00263 }
00264
00265
00266
00267
00268
00269 #ifdef R__SSL_GE_098
00270 gsiProxyCertInfo_t *d2i_gsiProxyCertInfo(gsiProxyCertInfo_t **pci,
00271 const unsigned char **pp, long length)
00272 #else
00273 gsiProxyCertInfo_t *d2i_gsiProxyCertInfo(gsiProxyCertInfo_t **pci,
00274 unsigned char **pp, long length)
00275 #endif
00276 {
00277
00278
00279
00280 M_ASN1_D2I_vars(pci, gsiProxyCertInfo_t *, gsiProxyCertInfo_new);
00281
00282
00283 M_ASN1_D2I_Init();
00284 M_ASN1_D2I_start_sequence();
00285
00286
00287
00288 M_ASN1_D2I_get(ret->proxyPolicy, d2i_gsiProxyPolicy);
00289
00290
00291 M_ASN1_D2I_get_EXP_opt(ret->proxyCertPathLengthConstraint, d2i_ASN1_INTEGER, 1);
00292 M_ASN1_D2I_get_opt(ret->proxyCertPathLengthConstraint, d2i_ASN1_INTEGER,
00293 V_ASN1_INTEGER);
00294
00295
00296 M_ASN1_D2I_Finish(pci, gsiProxyCertInfo_free, ASN1_F_D2I_GSIPROXYCERTINFO);
00297 }
00298
00299
00300
00301
00302 int i2d_gsiProxyCertInfo(gsiProxyCertInfo_t *pci, unsigned char **pp)
00303 {
00304
00305
00306 int v1 = 0;
00307
00308
00309 M_ASN1_I2D_vars(pci);
00310 v1 = 0;
00311
00312
00313 M_ASN1_I2D_len(pci->proxyPolicy, i2d_gsiProxyPolicy);
00314
00315
00316 if (pci->proxyCertPathLengthConstraint) {
00317 M_ASN1_I2D_len_EXP_opt(pci->proxyCertPathLengthConstraint,
00318 i2d_ASN1_INTEGER, 1, v1);
00319 }
00320
00321
00322 M_ASN1_I2D_seq_total();
00323
00324
00325 M_ASN1_I2D_put(pci->proxyPolicy, i2d_gsiProxyPolicy);
00326
00327
00328 if (pci->proxyCertPathLengthConstraint) {
00329 M_ASN1_I2D_put_EXP_opt(pci->proxyCertPathLengthConstraint, i2d_ASN1_INTEGER, 1, v1);
00330 }
00331
00332
00333 M_ASN1_I2D_finish();
00334 }
00335
00336
00337
00338 bool XrdSslgsiProxyCertInfo(const void *extdata, int &pathlen, bool *haspolicy)
00339 {
00340
00341
00342
00343
00344
00345
00346
00347
00348 if (!extdata) {
00349 return 0;
00350 }
00351
00352 X509_EXTENSION *ext = (X509_EXTENSION *)extdata;
00353
00354
00355 char s[80] = {0};
00356 OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ext), 1);
00357 if (strcmp(s, gsiProxyCertInfo_OID)) {
00358 return 0;
00359 }
00360
00361
00362 unsigned char *p = ext->value->data;
00363 #ifdef R__SSL_GE_098
00364 gsiProxyCertInfo_t *pci =
00365 d2i_gsiProxyCertInfo(0, (const unsigned char **)(&p), ext->value->length);
00366 #else
00367 gsiProxyCertInfo_t *pci = d2i_gsiProxyCertInfo(0, &p, ext->value->length);
00368 #endif
00369 if (!pci) {
00370 return 0;
00371 }
00372
00373
00374 pathlen = -1;
00375 if (pci->proxyCertPathLengthConstraint) {
00376 pathlen = ASN1_INTEGER_get(pci->proxyCertPathLengthConstraint);
00377 }
00378
00379
00380 if (haspolicy) {
00381 *haspolicy = (pci->proxyPolicy) ? 1 : 0;
00382 }
00383
00384
00385 return 1;
00386 }
00387
00388
00389 void XrdSslgsiSetPathLenConstraint(void *extdata, int pathlen)
00390 {
00391
00392
00393
00394
00395
00396 if (!extdata)
00397 return;
00398
00399 X509_EXTENSION *ext = (X509_EXTENSION *)extdata;
00400
00401
00402 char s[80] = {0};
00403 OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ext), 1);
00404 if (strcmp(s, gsiProxyCertInfo_OID))
00405 return;
00406
00407
00408 unsigned char *p = ext->value->data;
00409 #ifdef R__SSL_GE_098
00410 gsiProxyCertInfo_t *pci =
00411 d2i_gsiProxyCertInfo(0, (const unsigned char **)(&p), ext->value->length);
00412 #else
00413 gsiProxyCertInfo_t *pci = d2i_gsiProxyCertInfo(0, &p, ext->value->length);
00414 #endif
00415 if (!pci)
00416 return;
00417
00418
00419 if (pci->proxyCertPathLengthConstraint) {
00420 ASN1_INTEGER_set(pci->proxyCertPathLengthConstraint, pathlen);
00421 }
00422
00423
00424 return;
00425 }
00426
00427
00428 int XrdSslgsiX509CreateProxy(const char *fnc, const char *fnk,
00429 XrdProxyOpt_t *pxopt,
00430 XrdCryptosslgsiX509Chain *xp, XrdCryptoRSA **kp,
00431 const char *fnp)
00432 {
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 EPNAME("X509CreateProxy");
00445
00446
00447 if (!fnc || !fnk || !xp || !kp) {
00448 PRINT("invalid inputs ");
00449 return -1;
00450 }
00451
00452
00453
00454 OpenSSL_add_all_ciphers();
00455 OpenSSL_add_all_digests();
00456 ERR_load_crypto_strings();
00457
00458
00459 int bits = (pxopt && pxopt->bits >= 512) ? pxopt->bits : 512;
00460 int valid = (pxopt) ? pxopt->valid : 43200;
00461 int depthlen = (pxopt) ? pxopt->depthlen : -1;
00462
00463
00464
00465 X509 *xEEC = 0;
00466 FILE *fc = fopen(fnc, "r");
00467 if (fc) {
00468
00469 if (PEM_read_X509(fc, &xEEC, 0, 0)) {
00470 DEBUG("EEC certificate loaded from file: "<<fnc);
00471 } else {
00472 PRINT("unable to load EEC certificate from file: "<<fnc);
00473 fclose(fc);
00474 return -kErrPX_BadEECfile;
00475 }
00476 } else {
00477 PRINT("EEC certificate cannot be opened (file: "<<fnc<<")");
00478 return -kErrPX_BadEECfile;
00479 }
00480 fclose(fc);
00481
00482 int now = (int)time(0);
00483 if (now > XrdCryptosslASN1toUTC(X509_get_notAfter(xEEC))) {
00484 PRINT("EEC certificate has expired");
00485 return -kErrPX_ExpiredEEC;
00486 }
00487
00488
00489
00490 EVP_PKEY *ekEEC;
00491 FILE *fk = fopen(fnk, "r");
00492 if (fk) {
00493
00494 ekEEC = X509_get_pubkey(xEEC);
00495 PRINT("Your identity: "<<X509_NAME_oneline(X509_get_subject_name(xEEC),0,0));
00496 if (PEM_read_PrivateKey(fk, &ekEEC, 0, 0)) {
00497 DEBUG("EEC private key loaded from file: "<<fnk);
00498 } else {
00499 PRINT("unable to load EEC private key from file: "<<fnk);
00500 fclose(fk);
00501 return -kErrPX_BadEECfile;
00502 }
00503 } else {
00504 PRINT("EEC private key file cannot be opened (file: "<<fnk<<")");
00505 return -kErrPX_BadEECfile;
00506 }
00507 fclose(fk);
00508
00509 if (RSA_check_key(ekEEC->pkey.rsa) == 0) {
00510 PRINT("inconsistent key loaded");
00511 return -kErrPX_BadEECkey;
00512 }
00513
00514
00515 X509_REQ *preq = X509_REQ_new();
00516 if (!preq) {
00517 PRINT("cannot to create cert request");
00518 return -kErrPX_NoResources;
00519 }
00520
00521
00522 RSA *kPX = RSA_generate_key(bits, 0x10001, 0, 0);
00523 if (!kPX) {
00524 PRINT("proxy key could not be generated - return");
00525 return -kErrPX_GenerateKey;
00526 }
00527
00528
00529 EVP_PKEY *ekPX = EVP_PKEY_new();
00530 if (!ekPX) {
00531 PRINT("could not create a EVP_PKEY * instance - return");
00532 return -kErrPX_NoResources;
00533 }
00534 EVP_PKEY_set1_RSA(ekPX, kPX);
00535 X509_REQ_set_pubkey(preq, ekPX);
00536
00537
00538
00539 unsigned int serial = XrdSutRndm::GetUInt();
00540
00541
00542
00543
00544
00545 X509_NAME *psubj = X509_NAME_dup(X509_get_subject_name(xEEC));
00546
00547 unsigned char sn[20] = {0};
00548 sprintf((char *)sn, "%d", serial);
00549 if (!X509_NAME_add_entry_by_txt(psubj, (char *)"CN", MBSTRING_ASC,
00550 sn, -1, -1, 0)) {
00551 PRINT("could not add CN - (serial: "<<serial<<", sn: "<<sn<<")");
00552 return -kErrPX_SetAttribute;
00553 }
00554
00555
00556 if (X509_REQ_set_subject_name(preq, psubj) != 1) {
00557 PRINT("could not set subject name - return");
00558 return -kErrPX_SetAttribute;
00559 }
00560
00561
00562 gsiProxyCertInfo_t *pci = gsiProxyCertInfo_new();
00563 if (!pci) {
00564 PRINT("could not create structure for extension - return");
00565 return -kErrPX_NoResources;
00566 }
00567
00568 if (depthlen > -1) {
00569 if ((pci->proxyCertPathLengthConstraint = ASN1_INTEGER_new())) {
00570 ASN1_INTEGER_set(pci->proxyCertPathLengthConstraint, depthlen);
00571 } else {
00572 PRINT("could not set the path length contrain");
00573 return -kErrPX_SetPathDepth;
00574 }
00575 }
00576
00577
00578 X509_EXTENSION *ext = X509_EXTENSION_new();
00579 if (!ext) {
00580 PRINT("could not create extension object");
00581 return -kErrPX_NoResources;
00582 }
00583
00584 #ifndef R__SSL_096
00585
00586
00587 ASN1_OBJECT *obj = OBJ_nid2obj(OBJ_create(gsiProxyCertInfo_OID,
00588 "gsiProxyCertInfo_OID","GSI ProxyCertInfo OID"));
00589 #else
00590
00591
00592 ASN1_OBJECT *obj = OBJ_txt2obj_fix(gsiProxyCertInfo_OID, 1);
00593 #endif
00594 if (!obj || X509_EXTENSION_set_object(ext, obj) != 1) {
00595 PRINT("could not set extension name");
00596 return -kErrPX_SetAttribute;
00597 }
00598
00599 if (X509_EXTENSION_set_critical(ext, 1) != 1) {
00600 PRINT("could not set extension critical flag");
00601 return -kErrPX_SetAttribute;
00602 }
00603
00604 ext->value->length = i2d_gsiProxyCertInfo(pci, 0);
00605 if (!(ext->value->data = (unsigned char *)malloc(ext->value->length+1))) {
00606 PRINT("could not allocate data field for extension");
00607 return -kErrPX_NoResources;
00608 }
00609 unsigned char *pp = ext->value->data;
00610 if ((i2d_gsiProxyCertInfo(pci, &pp)) <= 0) {
00611 PRINT("problem converting data for extension");
00612 return -kErrPX_Error;
00613 }
00614
00615 STACK_OF(X509_EXTENSION) *esk = sk_X509_EXTENSION_new_null();
00616 if (!esk) {
00617 PRINT("could not create stack for extensions");
00618 return -kErrPX_NoResources;
00619 }
00620 if (sk_X509_EXTENSION_push(esk, ext) != 1) {
00621 PRINT("could not push the extension in the stack");
00622 return -kErrPX_Error;
00623 }
00624
00625 if (!(X509_REQ_add_extensions(preq, esk))) {
00626 PRINT("problem adding extension");
00627 return -kErrPX_SetAttribute;
00628 }
00629
00630
00631 if (!(X509_REQ_sign(preq, ekPX, EVP_md5()))) {
00632 PRINT("problems signing the request");
00633 return -kErrPX_Signing;
00634 }
00635
00636
00637 X509 *xPX = X509_new();
00638 if (!xPX) {
00639 PRINT("could not create certificate object for proxies");
00640 return -kErrPX_NoResources;
00641 }
00642
00643
00644 if (X509_set_version(xPX, 2L) != 1) {
00645 PRINT("could not set version");
00646 return -kErrPX_SetAttribute;
00647 }
00648
00649
00650 if (ASN1_INTEGER_set(X509_get_serialNumber(xPX), serial) != 1) {
00651 PRINT("could not set serial number");
00652 return -kErrPX_SetAttribute;
00653 }
00654
00655
00656 if (X509_set_subject_name(xPX, psubj) != 1) {
00657 PRINT("could not set subject name");
00658 return -kErrPX_SetAttribute;
00659 }
00660
00661
00662 if (X509_set_issuer_name(xPX, X509_get_subject_name(xEEC)) != 1) {
00663 PRINT("could not set issuer name");
00664 return -kErrPX_SetAttribute;
00665 }
00666
00667
00668 if (X509_set_pubkey(xPX, ekPX) != 1) {
00669 PRINT("could not set issuer name");
00670 return -kErrPX_SetAttribute;
00671 }
00672
00673
00674 if (!X509_gmtime_adj(X509_get_notBefore(xPX), 0)) {
00675 PRINT("could not set notBefore");
00676 return -kErrPX_SetAttribute;
00677 }
00678
00679
00680 if (!X509_gmtime_adj(X509_get_notAfter(xPX), valid)) {
00681 PRINT("could not set notAfter");
00682 return -kErrPX_SetAttribute;
00683 }
00684
00685
00686 if (X509_add_ext(xPX, ext, -1) != 1) {
00687 PRINT("could not add extension");
00688 return -kErrPX_SetAttribute;
00689 }
00690
00691
00692
00693 if (!(X509_sign(xPX, ekEEC, EVP_md5()))) {
00694 PRINT("problems signing the certificate");
00695 return -kErrPX_Signing;
00696 }
00697
00698
00699 XrdCryptoX509 *xcPX = new XrdCryptosslX509(xPX);
00700 if (!xcPX) {
00701 PRINT("could not create container for proxy certificate");
00702 return -kErrPX_NoResources;
00703 }
00704
00705 ((XrdCryptosslX509 *)xcPX)->SetPKI((XrdCryptoX509data)ekPX);
00706 xp->PushBack(xcPX);
00707 XrdCryptoX509 *xcEEC = new XrdCryptosslX509(xEEC);
00708 if (!xcEEC) {
00709 PRINT("could not create container for EEC certificate");
00710 return -kErrPX_NoResources;
00711 }
00712 xp->PushBack(xcEEC);
00713 *kp = new XrdCryptosslRSA(ekPX);
00714 if (!(*kp)) {
00715 PRINT("could not creatr out PKI");
00716 return -kErrPX_NoResources;
00717 }
00718
00719
00720
00721 int rc = 0;
00722 if (fnp) {
00723
00724 FILE *fp = fopen(fnp,"w");
00725 if (!fp) {
00726 PRINT("cannot open file to save the proxy certificate (file: "<<fnp<<")");
00727 fclose(fp);
00728 rc = -kErrPX_ProxyFile;
00729 }
00730 int ifp = fileno(fp);
00731 if (ifp == -1) {
00732 PRINT("got invalid file descriptor for the proxy certificate (file: "<<
00733 fnp<<")");
00734 fclose(fp);
00735 rc = -kErrPX_ProxyFile;
00736 }
00737
00738 if (fchmod(ifp, 0600) == -1) {
00739 PRINT("cannot set permissions on file: "<<fnp<<" (errno: "<<errno<<")");
00740 fclose(fp);
00741 rc = -kErrPX_ProxyFile;
00742 }
00743
00744 if (!rc && PEM_write_X509(fp, xPX) != 1) {
00745 PRINT("error while writing proxy certificate");
00746 fclose(fp);
00747 rc = -kErrPX_ProxyFile;
00748 }
00749 if (!rc && PEM_write_RSAPrivateKey(fp, kPX, 0, 0, 0, 0, 0) != 1) {
00750 PRINT("error while writing proxy private key");
00751 fclose(fp);
00752 rc = -kErrPX_ProxyFile;
00753 }
00754 if (!rc && PEM_write_X509(fp, xEEC) != 1) {
00755 PRINT("error while writing EEC certificate");
00756 fclose(fp);
00757 rc = -kErrPX_ProxyFile;
00758 }
00759 fclose(fp);
00760
00761 }
00762
00763
00764 EVP_PKEY_free(ekEEC);
00765 X509_REQ_free(preq);
00766 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
00767 sk_X509_EXTENSION_free(esk);
00768 #else
00769 sk_free(esk);
00770 #endif
00771
00772
00773 return rc;
00774 }
00775
00776
00777 int XrdSslgsiX509CreateProxyReq(XrdCryptoX509 *xcpi,
00778 XrdCryptoX509Req **xcro, XrdCryptoRSA **kcro)
00779 {
00780
00781
00782
00783
00784
00785 EPNAME("X509CreateProxyReq");
00786
00787
00788 if (!xcpi || !(xcpi->Opaque())) {
00789 PRINT("input proxy certificate not specified");
00790 return -1;
00791 }
00792
00793
00794 X509 *xpi = (X509 *)(xcpi->Opaque());
00795
00796
00797 if (!(xcpi->IsValid())) {
00798 PRINT("EEC certificate has expired");
00799 return -kErrPX_ExpiredEEC;
00800 }
00801
00802
00803 X509_REQ *xro = X509_REQ_new();
00804 if (!xro) {
00805 PRINT("cannot to create cert request");
00806 return -kErrPX_NoResources;
00807 }
00808
00809
00810
00811 int bits = EVP_PKEY_bits(X509_get_pubkey(xpi));
00812 bits = (bits < 512) ? 512 : bits;
00813
00814
00815 RSA *kro = RSA_generate_key(bits, 0x10001, 0, 0);
00816 if (!kro) {
00817 PRINT("proxy key could not be generated - return");
00818 return -kErrPX_GenerateKey;
00819 }
00820
00821
00822 EVP_PKEY *ekro = EVP_PKEY_new();
00823 if (!ekro) {
00824 PRINT("could not create a EVP_PKEY * instance - return");
00825 return -kErrPX_NoResources;
00826 }
00827 EVP_PKEY_set1_RSA(ekro, kro);
00828 X509_REQ_set_pubkey(xro, ekro);
00829
00830
00831
00832 unsigned int serial = XrdSutRndm::GetUInt();
00833
00834
00835
00836
00837
00838 X509_NAME *psubj = X509_NAME_dup(X509_get_subject_name(xpi));
00839 if (xcro && *xcro && *((int *)(*xcro)) <= 10100) {
00840
00841 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
00842 int ne = sk_X509_NAME_ENTRY_num(psubj->entries);
00843 #else
00844 int ne = psubj->entries->num;
00845 #endif
00846 if (ne >= 0) {
00847 X509_NAME_ENTRY *cne = X509_NAME_delete_entry(psubj, ne-1);
00848 if (cne) {
00849 X509_NAME_ENTRY_free(cne);
00850 } else {
00851 DEBUG("problems modifying subject name");
00852 }
00853 }
00854 *xcro = 0;
00855 }
00856
00857 unsigned char sn[20] = {0};
00858 sprintf((char *)sn, "%d", serial);
00859 if (!X509_NAME_add_entry_by_txt(psubj, (char *)"CN", MBSTRING_ASC,
00860 sn, -1, -1, 0)) {
00861 PRINT("could not add CN - (serial: "<<serial<<", sn: "<<sn<<")");
00862 return -kErrPX_SetAttribute;
00863 }
00864
00865
00866 if (X509_REQ_set_subject_name(xro, psubj) != 1) {
00867 PRINT("could not set subject name - return");
00868 return -kErrPX_SetAttribute;
00869 }
00870
00871
00872 gsiProxyCertInfo_t *pci = gsiProxyCertInfo_new();
00873 if (!pci) {
00874 PRINT("could not create structure for extension - return");
00875 return -kErrPX_NoResources;
00876 }
00877
00878
00879 X509_EXTENSION *xpiext = 0;
00880 int npiext = X509_get_ext_count(xpi);
00881 int i = 0;
00882 int indepthlen = -1;
00883 for (i = 0; i< npiext; i++) {
00884 xpiext = X509_get_ext(xpi, i);
00885 char s[256];
00886 OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(xpiext), 1);
00887 if (!strcmp(s, gsiProxyCertInfo_OID)) {
00888 unsigned char *p = xpiext->value->data;
00889 #ifdef R__SSL_GE_098
00890 gsiProxyCertInfo_t *inpci =
00891 d2i_gsiProxyCertInfo(0, (const unsigned char **)(&p), xpiext->value->length);
00892 #else
00893 gsiProxyCertInfo_t *inpci = d2i_gsiProxyCertInfo(0, &p, xpiext->value->length);
00894 #endif
00895 if (inpci &&
00896 inpci->proxyCertPathLengthConstraint)
00897 indepthlen = ASN1_INTEGER_get(inpci->proxyCertPathLengthConstraint);
00898 DEBUG("IN depth length: "<<indepthlen);
00899 }
00900
00901 xpiext = 0;
00902 }
00903
00904
00905 if (indepthlen > -1) {
00906 if ((pci->proxyCertPathLengthConstraint = ASN1_INTEGER_new())) {
00907 int depthlen = (indepthlen > 0) ? (indepthlen-1) : 0;
00908 ASN1_INTEGER_set(pci->proxyCertPathLengthConstraint, depthlen);
00909 } else {
00910 PRINT("could not set the path length contrain");
00911 return -kErrPX_SetPathDepth;
00912 }
00913 }
00914
00915
00916 X509_EXTENSION *ext = X509_EXTENSION_new();
00917 if (!ext) {
00918 PRINT("could not create extension object");
00919 return -kErrPX_NoResources;
00920 }
00921
00922 ext->value->length = i2d_gsiProxyCertInfo(pci, 0);
00923 if (!(ext->value->data = (unsigned char *)malloc(ext->value->length+1))) {
00924 PRINT("could not allocate data field for extension");
00925 return -kErrPX_NoResources;
00926 }
00927 unsigned char *pp = ext->value->data;
00928 if ((i2d_gsiProxyCertInfo(pci, &pp)) <= 0) {
00929 PRINT("problem converting data for extension");
00930 return -kErrPX_Error;
00931 }
00932
00933 #ifndef R__SSL_096
00934
00935
00936 ASN1_OBJECT *obj = OBJ_nid2obj(OBJ_create(gsiProxyCertInfo_OID,
00937 "gsiProxyCertInfo_OID","GSI ProxyCertInfo OID"));
00938 #else
00939
00940
00941 ASN1_OBJECT *obj = OBJ_txt2obj_fix(gsiProxyCertInfo_OID, 1);
00942 #endif
00943 if (!obj || X509_EXTENSION_set_object(ext, obj) != 1) {
00944 PRINT("could not set extension name");
00945 return -kErrPX_SetAttribute;
00946 }
00947
00948 if (X509_EXTENSION_set_critical(ext, 1) != 1) {
00949 PRINT("could not set extension critical flag");
00950 return -kErrPX_SetAttribute;
00951 }
00952
00953 STACK_OF(X509_EXTENSION) *esk = sk_X509_EXTENSION_new_null();
00954 if (!esk) {
00955 PRINT("could not create stack for extensions");
00956 return -kErrPX_NoResources;
00957 }
00958 if (sk_X509_EXTENSION_push(esk, ext) != 1) {
00959 PRINT("could not push the extension in the stack");
00960 return -kErrPX_Error;
00961 }
00962
00963 if (!(X509_REQ_add_extensions(xro, esk))) {
00964 PRINT("problem adding extension");
00965 return -kErrPX_SetAttribute;
00966 }
00967
00968
00969 if (!(X509_REQ_sign(xro, ekro, EVP_md5()))) {
00970 PRINT("problems signing the request");
00971 return -kErrPX_Signing;
00972 }
00973
00974
00975 *xcro = new XrdCryptosslX509Req(xro);
00976 *kcro = new XrdCryptosslRSA(ekro);
00977
00978
00979 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
00980 sk_X509_EXTENSION_free(esk);
00981 #else
00982 sk_free(esk);
00983 #endif
00984
00985
00986 return 0;
00987 }
00988
00989
00990
00991 int XrdSslgsiX509SignProxyReq(XrdCryptoX509 *xcpi, XrdCryptoRSA *kcpi,
00992 XrdCryptoX509Req *xcri, XrdCryptoX509 **xcpo)
00993 {
00994
00995
00996 EPNAME("X509SignProxyReq");
00997
00998
00999 if (!xcpi || !kcpi || !xcri || !xcpo) {
01000 PRINT("invalid inputs");
01001 return -1;
01002 }
01003
01004
01005 int timeleft = xcpi->NotAfter() - (int)time(0);
01006 if (timeleft < 0) {
01007 PRINT("EEC certificate has expired");
01008 return -kErrPX_ExpiredEEC;
01009 }
01010
01011 X509 *xpi = (X509 *)(xcpi->Opaque());
01012
01013
01014 if (kcpi->status != XrdCryptoRSA::kComplete) {
01015 PRINT("inconsistent key loaded");
01016 return -kErrPX_BadEECkey;
01017 }
01018
01019 RSA *kpi = ((EVP_PKEY *)(kcpi->Opaque()))->pkey.rsa;
01020
01021
01022 EVP_PKEY *ekpi = EVP_PKEY_new();
01023 if (!ekpi) {
01024 PRINT("could not create a EVP_PKEY * instance - return");
01025 return -kErrPX_NoResources;
01026 }
01027 EVP_PKEY_set1_RSA(ekpi, kpi);
01028
01029
01030 X509_REQ *xri = (X509_REQ *)(xcri->Opaque());
01031
01032
01033 XrdOucString psbj = X509_NAME_oneline(X509_get_subject_name(xpi), 0, 0);
01034 XrdOucString rsbj = X509_NAME_oneline(X509_REQ_get_subject_name(xri), 0, 0);
01035 if (psbj.length() <= 0 || rsbj.length() <= 0) {
01036 PRINT("names undefined");
01037 return -kErrPX_BadNames;
01038 }
01039
01040
01041
01042 XrdOucString neecp(psbj);
01043 XrdOucString neecr(rsbj,0,rsbj.rfind("/CN=")-1);
01044 if (neecr.length() <= 0 || neecr.length() <= 0 || neecp != neecr) {
01045 if (xcri->Version() <= 10100) {
01046
01047 neecp.erase(psbj.rfind("/CN="));
01048 if (neecr.length() <= 0 || neecr.length() <= 0 || neecp != neecr) {
01049 PRINT("Request subject not in the form '<EEC subject> + /CN=<serial>'");
01050 PRINT(" Versn: "<<xcri->Version());
01051 PRINT(" Proxy: "<<neecp);
01052 PRINT(" SubRq: "<<neecr);
01053 return -kErrPX_BadNames;
01054 }
01055 } else {
01056 PRINT("Request subject not in the form '<issuer subject> + /CN=<serial>'");
01057 PRINT(" Versn: "<<xcri->Version());
01058 PRINT(" Proxy: "<<neecp);
01059 PRINT(" SubRq: "<<neecr);
01060 return -kErrPX_BadNames;
01061 }
01062 }
01063
01064
01065 XrdOucString sserial(rsbj,rsbj.rfind("/CN=")+4);
01066 unsigned int serial = (unsigned int)(strtol(sserial.c_str(), 0, 10));
01067
01068
01069 X509 *xpo = X509_new();
01070 if (!xpo) {
01071 PRINT("could not create certificate object for proxies");
01072 return -kErrPX_NoResources;
01073 }
01074
01075
01076 if (X509_set_version(xpo, 2L) != 1) {
01077 PRINT("could not set version");
01078 return -kErrPX_SetAttribute;
01079 }
01080
01081
01082 if (ASN1_INTEGER_set(X509_get_serialNumber(xpo), serial) != 1) {
01083 PRINT("could not set serial number");
01084 return -kErrPX_SetAttribute;
01085 }
01086
01087
01088 if (X509_set_subject_name(xpo, X509_REQ_get_subject_name(xri)) != 1) {
01089 PRINT("could not set subject name");
01090 return -kErrPX_SetAttribute;
01091 }
01092
01093
01094 if (X509_set_issuer_name(xpo, X509_get_subject_name(xpi)) != 1) {
01095 PRINT("could not set issuer name");
01096 return -kErrPX_SetAttribute;
01097 }
01098
01099
01100 if (X509_set_pubkey(xpo, X509_REQ_get_pubkey(xri)) != 1) {
01101 PRINT("could not set public key");
01102 return -kErrPX_SetAttribute;
01103 }
01104
01105
01106 if (!X509_gmtime_adj(X509_get_notBefore(xpo), 0)) {
01107 PRINT("could not set notBefore");
01108 return -kErrPX_SetAttribute;
01109 }
01110
01111
01112 if (!X509_gmtime_adj(X509_get_notAfter(xpo), timeleft)) {
01113 PRINT("could not set notAfter");
01114 return -kErrPX_SetAttribute;
01115 }
01116
01117
01118
01119 X509_EXTENSION *xpiext = 0;
01120 int npiext = X509_get_ext_count(xpi);
01121 int i = 0;
01122 int indepthlen = -1;
01123 for (i = 0; i< npiext; i++) {
01124 xpiext = X509_get_ext(xpi, i);
01125 char s[256] = {0};
01126 ASN1_OBJECT *obj = X509_EXTENSION_get_object(xpiext);
01127 if (obj)
01128 OBJ_obj2txt(s, sizeof(s), obj, 1);
01129 if (!strcmp(s, gsiProxyCertInfo_OID)) {
01130 unsigned char *p = xpiext->value->data;
01131 #ifdef R__SSL_GE_098
01132 gsiProxyCertInfo_t *inpci =
01133 d2i_gsiProxyCertInfo(0, (const unsigned char **)(&p), xpiext->value->length);
01134 #else
01135 gsiProxyCertInfo_t *inpci = d2i_gsiProxyCertInfo(0, &p, xpiext->value->length);
01136 #endif
01137 if (inpci &&
01138 inpci->proxyCertPathLengthConstraint)
01139 indepthlen = ASN1_INTEGER_get(inpci->proxyCertPathLengthConstraint);
01140 DEBUG("IN depth length: "<<indepthlen);
01141 }
01142
01143 xpiext = 0;
01144 }
01145
01146
01147
01148 STACK_OF(X509_EXTENSION) *xrisk = X509_REQ_get_extensions(xri);
01149
01150
01151 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
01152 int nriext = sk_X509_EXTENSION_num(xrisk);
01153 #else
01154 int nriext = sk_num(xrisk);
01155 #endif
01156 if (nriext != 1) {
01157 PRINT("missing or too many extensions in request");
01158 return -kErrPX_BadExtension;
01159 }
01160
01161 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
01162 X509_EXTENSION *xriext = sk_X509_EXTENSION_value(xrisk, 0);
01163 #else
01164 X509_EXTENSION *xriext = (X509_EXTENSION *)sk_value(xrisk, 0);
01165 #endif
01166 if (!xriext) {
01167 PRINT("could not get extensions from request");
01168 return -kErrPX_BadExtension;
01169 }
01170
01171 char s[256];
01172 OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(xriext), 1);
01173 if (strcmp(s, gsiProxyCertInfo_OID)) {
01174 PRINT("wrong extension found");
01175 return -kErrPX_BadExtension;
01176 }
01177
01178 int reqdepthlen = -1;
01179 unsigned char *p = xriext->value->data;
01180 #ifdef R__SSL_GE_098
01181 gsiProxyCertInfo_t *reqpci =
01182 d2i_gsiProxyCertInfo(0, (const unsigned char **)(&p), xriext->value->length);
01183 #else
01184 gsiProxyCertInfo_t *reqpci = d2i_gsiProxyCertInfo(0, &p, xriext->value->length);
01185 #endif
01186 if (reqpci &&
01187 reqpci->proxyCertPathLengthConstraint)
01188 reqdepthlen = ASN1_INTEGER_get(reqpci->proxyCertPathLengthConstraint);
01189 DEBUG("REQ depth length: "<<reqdepthlen);
01190
01191
01192 int outdepthlen = (reqdepthlen < indepthlen) ? reqdepthlen :
01193 (indepthlen - 1);
01194
01195
01196 gsiProxyCertInfo_t *pci = gsiProxyCertInfo_new();
01197 if (!pci) {
01198 PRINT("could not create structure for extension - return");
01199 return -kErrPX_NoResources;
01200 }
01201
01202
01203 if (outdepthlen > -1) {
01204 if ((pci->proxyCertPathLengthConstraint = ASN1_INTEGER_new())) {
01205 int depthlen = (outdepthlen > 0) ? (outdepthlen-1) : 0;
01206 ASN1_INTEGER_set(pci->proxyCertPathLengthConstraint, depthlen);
01207 } else {
01208 PRINT("could not set the path length contrain");
01209 return -kErrPX_SetPathDepth;
01210 }
01211 }
01212
01213 X509_EXTENSION *ext = X509_EXTENSION_new();
01214 if (!ext) {
01215 PRINT("could not create extension object");
01216 return -kErrPX_NoResources;
01217 }
01218
01219 ext->value->length = i2d_gsiProxyCertInfo(pci, 0);
01220 if (!(ext->value->data = (unsigned char *)malloc(ext->value->length+1))) {
01221 PRINT("could not allocate data field for extension");
01222 return -kErrPX_NoResources;
01223 }
01224 unsigned char *pp = ext->value->data;
01225 if ((i2d_gsiProxyCertInfo(pci, &pp)) <= 0) {
01226 PRINT("problem converting data for extension");
01227 return -kErrPX_Error;
01228 }
01229
01230 #ifndef R__SSL_096
01231
01232
01233 ASN1_OBJECT *obj = OBJ_nid2obj(OBJ_create(gsiProxyCertInfo_OID,
01234 "gsiProxyCertInfo_OID","GSI ProxyCertInfo OID"));
01235 #else
01236
01237
01238 ASN1_OBJECT *obj = OBJ_txt2obj_fix(gsiProxyCertInfo_OID, 1);
01239 #endif
01240 if (!obj || X509_EXTENSION_set_object(ext, obj) != 1) {
01241 PRINT("could not set extension name");
01242 return -kErrPX_SetAttribute;
01243 }
01244
01245 if (X509_EXTENSION_set_critical(ext, 1) != 1) {
01246 PRINT("could not set extension critical flag");
01247 return -kErrPX_SetAttribute;
01248 }
01249
01250
01251 if (X509_add_ext(xpo, ext, -1) != 1) {
01252 PRINT("could not add extension");
01253 return -kErrPX_SetAttribute;
01254 }
01255
01256
01257
01258 if (!(X509_sign(xpo, ekpi, EVP_md5()))) {
01259 PRINT("problems signing the certificate");
01260 return -kErrPX_Signing;
01261 }
01262
01263
01264 *xcpo = new XrdCryptosslX509(xpo);
01265
01266
01267 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
01268 sk_X509_EXTENSION_free(xrisk);
01269 #else
01270 sk_free(xrisk);
01271 #endif
01272
01273
01274 return 0;
01275 }