char * PKI_CONFIG_find ( char *dir, char *name ) { struct dirent *dd = NULL; DIR *dirp = NULL; URL *url = NULL; int found = 0; char *ret = NULL; /* Check input */ if( !dir || !name ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (PKI_ERR); } if ((url = URL_new(dir)) == NULL) { PKI_log_debug("Dir [%s] is not a valid URI", dir ); return (PKI_ERR); } if (url->proto != URI_PROTO_FILE) { PKI_log_debug("URL is not a file, skipping!", dir ); return (PKI_ERR); } if ((dirp = opendir(url->addr)) == NULL) { PKI_log_debug("Can not open directory [%s]", url->addr ); return (PKI_ERR); } else { while(( dd = readdir( dirp )) != NULL ) { long len; char *filename = NULL; filename = dd->d_name; len = (long) strlen( filename ); PKI_log_debug("Processing file [%s]", filename ); if (len < 4 || strcmp(".xml", filename +len-4) != 0) { PKI_log_debug("Skipping %s", filename ); continue; } else { char fullpath[BUFF_MAX_SIZE]; size_t fullsize = 0; PKI_CONFIG *tmp_cfg = NULL; char *tmp_name = NULL; snprintf(fullpath, BUFF_MAX_SIZE, "%s/%s", url->addr, filename ); PKI_log_debug("Opening File %s", fullpath ); // Check the allowed size fullsize = strlen(url->addr) + strlen( filename ) + 1; if (fullsize > BUFF_MAX_SIZE) continue; if ((tmp_cfg = PKI_CONFIG_load(fullpath)) == NULL) { PKI_log_debug("Can not load %s", fullpath ); continue; } PKI_log_debug("Getting Name Param... "); tmp_name = PKI_CONFIG_get_value(tmp_cfg, "/*/name"); PKI_CONFIG_free(tmp_cfg); if (tmp_name != NULL) { PKI_log_debug("Got Name::%s", tmp_name); if (strcmp_nocase(tmp_name, name) == 0) { PKI_Free(tmp_name); tmp_name = NULL; // Safety found = 1; ret = strdup(fullpath); PKI_log_debug("File successfully loaded %s", fullpath ); break; } PKI_Free(tmp_name); tmp_name = NULL; // Safety } else PKI_log_debug("No Name found!"); } } closedir( dirp ); } // Let's free the URL memory if (url) URL_free(url); // If found, let's return it if (found == 1) return ret; // If not found, we return NULL return NULL; }
PKI_X509_CERT * PKI_X509_CERT_new (const PKI_X509_CERT * ca_cert, const PKI_X509_KEYPAIR * kPair, const PKI_X509_REQ * req, const char * subj_s, const char * serial_s, uint64_t validity, const PKI_X509_PROFILE * conf, const PKI_ALGOR * algor, const PKI_CONFIG * oids, HSM *hsm ) { PKI_X509_CERT *ret = NULL; PKI_X509_CERT_VALUE *val = NULL; PKI_X509_NAME *subj = NULL; PKI_X509_NAME *issuer = NULL; PKI_DIGEST_ALG *digest = NULL; PKI_X509_KEYPAIR_VALUE *signingKey = NULL; PKI_TOKEN *tk = NULL; PKI_X509_KEYPAIR_VALUE *certPubKeyVal = NULL; int rv = 0; int ver = 2; int64_t notBeforeVal = 0; ASN1_INTEGER *serial = NULL; char *ver_s = NULL; /* Check if the REQUIRED PKEY has been passed */ if (!kPair || !kPair->value) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (NULL); }; signingKey = kPair->value; /* TODO: This has to be fixed, to work on every option */ if ( subj_s ) { subj = PKI_X509_NAME_new ( subj_s ); } else if (conf || req) { char *tmp_s = NULL; // Let's use the configuration option first if (conf) { // Get the value of the DN, if present if ((tmp_s = PKI_CONFIG_get_value( conf, "/profile/subject/dn")) != NULL ) { // Builds from the DN in the config subj = PKI_X509_NAME_new(tmp_s); PKI_Free ( tmp_s ); } } // If we still do not have a name, let's check // the request for one if (req && !subj) { const PKI_X509_NAME * req_subj = NULL; // Copy the name from the request if ((req_subj = PKI_X509_REQ_get_data(req, PKI_X509_DATA_SUBJECT)) != NULL) { subj = PKI_X509_NAME_dup(req_subj); } } // If no name is provided, let's use an empty one // TODO: Shall we remove this and fail instead ? if (!subj) subj = PKI_X509_NAME_new( "" ); } else { struct utsname myself; char tmp_name[1024]; if (uname(&myself) < 0) { subj = PKI_X509_NAME_new( "" ); } else { sprintf( tmp_name, "CN=%s", myself.nodename ); subj = PKI_X509_NAME_new( tmp_name ); } } if (!subj) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, subj_s ); goto err; } if( ca_cert ) { const PKI_X509_NAME *ca_subject = NULL; /* Let's get the ca_cert subject and dup that data */ // ca_subject = (PKI_X509_NAME *) // X509_get_subject_name( (X509 *) ca_cert ); ca_subject = PKI_X509_CERT_get_data( ca_cert, PKI_X509_DATA_SUBJECT ); if( ca_subject ) { issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *)ca_subject); } else { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL); goto err; } } else { issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *) subj); } if( !issuer ) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL); goto err; } if(( ret = PKI_X509_CERT_new_null()) == NULL ) { PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL); goto err; } /* Alloc memory structure for the Certificate */ if((ret->value = ret->cb->create()) == NULL ) { PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL); return (NULL); } val = ret->value; if(( ver_s = PKI_CONFIG_get_value( conf, "/profile/version")) != NULL ) { ver = atoi( ver_s ) - 1; if ( ver < 0 ) ver = 0; PKI_Free ( ver_s ); } else { ver = 2; }; if (!X509_set_version(val,ver)) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_VERSION, NULL); goto err; } if (serial_s) { char * tmp_s = (char *) serial_s; serial = s2i_ASN1_INTEGER(NULL, tmp_s); } else { // If cacert we assume it is a normal cert - let's create a // random serial number, otherwise - it's a self-signed, use // the usual 'fake' 0 if ( ca_cert ) { unsigned char bytes[11]; RAND_bytes(bytes, sizeof(bytes)); bytes[0] = 0; serial = PKI_INTEGER_new_bin(bytes, sizeof(bytes)); } else { serial = s2i_ASN1_INTEGER( NULL, "0"); }; }; if(!X509_set_serialNumber( val, serial )) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SERIAL, serial_s); goto err; } /* Set the issuer Name */ // rv = X509_set_issuer_name((X509 *) ret, (X509_NAME *) issuer); if(!X509_set_issuer_name( val, (X509_NAME *) issuer)) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL); goto err; } /* Set the subject Name */ if(!X509_set_subject_name(val, (X509_NAME *) subj)) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, NULL); goto err; } /* Set the start date (notBefore) */ if (conf) { int years = 0; int days = 0; int hours = 0; int mins = 0; int secs = 0; char *tmp_s = NULL; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/years")) != NULL ) { years = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/days")) != NULL ) { days = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/hours")) != NULL ) { hours = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/minutes")) != NULL ) { mins = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/seconds")) != NULL ) { secs = atoi( tmp_s ); PKI_Free ( tmp_s ); }; notBeforeVal = secs + ( mins * 60 ) + ( hours * 3600 ) + ( days * 3600 * 24 ) + ( years * 3600 * 24 * 365 ); }; /* Set the validity (notAfter) */ if( conf && validity == 0 ) { long long years = 0; long long days = 0; long long hours = 0; long long mins = 0; long long secs = 0; char *tmp_s = NULL; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/years")) != NULL ) { years = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/days")) != NULL ) { days = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/hours")) != NULL ) { hours = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/minutes")) != NULL ) { mins = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/minutes")) != NULL ) { secs = atoll( tmp_s ); PKI_Free ( tmp_s ); }; validity = (unsigned long long) secs + (unsigned long long) ( mins * 60 ) + (unsigned long long) ( hours * 3600 ) + (unsigned long long) ( days * 3600 * 24 ) + (unsigned long long) ( years * 3600 * 24 * 365 ); }; if (validity <= 0) validity = 30 * 3600 * 24; #if ( LIBPKI_OS_BITS == LIBPKI_OS32 ) long notBeforeVal32 = (long) notBeforeVal; if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal32 ) == NULL) { #else if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal ) == NULL) { #endif PKI_ERROR(PKI_ERR_X509_CERT_CREATE_NOTBEFORE, NULL); goto err; } /* Set the end date in a year */ if (X509_gmtime_adj(X509_get_notAfter(val),(long int) validity) == NULL) { PKI_DEBUG("ERROR: can not set notAfter field!"); goto err; } /* Copy the PKEY if it is in the request, otherwise use the public part of the PKI_X509_CERT */ if (req) { certPubKeyVal = (PKI_X509_KEYPAIR_VALUE *) PKI_X509_REQ_get_data(req, PKI_X509_DATA_KEYPAIR_VALUE); if( !certPubKeyVal ) { PKI_DEBUG("ERROR, can not get pubkey from req!"); goto err; } } else { /* Self Signed -- Same Public Key! */ certPubKeyVal = signingKey; } if (!ca_cert && conf) { char *tmp_s = NULL; if(( tmp_s = PKI_X509_PROFILE_get_value( conf, "/profile/keyParams/algorithm")) != NULL ) { PKI_ALGOR *myAlg = NULL; PKI_DIGEST_ALG *dgst = NULL; if((myAlg = PKI_ALGOR_get_by_name( tmp_s )) != NULL ) { if(!algor) algor = myAlg; if((dgst = PKI_ALGOR_get_digest( myAlg )) != NULL ) { PKI_DEBUG("Got Signing Algorithm: %s, %s", PKI_DIGEST_ALG_get_parsed(dgst), PKI_ALGOR_get_parsed(myAlg)); digest = dgst; } else { PKI_DEBUG("Can not parse digest algorithm from %s", tmp_s); } } else { PKI_DEBUG("Can not parse key algorithm from %s", tmp_s); } PKI_Free ( tmp_s ); } } if (conf) { PKI_KEYPARAMS *kParams = NULL; PKI_SCHEME_ID scheme; scheme = PKI_ALGOR_get_scheme( algor ); kParams = PKI_KEYPARAMS_new(scheme, conf); if (kParams) { /* Sets the point compression */ switch ( kParams->scheme ) { #ifdef ENABLE_ECDSA case PKI_SCHEME_ECDSA: if ( (int) kParams->ec.form > 0 ) { # if OPENSSL_VERSION_NUMBER < 0x1010000fL EC_KEY_set_conv_form(certPubKeyVal->pkey.ec, (point_conversion_form_t) kParams->ec.form); # else EC_KEY_set_conv_form(EVP_PKEY_get0_EC_KEY(certPubKeyVal), (point_conversion_form_t) kParams->ec.form); # endif } if ( kParams->ec.asn1flags > -1 ) { # if OPENSSL_VERSION_NUMBER < 0x1010000fL EC_KEY_set_asn1_flag(certPubKeyVal->pkey.ec, kParams->ec.asn1flags ); # else EC_KEY_set_asn1_flag(EVP_PKEY_get0_EC_KEY(certPubKeyVal), kParams->ec.asn1flags ); # endif } break; #endif case PKI_SCHEME_RSA: case PKI_SCHEME_DSA: break; default: // Nothing to do PKI_ERROR(PKI_ERR_GENERAL, "Signing Scheme Uknown %d!", kParams->scheme); break; } } } if (!X509_set_pubkey(val, certPubKeyVal)) { PKI_DEBUG("ERROR, can not set pubkey in cert!"); goto err; } if (conf) { if((tk = PKI_TOKEN_new_null()) == NULL ) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); goto err; } PKI_TOKEN_set_cert(tk, ret); if (ca_cert) { PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ca_cert); } else { PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ret); } if (req) PKI_TOKEN_set_req(tk, (PKI_X509_REQ *)req ); if (kPair) PKI_TOKEN_set_keypair ( tk, (PKI_X509_KEYPAIR *)kPair ); rv = PKI_X509_EXTENSIONS_cert_add_profile(conf, oids, ret, tk); if (rv != PKI_OK) { PKI_DEBUG( "ERROR, can not set extensions!"); tk->cert = NULL; tk->cacert = NULL; tk->req = NULL; tk->keypair = NULL; PKI_TOKEN_free ( tk ); goto err; } // Cleanup for the token (used only to add extensions) tk->cert = NULL; tk->cacert = NULL; tk->req = NULL; tk->keypair = NULL; PKI_TOKEN_free ( tk ); } if (!digest) { if (!algor) { PKI_log_debug("Getting the Digest Algorithm from the CA cert"); // Let's get the Digest Algorithm from the CA Cert if (ca_cert) { if((algor = PKI_X509_CERT_get_data(ca_cert, PKI_X509_DATA_ALGORITHM )) == NULL) { PKI_log_err("Can not retrieve DATA algorithm from CA cert"); } } } // If we have an Algor from either the passed argument or // the CA Certificate, extract the digest from it. Otherwise // get the digest from the signing key if (algor) { if((digest = PKI_ALGOR_get_digest(algor)) == NULL ) { PKI_log_err("Can not get digest from algor"); } } // Check, if still no digest, let's try from the signing Key if (digest == NULL) { if ((digest = PKI_DIGEST_ALG_get_by_key( kPair )) == NULL) { PKI_log_err("Can not infer digest algor from the key pair"); } } } // No Digest Here ? We failed... if (digest == NULL) { PKI_log_err("PKI_X509_CERT_new()::Can not get the digest!"); return( NULL ); } // Sign the data if (PKI_X509_sign(ret, digest, kPair) == PKI_ERR) { PKI_log_err ("Can not sign certificate [%s]", ERR_error_string(ERR_get_error(), NULL )); PKI_X509_CERT_free ( ret ); return NULL; } #if ( OPENSSL_VERSION_NUMBER >= 0x0090900f ) # if OPENSSL_VERSION_NUMBER < 0x1010000fL PKI_X509_CERT_VALUE *cVal = (PKI_X509_CERT_VALUE *) ret->value; if (cVal && cVal->cert_info) { PKI_log_debug("Signature = %s", PKI_ALGOR_get_parsed(cVal->cert_info->signature)); } # endif // PKI_X509_CINF_FULL *cFull = NULL; // cFull = (PKI_X509_CINF_FULL *) cVal->cert_info; // cFull->enc.modified = 1; #endif return ret; err: if (ret) PKI_X509_CERT_free(ret); if (subj) PKI_X509_NAME_free(subj); if (issuer) PKI_X509_NAME_free(issuer); return NULL; } /*! * \brief Signs a PKI_X509_CERT */ int PKI_X509_CERT_sign(PKI_X509_CERT *cert, PKI_X509_KEYPAIR *kp, PKI_DIGEST_ALG *digest) { const PKI_ALGOR *alg = NULL; if( !cert || !cert->value || !kp || !kp->value ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return PKI_ERR; } if(!digest) { if((alg = PKI_X509_CERT_get_data(cert, PKI_X509_DATA_ALGORITHM))!=NULL) { digest = PKI_ALGOR_get_digest ( alg ); } } if(!digest) { if((digest = PKI_DIGEST_ALG_get_by_key(kp)) == NULL) { PKI_log_err("PKI_X509_CERT_new()::Can not get digest algor " "from key"); return PKI_ERR; } } if( PKI_X509_sign(cert, digest, kp) == PKI_ERR) { PKI_log_err ("PKI_X509_CERT_new()::Can not sign certificate [%s]", ERR_error_string(ERR_get_error(), NULL )); return PKI_ERR; } return PKI_OK; }; /*! * \brief Signs a PKI_X509_CERT by using a configured PKI_TOKEN */ int PKI_X509_CERT_sign_tk ( PKI_X509_CERT *cert, PKI_TOKEN *tk, PKI_DIGEST_ALG *digest) { PKI_X509_KEYPAIR *kp = NULL; if( !cert || !cert->value || !tk ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return PKI_ERR; }; if( PKI_TOKEN_login( tk ) == PKI_ERR ) { PKI_ERROR(PKI_ERR_HSM_LOGIN, NULL); return PKI_ERR; }; if((kp = PKI_TOKEN_get_keypair( tk )) == NULL ) { return PKI_ERR; }; return PKI_X509_CERT_sign ( cert, kp, digest ); };
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_X509_CRL *PKI_X509_CRL_new(const PKI_X509_KEYPAIR *k, const PKI_X509_CERT *cert, const char * crlNumber_s, unsigned long validity, const PKI_X509_CRL_ENTRY_STACK *sk, const PKI_X509_PROFILE *profile, const PKI_CONFIG *oids, HSM *hsm) { PKI_X509_CRL *ret = NULL; PKI_X509_CRL_VALUE *val = NULL; ASN1_INTEGER *crlNumber = NULL; ASN1_TIME *time = NULL; int rv = PKI_OK; int i = 0; char * tmp_s = NULL; PKI_X509_CRL_ENTRY *entry = NULL; PKI_DIGEST_ALG *dgst = NULL; long long lastUpdateVal = 0; long long nextUpdateVal = 0; /* Checks for the Key and its internal value */ if( !k || !k->value ) return NULL; /* checks for the certificate and its internal value */ if( !cert || !cert->value ) return ( NULL ); if(( ret = PKI_X509_CRL_new_null()) == NULL ) { PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL); goto err; } /* Alloc memory structure for the Certificate */ if((ret->value = ret->cb->create()) == NULL ) { PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL); goto err; } val = ret->value; if ( !crlNumber_s && profile ) { if(( tmp_s = PKI_CONFIG_get_value( profile, "/profile/crlNumber")) != NULL ) { crlNumber = PKI_INTEGER_new_char ( tmp_s ); PKI_Free ( tmp_s ); }; } else if ( crlNumber_s ) { crlNumber = PKI_INTEGER_new_char( crlNumber_s ); // Let's add the CRLSerial extension X509_CRL_add1_ext_i2d(val, NID_crl_number, crlNumber, 0, 0); }; /* Set the start date (notBefore) */ if (profile) { int years = 0; int days = 0; int hours = 0; int mins = 0; int secs = 0; if(( tmp_s = PKI_CONFIG_get_value( profile, "/profile/notBefore/years")) != NULL ) { years = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( profile, "/profile/notBefore/days")) != NULL ) { days = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( profile, "/profile/notBefore/hours")) != NULL ) { hours = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( profile, "/profile/notBefore/minutes")) != NULL ) { mins = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( profile, "/profile/notBefore/minutes")) != NULL ) { secs = atoi( tmp_s ); PKI_Free ( tmp_s ); }; lastUpdateVal = secs + ( mins * 60 ) + ( hours * 3600 ) + ( days * 3600 * 24 ) + ( years * 3600 * 24 * 365 ); } else { // Sets lastUpdate to current time lastUpdateVal = 0; }; if ( profile && validity <= 0 ) { long long years = 0; long long days = 0; long long hours = 0; long long mins = 0; long long secs = 0; if((tmp_s = PKI_CONFIG_get_value ( profile, "/profile/validity/years")) != NULL ) { years = atoll( tmp_s ); PKI_Free(tmp_s); } if((tmp_s = PKI_CONFIG_get_value ( profile, "/profile/validity/days")) != NULL ) { days = atoll( tmp_s ); PKI_Free( tmp_s ); } if((tmp_s = PKI_CONFIG_get_value ( profile, "/profile/validity/hours")) != NULL ) { hours = atoll( tmp_s ); PKI_Free( tmp_s ); } if((tmp_s = PKI_CONFIG_get_value ( profile, "/profile/validity/mins")) != NULL ) { mins = atoll( tmp_s ); PKI_Free ( tmp_s ); } if((tmp_s = PKI_CONFIG_get_value ( profile, "/profile/validity/secs")) != NULL ) { secs = atoll( tmp_s ); PKI_Free ( tmp_s ); } nextUpdateVal = secs + 60 * ( mins + 60 * (hours + 24 * ( days + 365 * years ) ) ); } else { nextUpdateVal = (long long) validity; }; /* Generates a new time for lastUpdate field */ if((time = PKI_TIME_new( lastUpdateVal )) == NULL ) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); goto err; }; /* Set the Last Update field */ if(X509_CRL_set_lastUpdate( val, time ) == 0 ) { PKI_log_err ( "ERROR, can not set lastUpdate field in CRL"); goto err; } PKI_TIME_free ( time ); time = NULL; // Memory /* Generates a new time for lastUpdate field */ if((time = PKI_TIME_new( nextUpdateVal )) == NULL ) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); goto err; }; /* Set the nextUpdate field */ if(X509_CRL_set_nextUpdate( val, time ) == 0 ) { PKI_log_err ( "ERROR, can not set lastUpdate field in CRL"); goto err; } PKI_TIME_free ( time ); time = NULL; // Memory /* Now we need to add the CRL issuer name and details */ if (X509_CRL_set_issuer_name( val, X509_get_subject_name(cert->value)) == 0) { PKI_log_debug( "Can not set CRL issuer name"); goto err; } if ( sk ) { /* Adds the list of revoked certificates */ for(i=0; i < PKI_STACK_X509_CRL_ENTRY_elements(sk); i++ ) { PKI_log_debug("CRL::ADDING ENTRY %d\n", i ); entry = PKI_STACK_X509_CRL_ENTRY_get_num(sk, i); if(!entry) break; X509_CRL_add0_revoked(val, entry); }; } /* Sorts the CRL entries */ X509_CRL_sort ( val ); /* if((ret = PKI_X509_new_value( PKI_DATATYPE_X509_CRL, val, hsm)) == NULL ) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); X509_CRL_free ( val ); return ( NULL ); } */ /* Get the extensions from the profile */ if( profile ) { PKI_TOKEN * tk; if((tk = PKI_TOKEN_new_null()) == NULL ) { PKI_log_err ( "Memory allocation failure"); PKI_X509_CRL_free ( ret ); return NULL; } PKI_TOKEN_set_cert(tk, (PKI_X509_CERT *)cert); PKI_TOKEN_set_keypair(tk, (PKI_X509_KEYPAIR *)k); if(PKI_X509_EXTENSIONS_crl_add_profile( profile, oids, ret, tk) == 0 ) { PKI_log_debug( "ERROR, can not set extensions!"); PKI_X509_CRL_free ( ret ); tk->cert = NULL; tk->keypair = NULL; PKI_TOKEN_free ( tk ); return ( NULL ); } tk->cert = NULL; tk->keypair = NULL; PKI_TOKEN_free ( tk ); } /* Get the Digest Algorithm */ if( (dgst = PKI_DIGEST_ALG_get_by_key( k )) == NULL ) { PKI_log_err("Can not get digest algor from keypair!"); goto err; } rv = PKI_X509_sign ( ret, dgst, k ); if ( rv == PKI_ERR ) { PKI_log_debug ("ERROR, can not sign CRL!"); goto err; } return( ret ); err: if ( time ) PKI_TIME_free ( time ); if ( ret ) PKI_X509_CRL_free ( ret ); return NULL; }
/* Functions */ OCSPD_CONFIG * OCSPD_load_config(char *configfile) { OCSPD_CONFIG *h = NULL; PKI_CONFIG *cnf = NULL; PKI_CONFIG_STACK *ca_config_stack = NULL; char *tmp_s = NULL; char *tmp_s2 = NULL; int i; /* Check for the environment variable PRQP_CONF */ if (configfile == NULL) configfile = getenv("OCSPD_CONF"); /* If not, check for the default CONFIG_FILE */ if (configfile == NULL) configfile = CONFIG_FILE; if( !configfile ) { /* No config file is available */ PKI_log(PKI_LOG_ERR, "No config file provided!"); return (NULL); } /* Load the config file */ if(( cnf = PKI_CONFIG_load ( configfile )) == NULL ) { PKI_log( PKI_LOG_ERR, "Can not load config file [%s]!", configfile ); return (NULL); } if(( h = (OCSPD_CONFIG *)PKI_Malloc(sizeof(OCSPD_CONFIG))) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); goto err; } /* Set the group and user string to NULL */ h->user = NULL; h->group = NULL; /* Set the PRQPD verbose status */ h->verbose = 0; h->debug = 0; h->nthreads = 5; h->http_proto = "1.0"; h->max_timeout_secs = 5; h->crl_auto_reload = 3600; h->crl_reload_expired = 1; h->crl_check_validity = 600; /* Copy the config filename so that it could be re-loaded on SIGHUP */ h->cnf_filename = strdup( configfile ); /* Initialize the COND variables and MUTEXES */ for( i = 0; i < sizeof ( h->mutexes ) / sizeof( PKI_MUTEX ); i++ ) { PKI_MUTEX_init ( &h->mutexes[i] ); } for( i = 0; i < sizeof ( h->condVars ) / sizeof( PKI_COND ); i++) { PKI_COND_init ( &h->condVars[i] ); } PKI_RWLOCK_init ( &h->crl_lock ); /* Token Initialization */ if (( tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/pkiConfigDir")) == NULL) { PKI_log_err("Missing pkiConfigDir in configuration!"); return NULL; } else { if ((tmp_s2 = PKI_CONFIG_get_value( cnf, "/serverConfig/general/token" )) != NULL) { h->token_name = strdup( tmp_s2 ); h->token_config_dir = strdup ( tmp_s ); if ((h->token = PKI_TOKEN_new_null()) == NULL) { PKI_log( PKI_LOG_ERR, "Memory error for new token"); exit(1); } PKI_Free(tmp_s2); } else { PKI_log_err("No General Token provided in configuration."); PKI_Free(tmp_s); return NULL; } PKI_Free(tmp_s); } /* Thread configuration */ if((tmp_s = PKI_CONFIG_get_value(cnf, "/serverConfig/general/spawnThreads")) != NULL) { int t = 0; if((t = atoi( tmp_s )) > 0 ) h->nthreads = t; PKI_Free(tmp_s); } if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/caConfigDir")) != NULL) { h->ca_config_dir = strdup(tmp_s); ca_config_stack = PKI_CONFIG_load_dir(h->ca_config_dir, NULL); if (ca_config_stack == NULL) { PKI_log( PKI_LOG_ERR, "Can't load caConfigDir (%s)", h->ca_config_dir); PKI_Free(tmp_s); goto err; } PKI_Free(tmp_s); } else { PKI_log( PKI_LOG_ERR, "/serverConfig/general/caConfigDir needed in conf!\n"); goto err; } /* Pid File */ if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/pidFile")) != NULL ) { h->pidfile = strdup(tmp_s); PKI_Free(tmp_s); } /* AutoReload timeout */ if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/crlAutoReload")) != NULL) { h->crl_auto_reload = atoi(tmp_s); if( h->crl_auto_reload <= 0 ) { h->crl_auto_reload = 0; PKI_log(PKI_LOG_INFO, "Auto Reload Disabled"); } PKI_Free(tmp_s); } /* CRL validity check timeout */ if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/crlCheckValidity")) != NULL ) { h->crl_check_validity = atoi(tmp_s); if ( h->crl_check_validity <= 0 ) { h->crl_check_validity = 0; PKI_log(PKI_LOG_INFO, "CRL check validity disabled"); } PKI_Free(tmp_s); } /* AutoReload timeout */ if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/crlReloadExpired")) != NULL ) { if (strncmp_nocase(tmp_s, "n", 1) == 0) { h->crl_reload_expired = 0; PKI_log(PKI_LOG_INFO, "Expired CRLs Reload Disabled"); } PKI_Free(tmp_s); } /* Server Privileges */ if ((tmp_s = PKI_CONFIG_get_value(cnf, "/serverConfig/security/user")) != NULL) { h->user = strdup(tmp_s); PKI_Free(tmp_s); } if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/security/group" )) != NULL) { h->group = strdup(tmp_s); PKI_Free(tmp_s); } if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/security/chrootDir" )) != NULL ) { h->chroot_dir = strdup(tmp_s); PKI_Free(tmp_s); } /* Bind Address */ if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/network/bindAddress" )) == NULL) { // If not bindAddress, let's use the universal one tmp_s = strdup("http://0.0.0.0:2560"); } if ((h->bindUrl = URL_new( tmp_s )) == NULL) { PKI_log( PKI_LOG_ERR, "Can't parse bindAddress (%s)", tmp_s ); PKI_Free(tmp_s); goto err; } // We need to free the tmp_s PKI_Free(tmp_s); /* HTTP Version */ if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/network/httpProtocol")) != NULL) { h->http_proto = strdup(tmp_s); PKI_Free(tmp_s); } /* Timeout for incoming connections */ if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/network/timeOut")) != NULL ) { long t = 0; if ((t = atol( tmp_s )) > 0) h->max_timeout_secs = (unsigned int) t; PKI_Free(tmp_s); } /* Maximum Request Size */ if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/response/maxReqSize" )) != NULL ) { int t = 0; if((t = atoi( tmp_s )) > 0 ) { h->max_req_size = t; } PKI_Free(tmp_s); } // Default h->digest = PKI_DIGEST_ALG_SHA1; /* Digest Algorithm to be used */ if ((tmp_s = PKI_CONFIG_get_value(cnf, "/serverConfig/response/digestAlgorithm" )) != NULL) { h->digest = PKI_DIGEST_ALG_get_by_name( tmp_s ); if (!h->digest) { PKI_log_err("Can not parse response digest algorithm: %s", tmp_s); exit(1); } else PKI_log_debug("Selected response digest algorithm: %s", tmp_s); PKI_Free(tmp_s); } /* Signing Digest Algorithm to be used */ if((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/response/signatureDigestAlgorithm" )) == NULL) { PKI_log_debug("No specific signature digest algorithm selected."); h->sigDigest = NULL; } else { h->sigDigest = PKI_DIGEST_ALG_get_by_name( tmp_s ); if (!h->sigDigest) { PKI_log_err("Can not parse signing digest algorithm: %s", tmp_s); exit(1); } else PKI_log_debug("Selected signature digest algorithm: %s", tmp_s); PKI_Free(tmp_s); } /* Now Parse the PRQP Response Section */ if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/response/validity/days" )) != NULL) { h->ndays = atoi(tmp_s); PKI_Free(tmp_s); } if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/response/validity/mins" )) != NULL) { h->nmin = atoi(tmp_s); PKI_Free(tmp_s); } h->set_nextUpdate = h->ndays * 3600 + h->nmin * 60; /* Database Options */ if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/dbUrl")) != NULL) { if ((h->db_url = URL_new ( tmp_s )) == NULL) { PKI_log_err ( "Database Url not parsable (%s)", tmp_s ); PKI_Free(tmp_s); goto err; } PKI_Free(tmp_s); } /* Database Persistant */ if ((tmp_s = PKI_CONFIG_get_value( cnf, "/serverConfig/general/dbPersistant")) != NULL) { if (strncmp_nocase ( "n", tmp_s, 1 ) == 0 ) h->db_persistant = 0; else h->db_persistant = 1; PKI_Free(tmp_s); } /* Now we should load the CA configuration files and generate the CERT_ID for the different CAs */ if ((OCSPD_build_ca_list( h, ca_config_stack )) == PKI_ERR ) { PKI_log(PKI_LOG_ERR, "Can not build CA list!"); if (ca_config_stack) PKI_STACK_CONFIG_free ( ca_config_stack ); goto err; } if (ca_config_stack) PKI_STACK_CONFIG_free ( ca_config_stack ); return ( h ); err: if( ca_config_stack ) PKI_STACK_CONFIG_free ( ca_config_stack ); if( cnf ) PKI_CONFIG_free ( cnf ); if( h ) PKI_Free ( h ); return( NULL ); }