/* * File: ac-validate.c * Author: Markus Lorch * Purpose: A sample program to valiadate an attribute certificatge * using the supplemental routines in x509ac-supp.c for * OpenSSL and Stephen Henson's core AC support * THIS IS JUST MEANT AS AN EXAMPLE, THE CODE HAS NOT BEEN REVIEWED * FOR SECURITY PROBLEMS OR MEMORY LEAKS AND THE LIKE. * Version: 0.2 * Date: July 21, 2003 * License: This code is in the public domain. I.e. it can be used, * distributed, and modified freely as long as I am credited * as the originator. * Comments: Work on this code was funded by the Virginia Commenwealth * Security Center and the Department of Computer Science at * Virginia Tech */ #include #include #include #include #include #include #include "x509ac.h" #include "x509ac-supp.h" /* change this to fit your setup */ #define CA_DIR "/etc/grid-security/certificates/" /* no changes necessary below */ X509_NAME *acIssuer, *acHolder; EVP_PKEY *pkey = NULL; X509AC *ac; int verify_callback (int ok, X509_STORE_CTX * stor) { if (!ok) fprintf (stderr, "Error: %s\n", X509_verify_cert_error_string (stor->error)); return ok; } int main (int argc, char *argv[]) { X509AC *ac; X509 *issuer; X509_NAME *issuerSubjectName; char nameString[ONELINELEN]; X509_STORE *store; X509_STORE_CTX *verify_ctx; STACK_OF(X509) * issuer_certs; FILE *fp; int ret=1; OpenSSL_add_all_algorithms (); ERR_load_crypto_strings (); fprintf (stderr,"ac-validate, a sample attribute certificate validator tool for OpenSSL\n"); fprintf (stderr,"c2003 Markus Lorch \n"); fprintf (stderr,"Version 0.2, July 2003 \n"); /* check parameters or display usage string */ if((argc<3) || (argc>4)) { fprintf (stderr, "\nac-validate attempts to parse and validate the provided attribute certificate\n"); fprintf (stderr, "It writes informative messages to stderr and returns zero if validation was successful and one (1) if there were errors. \n\n"); fprintf (stderr, "ac-validate requires the following parameters:\n"); fprintf (stderr, "\tac - the file name of the attribute certificate\n"); fprintf (stderr, "\tissuer - the file name of the issuers identity certificate\n"); fprintf (stderr, "\tCA (optional) - the directory of the trusted CA certificates\n"); fprintf (stderr, "If no CA dir is provided the compiled in default will be used (see source)\n\n"); fprintf (stderr, "Usage: ac-validate ac.pem issuer.pem [CAdir]\n\n\n"); exit(1); } /* load the attribute certificate with our custom PEM_read_X509AC */ fprintf (stderr,"Loading the attribute certificate now \n"); if (!(fp = fopen (argv[1], "r"))) int_error ("Error reading attribute certificate file"); if (!(ac = PEM_read_X509AC (fp, NULL, NULL, NULL))) int_error ("Error reading attribute certificate file" ); fclose (fp); /* print a textual representation of the core fields of the AC */ X509AC_print(ac); /* for verification build a verification context for the attribute cert using configured CA locations and the issuer cert */ fprintf(stderr, "Now try and validate the AC and its Issuer Chain \n"); fprintf(stderr, "================================================ \n\n"); /* create the cert store and set the verify callback */ if (!(store = X509_STORE_new ())) int_error ("Error creating X509_STORE_CTX object"); X509_STORE_set_verify_cb_func (store, verify_callback); /* load the CA certificates */ if(argc==4) { /* use command line CA directory */ fprintf(stderr, "Using CA certificates from %s \n", argv[3]); if (X509_STORE_load_locations (store, NULL, argv[3]) != 1) int_error ("Error loading the CA file or directory"); } else { fprintf(stderr, "Using CA certificates from %s \n", CA_DIR); if (X509_STORE_load_locations (store, NULL, CA_DIR) != 1) int_error ("Error loading the CA file or directory"); } if (X509_STORE_set_default_paths (store) != 1) int_error ("Error loading the system-wide CA certificates"); /* create a verification context and initialize it */ if (!(verify_ctx = X509_STORE_CTX_new ())) int_error ("Error creating X509_STORE_CTX object"); /* load the issuer cert and put it in a stack */ if (!(fp = fopen (argv[2], "r"))) int_error ("Error reading issuer certificate file"); if (!(issuer = PEM_read_X509 (fp, NULL, NULL, NULL))) int_error ("Error reading issuer certificate in file"); fclose (fp); issuerSubjectName = X509_get_subject_name(issuer); if (!issuerSubjectName) int_error ("Error getting subject name"); X509_NAME_oneline(issuerSubjectName,nameString,ONELINELEN); fprintf (stderr,"Issuer subject: %s \n", nameString); issuer_certs = sk_X509_new_null(); sk_X509_push(issuer_certs, issuer); /* init our context, with NULL instead of the X509 cert to be verified, and add the issuer certs */ if (X509_STORE_CTX_init (verify_ctx, store, NULL, issuer_certs) != 1) int_error ("Error initializing verification context"); /* call verify, the context has been set up previously */ fprintf (stderr,"calling X509AC_verify_cert\n"); ret=X509AC_verify_cert(verify_ctx, ac); /* free all the stuff (there is much more I know)*/ sk_X509_free(issuer_certs); if(ret!=1) { int_error("Error verifying attribute certificate"); return 1; /* fail */ } else { fprintf(stderr,"AC verified successfully\n"); return 0; /* checks out */ } } /* end main */