char * PKI_get_ca_service( PKI_X509_CERT *caCert, char *srv, char *url_s ) { PKI_STACK *services = NULL; PKI_STACK *ret_sk = NULL; char *ret_s = NULL; if( !srv || !caCert ) return ( NULL ); if((services = PKI_STACK_new_null()) == NULL ) { PKI_log_debug("Stack creation error in %s:%d", __FILE__, __LINE__ ); return ( NULL ); } PKI_log_debug ("Getting Address for %s", srv ); PKI_STACK_push( services, strdup(srv) ); ret_sk = PKI_get_ca_resources( caCert, NULL, NULL, services, url_s ); PKI_STACK_free_all( services ); if( !ret_sk ) { PKI_log_debug("No address returned for %s", srv ); return ( NULL ); } else { ret_s = PKI_STACK_pop( ret_sk ); PKI_STACK_free_all( ret_sk ); } PKI_log_debug ( "Returned address %s", ret_s ); return ( ret_s ); }
PKI_STACK *PKI_CONFIG_get_search_paths ( char *dir ) { char *homedir = NULL; char buff[BUFF_MAX_SIZE]; PKI_STACK *list = NULL; int i = 0; // PKI_log_debug("get_search_paths() start"); if((list = PKI_STACK_new_null()) == NULL ) { return ( NULL ); } /* If passed as an argument, dir is the first dir in the search path */ if( dir ) { PKI_STACK_push( list, strdup(dir) ); return list; } /* Check for the HOME environment variable */ if(( homedir = getenv("HOME")) != NULL ) { memset(buff, '\x0', sizeof( buff )); snprintf( buff, sizeof( buff), "%s" LIBPKI_PATH_SEPARATOR ".libpki", homedir ); /* Adds the user's home directory to the search path */ PKI_STACK_push ( list, strdup( buff ) ); }; /* Adds all the 'default' libpki config directories */ for( i = 0 ; i < PKI_DEF_CONF_DIRS_SIZE; i++ ) { PKI_STACK_push ( list, strdup(def_conf_dirs[i]) ); } // PKI_log_debug("get_search_paths()::Entries in list %d", // PKI_STACK_elements ( list )); // PKI_log_debug("get_search_paths()::ENDING"); return ( list ); }
PKI_STACK * PKI_get_cert_service_sk( PKI_X509_CERT *cert, char *srv, char *url_s ) { PKI_STACK *services = NULL; PKI_STACK *ret_sk = NULL; if( !srv || !cert ) return ( NULL ); if((services = PKI_STACK_new_null()) == NULL ) { PKI_log_debug("Stack creation error"); return ( NULL ); } PKI_STACK_push( services, strdup( srv )); ret_sk = PKI_get_ca_resources( NULL, NULL, cert, services, url_s ); PKI_STACK_free_all( services ); return ( ret_sk ); }
PKI_STACK * PKI_X509_CERT_get_email (const PKI_X509_CERT *x ) { PKI_STACK *sk = NULL; PKI_X509_NAME_RDN **list = NULL; const PKI_X509_NAME *name = NULL; // PKI_X509_EXTENSION_STACK * ext_list = NULL; PKI_X509_EXTENSION * ext = NULL; if(!x || !x->value) return NULL; if((sk = PKI_STACK_new_null()) == NULL) return NULL; name = PKI_X509_CERT_get_data(x, PKI_X509_DATA_SUBJECT); // Maybe we find something in the DN... if(name) { int curr = 0; PKI_X509_NAME_RDN *el = NULL; list = PKI_X509_NAME_get_list(name, PKI_X509_NAME_TYPE_EMAIL); for(curr = 0; el != NULL; curr++ ) { el = list[curr]; PKI_STACK_push( sk, PKI_X509_NAME_RDN_value(el)); } } if((ext = PKI_X509_CERT_get_extension_by_name(x, "subjectAltName")) != NULL) { PKI_log_debug("Got subjectAltName: Code Still Missing!"); } PKI_log_debug("Code still missing!"); return sk; }
PKI_STACK * PKI_CONFIG_get_stack_value ( PKI_CONFIG *doc, char *search ) { PKI_CONFIG_ELEMENT_STACK *sk = NULL; PKI_STACK *ret = NULL; PKI_CONFIG_ELEMENT *curr = NULL; int size = -1; char *val = NULL; if (( sk = PKI_CONFIG_get_element_stack ( doc, search)) == NULL ) { return NULL; } if((size = PKI_STACK_CONFIG_ELEMENT_elements ( sk )) <= 0 ) { return NULL; } ret = PKI_STACK_new( NULL ); while ((curr = PKI_STACK_CONFIG_ELEMENT_pop ( sk )) != NULL ) { if( curr && curr->type == XML_ELEMENT_NODE ) { if((val = PKI_CONFIG_get_element_value ( curr )) != NULL ) { PKI_STACK_push ( ret, strdup (val) ); } } } PKI_STACK_free_all ( sk ); return ret; /* xmlXPathContext *xpathCtx = NULL; xmlXPathObject *xpathObj = NULL; xmlNodeSet *nodes = NULL; PKI_STACK *sk = NULL; char *val = NULL; int size = 0; int i = 0; char *my_search = NULL; if( !doc || !search ) return (NULL); xpathCtx = xmlXPathNewContext(doc); if(xpathCtx == NULL) { PKI_log_debug("ERROR, unable to create new XPath context!\n"); return(NULL); } my_search = _xml_search_namespace_add ( search ); xmlXPathRegisterNs(xpathCtx, (xmlChar *) PKI_NAMESPACE_PREFIX, (xmlChar *) PKI_NAMESPACE_HREF); xpathObj = xmlXPathEvalExpression( (xmlChar *) my_search, xpathCtx); PKI_Free ( my_search ); if( xpathObj == NULL ) { xmlXPathFreeContext(xpathCtx); return(NULL); } nodes = xpathObj->nodesetval; if( nodes ) { size = nodes->nodeNr; } sk = PKI_STACK_new(NULL); for( i=0; i < size; i++ ) { PKI_CONFIG_ELEMENT *curr = NULL; curr = nodes->nodeTab[i]; val = (char *) xmlNodeListGetString(doc, curr->xmlChildrenNode, 1); PKI_STACK_push( sk, strdup( val )); } xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); return (sk); */ }
PKI_STACK *PKI_X509_CERT_get_cdp (const PKI_X509_CERT *x) { STACK_OF(DIST_POINT) *sk_cdp = NULL; DIST_POINT *cdp = NULL; STACK_OF(CONF_VALUE) *sk_val = NULL; CONF_VALUE *v = NULL; PKI_STACK *ret = NULL; PKI_X509_CERT_VALUE *cert = NULL; char *tmp_s = NULL; int k = -1; int i = 0; if ( !x || !x->value ) return NULL; cert = (PKI_X509_CERT_VALUE *) x->value; if(( sk_cdp = X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL)) == NULL ) { return NULL; } /* Should we go through the whole stack ? Maybe, now we just take the first value... */ if ( sk_DIST_POINT_num ( sk_cdp ) < 1 ) { return NULL; } for ( i = 0 ; i < sk_DIST_POINT_num ( sk_cdp ); i++ ) { cdp = sk_DIST_POINT_value ( sk_cdp, i ); if( cdp->distpoint ) { if(cdp->distpoint->type == 0) { if( cdp->distpoint->name.fullname ) { sk_val = i2v_GENERAL_NAMES(NULL, cdp->distpoint->name.fullname, sk_val); k=0; for( ;; ) { v = sk_CONF_VALUE_value( sk_val, k++ ); if( v == NULL ) break; if( strncmp_nocase("URI", v->name, 3) == 0 ) { PKI_log_debug( "INFO::Found " "CDP in cert %s:%s", v->name, v->value ); if (!ret) { ret = PKI_STACK_new_null (); if (!ret) return NULL; } tmp_s = strdup( v->value ); PKI_STACK_push ( ret, tmp_s ); } } // sk_CONF_VALUE_free(sk_val); } } // else { // DIST_POINT_free( cdp ); // sk_DIST_POINT_free( sk_cdp ); //} } } return ret; }
PKI_MEM_STACK *URL_get_data_pkcs11_url ( URL *url, ssize_t size ) { #ifdef HAVE_P11 // PKCS11_CTX *ctx = NULL; PKCS11_SLOT *slots = NULL; PKCS11_TOKEN *tk = NULL; char *libfile = NULL; int num = 0; int i = 0; char * search_label = NULL; char * search_id = NULL; char * search_slot = NULL; char * search_slotid = NULL; PKI_MEM *tmp_mem = NULL; PKI_MEM_STACK *sk = NULL; if( !url ) return (NULL); /* if((libfile = pkcs11_parse_url_libpath ( url )) == NULL ) { return( NULL ); } */ /* slot = pkcs11_parse_url_slot ( url ); id = pkcs11_parse_url_id ( url ); */ if( ctx == NULL ) { if((ctx = PKCS11_CTX_new ()) == NULL ) { return(NULL); } PKI_log_debug("Loading %s Library", url->addr ); if(( i = PKCS11_CTX_load(ctx, url->addr)) != 0 ) { PKI_log_err("Can not load library %s [err::%d]", url->addr, i); // ERR_print_errors_fp( stderr ); } } if( PKCS11_enumerate_slots( ctx, &slots, &num ) == -1 ) { PKI_log_err ("Can not enumerate slots"); goto err; }; if(( sk = PKI_STACK_MEM_new()) == NULL ) { goto err; } search_slot = pkcs11_parse_url_getval( url, "slot" ); search_slotid = pkcs11_parse_url_getval( url, "slotid" ); search_label = pkcs11_parse_url_getval( url, "label" ); search_id = pkcs11_parse_url_getval( url, "id" ); if( search_slot ) PKI_log_debug("DEBUG::PKCS11::SEARCH::SLOT => %s\n", search_slot); if( search_slotid ) PKI_log_debug("DEBUG::PKCS11::SEARCH::SLOTID => %s\n", search_slotid); if( search_label ) PKI_log_debug("DEBUG::PKCS11::SEARCH::LABEL => %s\n", search_label); if( search_id ) PKI_log_debug("DEBUG::PKCS11::SEARCH::ID => %s\n", search_id); for(i = 0; i < num; i++ ) { BIO *mem = NULL; BUF_MEM *mem_buf = NULL; PKCS11_CERT *certs = NULL; PKCS11_SLOT *p = NULL; PKCS11_CERT *x = NULL; PKCS11_KEY *keyList = NULL; PKCS11_KEY *key = NULL; EVP_PKEY *evp_pkey = NULL; int n = 0; int t = 0; int n_objs = 0; int p_ret = 0; p = &slots[i]; if((!p) || ((tk = p->token) == NULL) ) { continue; } if( (search_slot) && ( strncmp_nocase( search_slot, tk->label, strlen(search_slot) == 0) )) { continue; } if( (search_slotid) && ( atoi(search_slotid) != i )) { PKI_log_debug("PKCS11::SLOTID is %s (%d), curr is %d\n", search_slotid, atoi(search_slotid), i); continue; } if( strncmp_nocase( url->attrs, "cert", 4 ) == 0) { PKI_log_debug("PKCS11::CERT DATATYPE SELECTED!\n"); if((mem = BIO_new(BIO_s_mem())) == NULL ) { goto err; } /* Get the list of certificates in the slot */ p_ret = PKCS11_enumerate_certs( tk, &certs, &n_objs); for( n = 0; n < n_objs; n++ ) { /* Pointer to the current certificate */ x = &certs[n]; PKI_log_debug("PKCS11::CERT label=%s\n", x->label); PKI_log_debug("PKCS11::CERT id="); for( t = 0; t < x->id_len; t ++ ) { printf("%c", x->id[t] ); } printf("\n"); if( (search_label) && (strncmp_nocase( search_label, x->label, strlen( search_label)) != 0 )){ PKI_log_debug("PKCS11::LABEL does not" "match, SKIPPING!!!!\n"); continue; } if( search_id ) { int stop = 0; for( t = 0; t < x->id_len; t ++ ) { if( search_id[t] != x->id[t] ) { stop = 1; break; } } if( stop == 1 ) { printf("DEBUG::PKCS11::ID does not" "match, SKIPPING!!!!\n"); continue; } } /* Write the cert in PEM format to memory */ p_ret = PEM_write_bio_X509( mem, x->x509 ); /* Get the pointer to the memory buffer */ BIO_get_mem_ptr( mem, &mem_buf ); /* Push a PKI_MEM buffer on the stack */ tmp_mem = PKI_MEM_new_null(); PKI_MEM_add ( tmp_mem, mem_buf->data, mem_buf->length); PKI_STACK_push( sk, tmp_mem ); } /* Free the temp memory buffer */ if( mem ) BIO_free( mem ); } else if (strncmp_nocase( url->attrs, "key", 3) == 0 ) { char *pin = NULL; PKI_log_debug("PKCS11::KEY DATATYPE SELECTED!\n"); pin = pkcs11_parse_url_getval( url, "pin" ); if ( (tk->loginRequired == 1) && (pin != NULL ) ) { p_ret = PKCS11_login ( p, 0, pin ); PKI_log_debug("PKCS11::LOGIN Result %d\n", p_ret ); } if((mem = BIO_new(BIO_s_mem())) == NULL ) { goto err; } p_ret = PKCS11_enumerate_keys ( tk, &keyList, &n_objs ); for( n = 0; n < n_objs; n++ ) { key = &keyList[n]; printf("DEBUG::PKCS11::KEY label=%s\n", key->label); printf("DEBUG::PKCS11::KEY id="); for( t = 0; t < key->id_len; t ++ ) { printf("%c", key->id[t] ); } printf("\n"); if( (search_label) && (strncmp_nocase( search_label, x->label, strlen( search_label)) != 0 )){ printf("DEBUG::PKCS11::LABEL does not" "match, SKIPPING!!!!\n"); continue; } if( search_id ) { int stop = 0; for( t = 0; t < x->id_len; t ++ ) { if( search_id[t] != x->id[t] ) { stop = 1; break; } } if( stop == 1 ) { printf("DEBUG::PKCS11::ID does not" "match, SKIPPING!!!!\n"); continue; } } /* Get Private Key in OpenSSL format */ evp_pkey = PKCS11_get_private_key( key ); /* Write the cert in PEM format to memory */ p_ret = PEM_write_bio_PUBKEY( mem, evp_pkey ); /* Get the pointer to the memory buffer */ BIO_get_mem_ptr( mem, &mem_buf ); /* Push a PKI_MEM buffer on the stack */ tmp_mem = PKI_MEM_new_null(); PKI_MEM_add ( tmp_mem, mem_buf->data, mem_buf->length); PKI_STACK_push( sk, tmp_mem ); } if( mem ) BIO_free ( mem ); } else { printf("DEBUG::PKCS11::OTHER DATATYPE SELECTED!\n"); } } err: if( slots ) PKCS11_release_all_slots( ctx, slots, num ); /* if( ctx ) { PKCS11_CTX_unload(ctx); PKCS11_CTX_free(ctx); } */ if( libfile ) PKI_Free (libfile); if( search_slot ) PKI_Free ( search_slot ); if( search_slotid ) PKI_Free ( search_slotid ); if( search_label ) PKI_Free ( search_label ); if( search_id ) PKI_Free ( search_id ); return ( sk ); #else return ( NULL ); #endif }
int OCSPD_build_ca_list ( OCSPD_CONFIG *handler, PKI_CONFIG_STACK *ca_conf_sk) { int i = 0; PKI_STACK *ca_list = NULL; PKI_log_debug("Building CA List"); if ( !ca_conf_sk ) { PKI_log( PKI_LOG_ERR, "No stack of ca configs!"); return ( PKI_ERR ); } if((ca_list = PKI_STACK_new((void (*))CA_LIST_ENTRY_free)) == NULL ) { PKI_log_err ( "Memory Error"); return ( PKI_ERR ); } for (i = 0; i < PKI_STACK_CONFIG_elements( ca_conf_sk ); i++) { char *tmp_s = NULL; URL *tmp_url = NULL; PKI_X509_CERT *tmp_cert = NULL; CA_LIST_ENTRY *ca = NULL; PKI_CONFIG *cnf = NULL; /* Get the current Configureation file */ cnf = PKI_STACK_CONFIG_get_num( ca_conf_sk, i ); if (!cnf) continue; /* Get the CA cert from the cfg file itself */ if((tmp_s = PKI_CONFIG_get_value( cnf, "/caConfig/caCertValue" )) == NULL ) { /* Get the CA parsed url */ if((tmp_url = URL_new( PKI_CONFIG_get_value( cnf, "/caConfig/caCertUrl" ))) == NULL ) { /* Error, can not parse url data */ PKI_log( PKI_LOG_ERR, "Can not parse CA cert url (%s)", PKI_CONFIG_get_value(cnf, "/caConfig/caCertUrl")); continue; } if((tmp_cert = PKI_X509_CERT_get_url(tmp_url, NULL, NULL ))== NULL) { PKI_log_err("Can not get CA cert from (%s)", tmp_url); URL_free (tmp_url); continue; } } else { PKI_X509_CERT_STACK *cc_sk = NULL; PKI_MEM *mm = NULL; if((mm = PKI_MEM_new_null()) == NULL ) { PKI_Free(tmp_s); continue; } PKI_MEM_add ( mm, tmp_s, strlen(tmp_s)); if((cc_sk=PKI_X509_CERT_STACK_get_mem(mm, NULL)) == NULL ) { PKI_log_err ( "Can not parse cert from /caConfig/caCertValue"); PKI_Free(tmp_s); continue; } if ((tmp_cert = PKI_STACK_X509_CERT_pop( cc_sk )) == NULL ) { PKI_log_err ( "No elements on stack from /caConfig/caCertValue"); PKI_STACK_X509_CERT_free_all(cc_sk); PKI_Free(tmp_s); continue; } PKI_STACK_X509_CERT_free ( cc_sk ); PKI_Free(tmp_s); } /* OCSPD create the CA entry */ if ((ca = CA_LIST_ENTRY_new()) == NULL ) { PKI_log_err ( "CA List structure init error"); /* remember to do THIS!!!! */ if( tmp_url ) URL_free ( tmp_url ); if( tmp_cert ) PKI_X509_CERT_free ( tmp_cert ); continue; } ca->ca_cert = tmp_cert; tmp_cert = NULL; ca->ca_url = tmp_url; tmp_url = NULL; ca->ca_id = PKI_CONFIG_get_value( cnf, "/caConfig/name" ); ca->cid = CA_ENTRY_CERTID_new ( ca->ca_cert, handler->digest ); /* Get the CRL URL and the CRL itself */ if((tmp_s = PKI_CONFIG_get_value(cnf, "/caConfig/crlUrl")) == NULL) { PKI_STACK *cdp_sk = NULL; /* Now let's get it from PRQP */ /* Now from the Certificate */ if((cdp_sk = PKI_X509_CERT_get_cdp (ca->ca_cert)) ==NULL) { // No source for the CRL Distribution Point PKI_log_err ( "ERROR::Can not find the CDP for %s, skipping CA", ca->ca_id ); CA_LIST_ENTRY_free ( ca ); continue; } while ((tmp_s = PKI_STACK_pop ( cdp_sk )) != NULL) { if ((ca->crl_url = URL_new ( tmp_s )) == NULL ) { PKI_log_err( "URL %s not in the right format!"); CA_LIST_ENTRY_free ( ca ); continue; } else if( tmp_s ) PKI_Free ( tmp_s ); break; } } else { PKI_log_debug("Got CRL Url -> %s", tmp_s ); if((ca->crl_url = URL_new ( tmp_s )) == NULL ) { PKI_log_err ("Error Parsing CRL URL [%s] for CA [%s]", ca->ca_id, tmp_s); CA_LIST_ENTRY_free ( ca ); PKI_Free(tmp_s); continue; } PKI_Free(tmp_s); } if(OCSPD_load_crl ( ca, handler ) == PKI_ERR ) { PKI_log_err ( "Can not get CRL for %s", ca->ca_id); CA_LIST_ENTRY_free ( ca ); continue; } /* If the Server has a Token to be used with this CA, let's load it */ if((tmp_s = PKI_CONFIG_get_value ( cnf, "/caConfig/serverToken" )) == NULL) { /* No token in config, let's see if a specific cert is configured */ ca->token = NULL; if((tmp_s = PKI_CONFIG_get_value ( cnf, "/caConfig/serverCertUrl" )) == NULL ) { /* No cert is configured, we will use the defaults */ ca->server_cert = NULL; } else { /* The Server's cert URL is found, let's load the certificate */ if ((tmp_cert = PKI_X509_CERT_get ( tmp_s, NULL, NULL )) == NULL ) { PKI_log_err("Can not get server's cert from %s!", tmp_s ); CA_LIST_ENTRY_free ( ca ); PKI_Free(tmp_s); continue; } else { ca->server_cert = tmp_cert; } PKI_Free(tmp_s); } } else { /* A Token for this CA is found - we do not load it to avoid problems with Thread Initialization */ ca->server_cert = NULL; ca->token_name = tmp_s; ca->token = PKI_TOKEN_new_null(); if ((tmp_s = PKI_CONFIG_get_value ( cnf, "/caConfig/pkiConfigDir" )) != NULL) { ca->token_config_dir = strdup( tmp_s ); PKI_Free(tmp_s); } else { ca->token_config_dir = strdup(handler->token_config_dir); } } if((tmp_s = PKI_CONFIG_get_value ( cnf, "/caConfig/caCompromised" )) == NULL) { ca->compromised = 0; } else { ca->compromised = atoi(tmp_s); PKI_Free(tmp_s); } /* Responder Id Type */ if ((tmp_s = PKI_CONFIG_get_value(cnf, "/caConfig/responderIdType")) != NULL) { if (strncmp_nocase(tmp_s, "keyid", 5) == 0) { ca->response_id_type = PKI_X509_OCSP_RESPID_TYPE_BY_KEYID; } else if (strncmp_nocase(tmp_s, "name", 4) == 0) { ca->response_id_type = PKI_X509_OCSP_RESPID_TYPE_BY_NAME; } else { PKI_log_err("Can not parse responderIdType: %s (allowed 'keyid' or 'name')", tmp_s); exit(1); } PKI_Free(tmp_s); } else { // Default Value ca->response_id_type = PKI_X509_OCSP_RESPID_TYPE_BY_NAME; } // Now let's add the CA_LIST_ENTRY to the list of configured CAs PKI_STACK_push ( ca_list, ca ); } handler->ca_list = ca_list; return ( PKI_OK ); }
PKI_MEM_STACK *URL_get_data_mysql_url ( const URL *url, ssize_t size ) { #ifdef HAVE_MYSQL MYSQL_ROW row; MYSQL * sql = NULL; MYSQL_FIELD *fields = NULL; MYSQL_RES *res = NULL; unsigned long *lengths = NULL; long long n_rows = 0; int n_fields = 0; PKI_MEM *tmp_mem = NULL; PKI_MEM_STACK *sk = NULL; char * query = NULL; if( !url ) return (NULL); if((sql = db_connect ( url )) == NULL ) { return NULL; } if ((query = parse_url_query(url)) == NULL) { PKI_log_err("Can not parse URL query"); goto end; } else mysql_query(sql, query); /* Get the Data */ if((res = mysql_store_result( sql )) == NULL) { PKI_log_err("Can not retrieve SQL data"); goto end; } if( ((n_rows = (long long) mysql_num_rows( res )) < 1 ) || ((sk = PKI_STACK_MEM_new()) == NULL)) { PKI_log_err("No returned rows found"); goto end; } while((row = mysql_fetch_row(res)) != NULL ) { /* Count the number of fields retrieved */ n_fields = (int) mysql_num_fields( res ); lengths = mysql_fetch_lengths( res ); fields = mysql_fetch_fields( res ); if (!fields) { PKI_ERROR(PKI_ERR_GENERAL, "can not fetch query fields"); break; } if (n_fields > 0) { tmp_mem = PKI_MEM_new_null(); if (size == 0 || (( size > 0 ) && ( lengths[0] < size))) { PKI_MEM_add(tmp_mem,row[0],lengths[0]); /* For now, let's only deal with one field at the time */ PKI_STACK_push( sk, tmp_mem ); } } } end: if (query) PKI_Free (query); db_close ( sql ); return ( sk ); #else return ( NULL ); #endif }