XRootD
Loading...
Searching...
No Matches
XrdSecgsitest.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d S e c g s i t e s t . c c */
4/* */
5/* (c) 2005, G. Ganis / CERN */
6/* */
7/* This file is part of the XRootD software suite. */
8/* */
9/* XRootD is free software: you can redistribute it and/or modify it under */
10/* the terms of the GNU Lesser General Public License as published by the */
11/* Free Software Foundation, either version 3 of the License, or (at your */
12/* option) any later version. */
13/* */
14/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
15/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
16/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
17/* License for more details. */
18/* */
19/* You should have received a copy of the GNU Lesser General Public License */
20/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
21/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
22/* */
23/* The copyright holder's institutional names and contributor's names may not */
24/* be used to endorse or promote products derived from this software without */
25/* specific prior written permission of the institution or contributor. */
26/* */
27/******************************************************************************/
28
29//
30// Test program for XrdSecgsi
31//
32
33#include <cstdio>
34#include <cstdlib>
35#include <cstring>
36
37#include <sys/types.h>
38#include <pwd.h>
39
42#include "XrdSys/XrdSysError.hh"
43
44#include "XrdSut/XrdSutAux.hh"
45
52
54
56
58
59#include <openssl/x509v3.h>
60#include <openssl/x509.h>
61
62//
63// Globals
64
65// #define PRINT(x) {std::cerr <<x <<std::endl;}
67
72XrdOucString CAdir = "/etc/grid-security/certificates/";
73int CAnum = 0;
75int Dbg = 0;
76int Help = 0;
77
78//
79// For error logging and tracing
81static XrdSysError eDest(0,"gsitest_");
83
84#define PRTWIDTH 80
85static void pdots(const char *t, bool ok = 1)
86{
87 unsigned int i = 0;
88 unsigned int l = (t) ? strlen (t) : 0;
89 unsigned int np = PRTWIDTH - l - 8;
90 if (l > 0) {
91 printf("|| %s ", t);
92 } else {
93 printf("|| ");
94 }
95 for (; i < np ; i++) { printf("."); }
96 printf(" %s\n", (ok ? "PASSED" : "FAILED"));
97}
98static void pline(const char *t)
99{
100 unsigned int i = 0;
101 unsigned int l = (t) ? strlen (t) : 0;
102 unsigned int np = PRTWIDTH - l - 3;
103 if (l > 0) {
104 printf("|| %s ---", t);
105 } else {
106 printf("|| ----");
107 }
108 for (; i < np ; i++) { printf("-"); }
109 printf("\n");
110}
111
112static void printHelp()
113{
114 printf(" \n");
115 printf(" Basic test program for crypto functionality in relation to GSI.\n");
116 printf(" The program needs access to a user certificate file and its private key, and the related\n");
117 printf(" CA file(s); the CRL is downloaded using the information found in the CA certificate.\n");
118 printf(" The location of the files are the standard ones and they can modified by the standard\n");
119 printf(" environment variables:\n");
120 printf(" \n");
121 printf(" X509_USER_CERT [$HOME/.globus/usercert.pem] user certificate\n");
122 printf(" X509_USER_KEY [$HOME/.globus/userkey.pem] user private key\n");
123 printf(" X509_USER_PROXY [/tmp/x509up_u<uid>] user proxy\n");
124 printf(" X509_CERT_DIR [/etc/grid-security/certificates/] CA certificates and CRL directories\n");
125 printf(" \n");
126 printf(" Usage:\n");
127 printf(" xrdgsitest [-v,--verbose] [-h,--help] \n");
128 printf(" \n");
129 printf(" -h, --help Print this screen\n");
130 printf(" -v, --verbose Dump all details\n");
131 printf(" \n");
132 printf(" The output is a list of PASSED/FAILED test, interleaved with details when the verbose option\n");
133 printf(" is chosen.\n");
134 printf(" \n");
135}
136
137int main( int argc, char **argv )
138{
139 // Test implemented functionality
140 EPNAME("main");
141 char cryptomod[64] = "ssl";
142 char outname[256] = {0};
143
144 // Basic argument parsing
145 int i = 1;
146 for (; i < argc; i++) {
147 // Verbosity level
148 if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) Dbg = 1;
149 if (!strcmp(argv[i], "-vv")) Dbg = 2;
150 // Help
151 if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) Help = 1;
152 }
153
154 // Print help if required
155 if (Help) {
156 printHelp();
157 exit(0);
158 }
159
160 //
161 // Initiate error logging and tracing
163 if (!gsiTrace)
164 gsiTrace = new XrdOucTrace(&eDest);
165 if (gsiTrace && Dbg > 0) {
166 // Medium level
168 }
169 //
170 // Set debug flags in other modules
171 kXR_int32 tracesut = (Dbg > 0) ? sutTRACE_Debug : 0;
172 kXR_int32 tracecrypto = (Dbg > 0) ? cryptoTRACE_Debug : 0;
173 XrdSutSetTrace(tracesut);
174 XrdCryptoSetTrace(tracecrypto);
175
176 //
177 // Determine application name
178 char *p = argv[0];
179 int k = strlen(argv[0]);
180 while (k--)
181 if (p[k] == '/') break;
182 strcpy(outname,p+k+1);
183
184 //
185 // Load the crypto factory
187 pdots(" Cannot instantiate factory", 0);
188 exit(1);
189 }
190 if (Dbg > 0)
192
193 pline("");
194 pline("Crypto functionality tests for GSI");
195 pline("");
196
197 //
198 // Find out the username and locate the relevant certificates and directories
199 struct passwd *pw = getpwuid(geteuid());
200 if (!pw) {
201 pdots(" Could not resolve user info - exit", 0);
202 exit(1);
203 }
204 NOTIFY("effective user is : "<<pw->pw_name<<", $HOME : "<<pw->pw_dir);
205
206 //
207 // User certificate
208 EEcert = pw->pw_dir;
209 EEcert += "/.globus/usercert.pem";
210 if (getenv("X509_USER_CERT")) EEcert = getenv("X509_USER_CERT");
211 NOTIFY("user EE certificate: "<<EEcert);
213 if (xEE) {
214 if (Dbg > 0) xEE->Dump();
215 } else {
216 pdots(" Problems loading user EE cert", 0);
217 }
218 if (xEE) pdots("Loading EEC", 1);
219
220 //
221 // User key
222 EEkey = pw->pw_dir;
223 EEkey += "/.globus/userkey.pem";
224 if (getenv("X509_USER_KEY")) EEkey = getenv("X509_USER_KEY");
225 NOTIFY("user EE key: "<<EEkey);
226 //
227 // User Proxy certificate
228 PXcert = "/tmp/x509up_u";
229 PXcert += (int) pw->pw_uid;
230 if (getenv("X509_USER_PROXY")) PXcert = getenv("X509_USER_PROXY");
231 NOTIFY("user proxy certificate: "<<PXcert);
233 if (xPX) {
234 if (Dbg > 0) xPX->Dump();
235 } else {
236 pdots(" Problems loading user proxy cert", 0);
237 }
238 if (xPX) pdots("Loading User Proxy", 1);
239
240 //
241 pline("");
242 pline("Recreate the proxy certificate");
243 XrdProxyOpt_t *pxopt = 0; // defaults
245 XrdCryptoRSA *kPXp = 0;
246 XrdCryptoX509 *xPXp = 0;
247 X509_EXTENSION *ext = 0;
249 pxopt, cPXp, &kPXp, PXcert.c_str());
250 if (prc == 0) {
251 if (Dbg > 0) cPXp->Dump();
252 if ((xPXp = (XrdCryptoX509 *)(cPXp->Begin()))) {
253 pdots("Recreating User Proxy", 1);
254 if ((ext = (X509_EXTENSION *)(xPXp->GetExtension("1.3.6.1.4.1.3536.1.222")))) {
255 pdots("proxyCertInfo extension OK", 1);
256 }
257 }
258 } else {
259 pdots("Recreating User Proxy", 0);
260 exit(1);
261 }
262
263 // use recreated proxy certificate if it a proxy was not already set
264 if (!xPX)
265 xPX = xPXp;
266
267 //
268 pline("");
269 pline("Load CA certificates");
270 // Load CA certificates now
271 XrdCryptoX509 *xCA[5], *xCAref = 0;
272 if (getenv("X509_CERT_DIR")) CAdir = getenv("X509_CERT_DIR");
273 if (!CAdir.endswith("/")) CAdir += "/";
274 XrdCryptoX509 *xc = xEE;
275 bool rCAfound = 0;
276 int nCA = 0;
277 while (!rCAfound && nCA < 5) {
278 CAcert[nCA] = CAdir;
279 CAcert[nCA] += xc->IssuerHash();
280 NOTIFY("issuer CA certificate path "<<CAcert[nCA]);
281 xCA[nCA] = gCryptoFactory->X509(CAcert[nCA].c_str());
282 if (xCA[nCA]) {
283 if (Dbg > 0) xCA[nCA]->Dump();
284 pdots("Loading CA certificate", 1);
285 } else {
286 pdots("Loading CA certificate", 0);
287 rCAfound = 0;
288 break;
289 }
290 // Check if self-signed
291 if (!strcmp(xCA[nCA]->IssuerHash(), xCA[nCA]->SubjectHash())) {
292 rCAfound = 1;
293 break;
294 }
295 // If not, parse the issuer ...
296 xc = xCA[nCA];
297 nCA++;
298 }
299
300 //
301 pline("");
302 pline("Testing ParseFile");
304 XrdCryptoRSA *key = 0;
306 if (ParseFile) {
307 int nci = (*ParseFile)(PXcert.c_str(), chain, 0);
308 if (!(key = chain->Begin()->PKI())) {
309 pdots("getting PKI", 0);
310 }
311 NOTIFY(nci <<" certificates found parsing file");
312 if (Dbg > 0) chain->Dump();
313 int jCA = nCA + 1;
314 while (jCA--) {
315 chain->PushBack(xCA[jCA]);
316 }
317 if (Dbg > 0) chain->Dump();
318 int rorc = chain->Reorder();
319 if (rCAfound) {
320 if (Dbg > 0) chain->Dump();
321 pdots("Chain reorder: ", (rorc != -1));
323 int verc = chain->Verify(ecod);
324 pdots("Chain verify: ", verc);
325 } else {
326 pdots("Full CA chain verification", 0);
327 }
328 } else {
329 pdots("attaching to X509ParseFile", 0);
330 exit (1);
331 }
332
333 //
334 pline("");
335 pline("Testing ExportChain");
337 XrdSutBucket *chainbck = 0;
338 if (ExportChain && chain->End()) {
339 chainbck = (*ExportChain)(chain, 0);
340 pdots("Attach to X509ExportChain", 1);
341 } else {
342 pdots("Attach to X509ExportChain", 0);
343 exit (1);
344 }
345 //
346 pline("");
347 pline("Testing Chain Import");
349 if (!ParseBucket) pdots("attaching to X509ParseBucket", 0);
350 // Init new chain with CA certificate
351 int jCA = nCA;
352 XrdCryptoX509Chain *CAchain = new XrdCryptoX509Chain(xCA[jCA]);
353 while (jCA) { CAchain->PushBack(xCA[--jCA]); }
354 if (ParseBucket && CAchain) {
355 int nci = (*ParseBucket)(chainbck, CAchain);
356 NOTIFY(nci <<" certificates found parsing bucket");
357 if (Dbg > 0) CAchain->Dump();
358 int rorc = CAchain->Reorder();
359 pdots("Chain reorder: ", (rorc != -1));
360 if (Dbg > 0) CAchain->Dump();
362 int verc = CAchain->Verify(ecod);
363 pdots("Chain verify: ", verc);
364 } else {
365 pdots("creating new X509Chain", 0);
366 exit (1);
367 }
368
369 //
370 pline("");
371 pline("Testing GSI chain import and verification");
372 // Init new GSI chain with CA certificate
373 jCA = nCA;
375 while (jCA) { GSIchain->PushBack(xCA[--jCA]); }
376 if (ParseBucket && GSIchain) {
377 int nci = (*ParseBucket)(chainbck, GSIchain);
378 NOTIFY(nci <<" certificates found parsing bucket");
379 if (Dbg > 0) GSIchain->Dump();
381 x509ChainVerifyOpt_t vopt = { kOptsRfc3820, 0, -1, 0};
382 int verc = GSIchain->Verify(ecod, &vopt);
383 pdots("GSI chain verify: ", verc);
384 if (!verc) NOTIFY("GSI chain verify ERROR: "<<GSIchain->LastError());
385 if (Dbg > 0) GSIchain->Dump();
386 } else {
387 pdots("Creating new gsiX509Chain", 0);
388 exit (1);
389 }
390
391 //
392 pline("");
393 pline("Testing GSI chain copy");
394 // Init new GSI chain with CA certificate
396 if (GSInew) {
397 if (Dbg > 0) GSInew->Dump();
399 x509ChainVerifyOpt_t vopt = { kOptsRfc3820, 0, -1, 0};
400 int verc = GSInew->Verify(ecod, &vopt);
401 if (!verc) NOTIFY("GSI chain copy verify ERROR: "<<GSInew->LastError());
402 pdots("GSI chain verify: ", verc);
403 if (Dbg > 0) GSInew->Dump();
404 } else {
405 pdots("Creating new gsiX509Chain with copy", 0);
406 exit (1);
407 }
408
409 //
410 pline("");
411 pline("Testing Cert verification");
413 if (VerifyCert) {
414 bool ok;
415 jCA = nCA;
416 while (jCA >= 0) {
417 ok = xEE->Verify(xCA[jCA]);
418 NOTIFY( ": verify cert: EE signed by CA? " <<ok<<" ("<<xCA[jCA]->Subject()<<")");
419 if (ok) xCAref = xCA[jCA];
420 jCA--;
421 }
422 pdots("verify cert: EE signed by CA", (xCAref ? 1 : 0));
423 ok = xPX->Verify(xEE);
424 pdots("verify cert: PX signed by EE", ok);
425 jCA = nCA;
426 bool refok = 0;
427 while (jCA >= 0) {
428 ok = xPX->Verify(xCA[jCA]);
429 NOTIFY( ": verify cert: PX signed by CA? " <<ok<<" ("<<xCA[jCA]->Subject()<<")");
430 if (!refok && ok) refok = 1;
431 jCA--;
432 }
433 pdots("verify cert: PX not signed by CA", !refok);
434 } else {
435 pdots("Attaching to X509VerifyCert", 0);
436 exit (1);
437 }
438
439
440 //
441 pline("");
442 pline("Testing request creation");
443 XrdCryptoX509Req *rPXp = 0;
444 XrdCryptoRSA *krPXp = 0;
445 prc = gCryptoFactory->X509CreateProxyReq()(xPX, &rPXp, &krPXp);
446 if (prc == 0) {
447 pdots("Creating request", 1);
448 if (Dbg > 0) rPXp->Dump();
449 } else {
450 pdots("Creating request", 0);
451 exit(1);
452 }
453
454 //
455 pline("");
456 pline("Testing request signature");
457 XrdCryptoX509 *xPXpp = 0;
458 prc = gCryptoFactory->X509SignProxyReq()(xPX, kPXp, rPXp, &xPXpp);
459 if (prc == 0) {
460 if (Dbg > 0) xPXpp->Dump();
461 xPXpp->SetPKI((XrdCryptoX509data) krPXp->Opaque());
462 bool extok = 0;
463 if ((ext = (X509_EXTENSION *)xPXpp->GetExtension(gsiProxyCertInfo_OID))) extok = 1;
464 pdots("Check proxyCertInfo extension", extok);
465 } else {
466 pdots("Signing request", 0);
467 exit(1);
468 }
469
470 //
471 pline("");
472 pline("Testing export of signed proxy");
473 PPXcert = PXcert;
474 PPXcert += "p";
475 NOTIFY(": file for signed proxy chain: "<<PPXcert);
477 // Init the proxy chain
478 XrdCryptoX509Chain *PXchain = new XrdCryptoX509Chain(xPXpp);
479 PXchain->PushBack(xPX);
480 PXchain->PushBack(xEE);
481 if (ChainToFile && PXchain) {
482 if ((*ChainToFile)(PXchain, PPXcert.c_str()) != 0) {
483 NOTIFY(": problems saving signed proxy chain to file: "<<PPXcert);
484 pdots("Saving signed proxy chain to file", 0);
485 } else {
486 pdots("Saving signed proxy chain to file", 1);
487 }
488 } else {
489 pdots("Creating new X509Chain", 0);
490 exit (1);
491 }
492
493 //
494 pline("");
495 pline("Testing CRL identification");
496 X509_EXTENSION *crlext = 0;
497 if (xCAref) {
498 if ((crlext = (X509_EXTENSION *)xCAref->GetExtension("crlDistributionPoints"))) {
499 pdots("Check CRL distribution points extension OK", 1);
500 } else {
501 pdots("Getting extension", 0);
502 }
503 }
504
505 //
506 pline("");
507 pline("Testing CRL loading");
508 XrdCryptoX509Crl *xCRL1 = gCryptoFactory->X509Crl(xCAref);
509 if (xCRL1) {
510 if (Dbg > 0) xCRL1->Dump();
511 pdots("Loading CA1 crl", 1);
512 // Verify CRL signature
513 bool crlsig = 0, xsig = 0;
514 for (jCA = 0; jCA <= nCA; jCA++) {
515 xsig = xCRL1->Verify(xCA[jCA]);
516 NOTIFY( ": CRL signature OK? "<<xsig<<" ("<<xCA[jCA]->Subject()<<")");
517 if (!crlsig && xsig) crlsig = 1;
518 }
519 pdots("CRL signature OK", crlsig);
520 // Verify a serial number
521 bool snrev = xCRL1->IsRevoked(25, 0);
522 NOTIFY( ": SN: 25 revoked? "<<snrev);
523 // Verify another serial number
524 snrev = xCRL1->IsRevoked(0x20, 0);
525 NOTIFY( ": SN: 32 revoked? "<<snrev);
526 } else {
527 pdots("Loading CA1 crl", 0);
528 }
529
530 pline("");
531 exit(0);
532}
int kXR_int32
Definition XPtypes.hh:89
#define EPNAME(x)
#define TRACE_Debug
void XrdCryptoSetTrace(kXR_int32 trace)
#define cryptoTRACE_Debug
int(* XrdCryptoX509ChainToFile_t)(XrdCryptoX509Chain *, const char *)
#define gsiProxyCertInfo_OID
XrdSutBucket *(* XrdCryptoX509ExportChain_t)(XrdCryptoX509Chain *, bool)
int(* XrdCryptoX509ParseBucket_t)(XrdSutBucket *, XrdCryptoX509Chain *)
bool(* XrdCryptoX509VerifyCert_t)(XrdCryptoX509 *c, XrdCryptoX509 *r)
int(* XrdCryptoX509ParseFile_t)(const char *fname, XrdCryptoX509Chain *, const char *)
void * XrdCryptoX509data
const int kOptsRfc3820
#define TRACE_Authen
XrdCryptoX509ParseFile_t ParseFile
#define NOTIFY(y)
XrdOucString CAdir
XrdOucString CAcert[5]
int main(int argc, char **argv)
XrdOucString PPXcert
#define PRTWIDTH
static void pline(const char *t)
XrdOucString PXcert
static void printHelp()
static XrdSysLogger Logger
int Help
XrdCryptoFactory * gCryptoFactory
int CAnum
XrdOucTrace * gsiTrace
static XrdSysError eDest(0,"gsitest_")
static void pdots(const char *t, bool ok=1)
int Dbg
XrdOucString EEcert
XrdOucString EEkey
void XrdSutSetTrace(kXR_int32 trace)
Definition XrdSutAux.cc:93
#define sutTRACE_Debug
Definition XrdSutAux.hh:99
virtual XrdCryptoX509ParseBucket_t X509ParseBucket()
virtual XrdCryptoX509CreateProxyReq_t X509CreateProxyReq()
virtual XrdCryptoX509 * X509(const char *cf, const char *kf=0)
virtual void SetTrace(kXR_int32 trace)
virtual XrdCryptoX509ParseFile_t X509ParseFile()
virtual XrdCryptoX509CreateProxy_t X509CreateProxy()
virtual XrdCryptoX509ChainToFile_t X509ChainToFile()
virtual XrdCryptoX509Crl * X509Crl(const char *crlfile, int opt=0)
static XrdCryptoFactory * GetCryptoFactory(const char *factoryname)
virtual XrdCryptoX509SignProxyReq_t X509SignProxyReq()
virtual XrdCryptoX509ExportChain_t X509ExportChain()
virtual XrdCryptoX509VerifyCert_t X509VerifyCert()
virtual XrdCryptoRSAdata Opaque()
virtual bool Verify(EX509ChainErr &e, x509ChainVerifyOpt_t *vopt=0)
const char * LastError() const
XrdCryptoX509 * Begin()
void PushBack(XrdCryptoX509 *c)
XrdCryptoX509 * End() const
virtual void Dump()
virtual bool IsRevoked(int serialnumber, int when)
virtual bool Verify(XrdCryptoX509 *ref)
virtual void Dump()
virtual bool Verify(XrdCryptoX509 *ref)
virtual XrdCryptoX509data GetExtension(const char *oid)
virtual void SetPKI(XrdCryptoX509data pki)
virtual void Dump()
virtual XrdCryptoRSA * PKI()
virtual const char * IssuerHash(int)
bool Verify(EX509ChainErr &e, x509ChainVerifyOpt_t *vopt=0)
bool endswith(char c)
const char * c_str() const
XrdSysLogger * logger(XrdSysLogger *lp=0)