char * PKI_X509_CERT_get_parsed(const PKI_X509_CERT *x, PKI_X509_DATA type ) { char *ret = NULL; PKI_X509_KEYPAIR *k = NULL; const PKI_X509_KEYPAIR_VALUE *pkey = NULL; if( !x ) return (NULL); switch( type ) { case PKI_X509_DATA_SERIAL: ret = PKI_INTEGER_get_parsed((PKI_INTEGER *) PKI_X509_CERT_get_data(x, type)); break; case PKI_X509_DATA_SUBJECT: case PKI_X509_DATA_ISSUER: ret = PKI_X509_NAME_get_parsed((PKI_X509_NAME *) PKI_X509_CERT_get_data(x, type)); break; case PKI_X509_DATA_NOTBEFORE: case PKI_X509_DATA_NOTAFTER: ret = PKI_TIME_get_parsed((PKI_TIME *)PKI_X509_CERT_get_data(x, type)); break; case PKI_X509_DATA_ALGORITHM: ret = (char *) PKI_ALGOR_get_parsed((PKI_ALGOR *) PKI_X509_CERT_get_data(x,type)); break; case PKI_X509_DATA_PUBKEY: case PKI_X509_DATA_KEYPAIR_VALUE: if ((pkey = PKI_X509_CERT_get_data(x, type)) != NULL) { k = PKI_X509_new_dup_value(PKI_DATATYPE_X509_KEYPAIR, pkey, NULL); ret = PKI_X509_KEYPAIR_get_parsed( k ); PKI_X509_KEYPAIR_free(k); } break; case PKI_X509_DATA_KEYSIZE: PKI_ERROR(PKI_ERR_PARAM_TYPE, "Deprecated Cert Datatype"); break; case PKI_X509_DATA_CERT_TYPE: case PKI_X509_DATA_SIGNATURE: case PKI_X509_DATA_EXTENSIONS: default: /* Not Recognized/Supported DATATYPE */ return (NULL); } return (ret); }
PKI_X509_CERT_TYPE PKI_X509_CERT_get_type(const PKI_X509_CERT *x) { PKI_X509_CERT_TYPE ret = PKI_X509_CERT_TYPE_USER; const PKI_X509_NAME *subj = NULL; const PKI_X509_NAME *issuer = NULL; BASIC_CONSTRAINTS *bs = NULL; PKI_X509_EXTENSION *ext = NULL; if (!x || !x->value || (x->type != PKI_DATATYPE_X509_CERT) ) return PKI_X509_CERT_TYPE_UNKNOWN; subj = PKI_X509_CERT_get_data ( x, PKI_X509_DATA_SUBJECT ); issuer = PKI_X509_CERT_get_data ( x, PKI_X509_DATA_ISSUER ); if ( subj && issuer ) { if ( PKI_X509_NAME_cmp( subj, issuer ) == 0) { ret |= PKI_X509_CERT_TYPE_ROOT; } } if((ext = PKI_X509_CERT_get_extension_by_id ( x, NID_basic_constraints)) != NULL ) { if(( bs = ext->value )) { if ( bs->ca ) ret |= PKI_X509_CERT_TYPE_CA; BASIC_CONSTRAINTS_free ( bs ); } PKI_X509_EXTENSION_free ( ext ); } if((ext = PKI_X509_CERT_get_extension_by_id ( x, NID_proxyCertInfo )) != NULL ) { if ( ret & PKI_X509_CERT_TYPE_CA ) { PKI_log_err ( "Certificate Error, Proxy Cert info set", "in a CA certificate!"); } else { ret |= PKI_X509_CERT_TYPE_PROXY; } PKI_X509_EXTENSION_free ( ext ); } return ret; }
int check_crl ( PKI_X509_CRL *x_crl, PKI_X509_CERT *x_cacert, OCSPD_CONFIG *conf ) { PKI_X509_KEYPAIR_VALUE *pkey = NULL; PKI_X509_KEYPAIR *k = NULL; int ret = -1; if (!conf) return (-1); PKI_RWLOCK_read_lock ( &conf->crl_lock ); if( !x_crl || !x_crl->value || !x_cacert || !x_cacert->value ) { if( conf->verbose ) { if(!x_crl || !x_crl->value) PKI_log_err ("CRL missing"); if(!x_cacert || !x_cacert->value) PKI_log_err("CA cert missing"); } PKI_RWLOCK_release_read ( &conf->crl_lock ); return(-1); } /* Gets the Public Key of the CA Certificate */ if((pkey = PKI_X509_CERT_get_data( x_cacert, PKI_X509_DATA_PUBKEY )) == NULL ) { PKI_log_err( "Can not parse PubKey from CA Cert"); PKI_RWLOCK_release_read ( &conf->crl_lock ); return(-3); } if ((k = PKI_X509_new_value(PKI_DATATYPE_X509_KEYPAIR, pkey, NULL)) == NULL ) { PKI_log_err ("Memory Error!"); PKI_RWLOCK_release_read ( &conf->crl_lock ); return(-3); } if ( PKI_X509_verify ( x_crl, k ) == PKI_OK ) { PKI_log_debug("CRL signature is verified!"); ret = PKI_OK; } else { ret = PKI_ERR; } k->value = NULL; PKI_X509_KEYPAIR_free ( k ); PKI_RWLOCK_release_read ( &conf->crl_lock ); if ( ret > 0 ) { PKI_log(PKI_LOG_INFO, "CRL matching CA cert ok [ %d ]", ret); } return ret; }
int PKI_X509_CERT_get_keysize(const PKI_X509_CERT *x ) { const PKI_X509_KEYPAIR_VALUE *pkey = NULL; if (!x || !x->value) return (0); if ((pkey = PKI_X509_CERT_get_data(x, PKI_X509_DATA_KEYPAIR_VALUE)) == NULL) { return (0); } return PKI_X509_KEYPAIR_VALUE_get_size(pkey); }
const PKI_X509_CRL_ENTRY * PKI_X509_CRL_lookup_cert(const PKI_X509_CRL *x, const PKI_X509_CERT *cert) { const PKI_INTEGER *serial = NULL; if (!x || !cert) return NULL; if ((serial = PKI_X509_CERT_get_data(cert, PKI_X509_DATA_SERIAL )) == NULL ) { return ( NULL ); } return PKI_X509_CRL_lookup ( x, serial ); }
int PKI_X509_CERT_get_keysize ( PKI_X509_CERT *x ) { int keysize = 0; PKI_X509_KEYPAIR_VALUE *pkey = NULL; if( !x || !x->value ) return (0); if((pkey = PKI_X509_CERT_get_data(x, PKI_X509_DATA_KEYPAIR_VALUE))==NULL){ return (0); } keysize = PKI_X509_KEYPAIR_VALUE_get_size( pkey ); return keysize; }
PKI_DIGEST *PKI_X509_CERT_key_hash(const PKI_X509_CERT *x, const PKI_DIGEST_ALG *alg ) { const PKI_X509_KEYPAIR_VALUE *key = NULL; PKI_DIGEST *keyHash = NULL; if ( !x || !x->value ) return NULL; if ( !alg ) alg = PKI_DIGEST_ALG_DEFAULT; if ((key = PKI_X509_CERT_get_data(x, PKI_X509_DATA_KEYPAIR_VALUE)) == NULL) return NULL; if ((keyHash = PKI_X509_KEYPAIR_VALUE_pub_digest(key, alg)) == NULL) return NULL; return keyHash; }
int PKI_X509_CERT_is_selfsigned(const PKI_X509_CERT *x ) { PKI_X509_KEYPAIR *kp = NULL; const PKI_X509_KEYPAIR *kval = NULL; int ret = -1; if (!x) return PKI_ERR; kval = PKI_X509_CERT_get_data ( x, PKI_X509_DATA_PUBKEY ); if ( !kval ) return PKI_ERR; kp = PKI_X509_new_dup_value(PKI_DATATYPE_X509_KEYPAIR, kval, NULL); if ( !kp ) return PKI_ERR; ret = PKI_X509_verify ( x, kp ); PKI_X509_KEYPAIR_free ( kp ); return ret; }
int PKI_X509_CERT_check_pubkey(PKI_X509_CERT *x, PKI_X509_KEYPAIR *k) { int ret = 0; X509_PUBKEY *pub_key = NULL; PKI_X509_KEYPAIR_VALUE *k_val = NULL; PKI_STRING *c_pubkey = NULL; PKI_STRING *k_pubkey = NULL; // Input checks if (!x || !x->value || !k || !k->value) return -1; // Gets the certificate's public key bits c_pubkey = PKI_X509_CERT_get_data(x, PKI_X509_DATA_PUBKEY_BITSTRING); if (!c_pubkey) return -99; // Gets the Key Value from the KeyPair k_val = PKI_X509_get_value(k); if (!k_val) { // Let's return ok, because in HSMs we might not have // access to the pubkey data return 0; } // Gets the KeyPair public key bits if (!X509_PUBKEY_set(&pub_key, k_val)) return -99; // Now let's point to tke KeyPair's public key k_pubkey = pub_key->public_key; // Compares the two bit strings ret = PKI_STRING_cmp(c_pubkey, k_pubkey); // Frees the memory X509_PUBKEY_free(pub_key); // Let's return the result of the operation return ret; }
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_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 ); };
CA_ENTRY_CERTID * CA_ENTRY_CERTID_new ( PKI_X509_CERT *cert, PKI_DIGEST_ALG * digestAlg ) { CA_ENTRY_CERTID *ret = NULL; PKI_STRING *keyString = NULL; PKI_DIGEST *keyDigest = NULL; PKI_X509_NAME *iName = NULL; PKI_DIGEST *nameDigest = NULL; /* Check for needed info */ if ( !cert || !cert->value ) return NULL; /* Use SHA1 as default digest algorithm */ if ( !digestAlg ) digestAlg = PKI_DIGEST_ALG_SHA1; // Allocate Memory for the CA_ENTRY_CERTID if((ret = PKI_Malloc(sizeof(CA_ENTRY_CERTID))) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); goto err; } /* Retrieves the subject name from the certificate */ if ((iName = PKI_X509_CERT_get_data(cert, PKI_X509_DATA_SUBJECT)) == NULL) { PKI_log_err("Can not get certificate's subject"); goto err; }; // Let's build the HASH of the Name if((nameDigest = PKI_X509_NAME_get_digest(iName, digestAlg)) == NULL) { PKI_log_err("Can not get digest string from certificate's subject"); goto err; }; // Assign the new OCTET string tothe nameHash field if (( ret->nameHash = PKI_STRING_new ( PKI_STRING_OCTET, (char *) nameDigest->digest, (ssize_t) nameDigest->size )) == NULL ) { PKI_log_err("Can not assign nameHash to CERTID"); goto err; }; // Let's get the key bitstring from the certificate if (( keyString = PKI_X509_CERT_get_data( cert, PKI_X509_DATA_PUBKEY_BITSTRING)) == NULL ) { PKI_log_err("Can not get certificate's pubkey bitstring"); goto err; } else { // We build the keyDigest from the keyString if((keyDigest = PKI_STRING_get_digest (keyString, digestAlg)) == NULL ) { PKI_log_err("Can not create new keyDigest from keyString"); goto err; }; }; if((ret->keyHash = PKI_STRING_new ( PKI_STRING_OCTET, (char *) keyDigest->digest, (ssize_t) keyDigest->size )) == NULL ) { PKI_log_err("Can not assign keyHash to CERTID"); goto err; }; /* Set the Digest Algorithm used */ if((ret->hashAlgorithm = PKI_ALGORITHM_new_digest( digestAlg )) == NULL ) { if( ret ) CA_ENTRY_CERTID_free ( ret ); PKI_log_err("ERROR, can not create a new hashAlgorithm!"); return NULL; }; if ( nameDigest ) PKI_DIGEST_free ( nameDigest ); if ( keyDigest ) PKI_DIGEST_free ( keyDigest ); return ret; err: if ( nameDigest ) PKI_DIGEST_free ( nameDigest ); if ( keyDigest ) PKI_DIGEST_free ( keyDigest ); if ( ret ) CA_ENTRY_CERTID_free ( ret ); return ( NULL ); }