diff options
Diffstat (limited to 'usr/src/lib')
27 files changed, 7940 insertions, 5654 deletions
diff --git a/usr/src/lib/libkmf/include/algorithm.h b/usr/src/lib/libkmf/include/algorithm.h index c52ee81028..00e2eabddf 100644 --- a/usr/src/lib/libkmf/include/algorithm.h +++ b/usr/src/lib/libkmf/include/algorithm.h @@ -37,7 +37,7 @@ typedef struct pkcs_algorithm_map } PKCS_ALGORITHM_MAP; extern KMF_SIGNATURE_MODE PKCS_GetDefaultSignatureMode(KMF_ALGORITHM_INDEX); -extern PKCS_ALGORITHM_MAP* PKCS_GetAlgorithmMap(KMF_ALGCLASS, uint32_t, +extern PKCS_ALGORITHM_MAP* pkcs_get_alg_map(KMF_ALGCLASS, uint32_t, uint32_t); #ifdef __cplusplus diff --git a/usr/src/lib/libkmf/include/kmfapi.h b/usr/src/lib/libkmf/include/kmfapi.h index fd29b0733c..4826248ddb 100644 --- a/usr/src/lib/libkmf/include/kmfapi.h +++ b/usr/src/lib/libkmf/include/kmfapi.h @@ -42,309 +42,334 @@ extern "C" { /* * Setup operations. */ -extern KMF_RETURN KMF_Initialize(KMF_HANDLE_T *, char *, char *); -extern KMF_RETURN KMF_ConfigureKeystore(KMF_HANDLE_T, KMF_CONFIG_PARAMS *); -extern KMF_RETURN KMF_Finalize(KMF_HANDLE_T); +extern KMF_RETURN kmf_initialize(KMF_HANDLE_T *, char *, char *); +extern KMF_RETURN kmf_configure_keystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern KMF_RETURN kmf_finalize(KMF_HANDLE_T); /* * Key operations. */ -extern KMF_RETURN KMF_SignDataWithKey(KMF_HANDLE_T, - KMF_KEY_HANDLE *, KMF_OID *, - KMF_DATA *, KMF_DATA *); - -extern KMF_RETURN KMF_VerifyDataWithKey(KMF_HANDLE_T, - KMF_KEY_HANDLE *, KMF_ALGORITHM_INDEX, KMF_DATA *, KMF_DATA *); - -extern KMF_RETURN KMF_CreateKeypair(KMF_HANDLE_T, - KMF_CREATEKEYPAIR_PARAMS *, KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); +extern KMF_RETURN kmf_create_keypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_DeleteKeyFromKeystore(KMF_HANDLE_T, - KMF_DELETEKEY_PARAMS *, KMF_KEY_HANDLE *); +extern KMF_RETURN kmf_delete_key_from_keystore(KMF_HANDLE_T, int, + KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_SignCertRecord(KMF_HANDLE_T, KMF_KEY_HANDLE *, - KMF_X509_CERTIFICATE *, KMF_DATA *); +extern KMF_RETURN kmf_find_key(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, - KMF_KEY_HANDLE *, uint32_t *); +extern KMF_RETURN kmf_find_prikey_by_cert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, - KMF_RAW_KEY_DATA *); +extern KMF_RETURN kmf_store_key(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, - KMF_KEY_HANDLE *); +extern KMF_RETURN kmf_create_sym_key(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, +extern KMF_RETURN kmf_get_sym_key_value(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); /* * Certificate operations. */ -extern KMF_RETURN KMF_FindCert(KMF_HANDLE_T, KMF_FINDCERT_PARAMS *, - KMF_X509_DER_CERT *, uint32_t *); +extern KMF_RETURN kmf_find_cert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_EncodeCertRecord(KMF_X509_CERTIFICATE *, - KMF_DATA *); -extern KMF_RETURN KMF_DecodeCertData(KMF_DATA *, KMF_X509_CERTIFICATE **); +extern KMF_RETURN kmf_encode_cert_record(KMF_X509_CERTIFICATE *, KMF_DATA *); -extern KMF_RETURN KMF_SignCertWithKey(KMF_HANDLE_T, const KMF_DATA *, - KMF_KEY_HANDLE *, KMF_DATA *); -extern KMF_RETURN KMF_SignCertWithCert(KMF_HANDLE_T, - KMF_CRYPTOWITHCERT_PARAMS *, - const KMF_DATA *, KMF_DATA *, KMF_DATA *); +extern KMF_RETURN kmf_import_cert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_SignDataWithCert(KMF_HANDLE_T, - KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, KMF_DATA *, KMF_DATA *); +extern KMF_RETURN kmf_store_cert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_VerifyCertWithKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, - const KMF_DATA *); -extern KMF_RETURN KMF_VerifyCertWithCert(KMF_HANDLE_T, const KMF_DATA *, - const KMF_DATA *); -extern KMF_RETURN KMF_VerifyDataWithCert(KMF_HANDLE_T, - KMF_KEYSTORE_TYPE, KMF_ALGORITHM_INDEX, KMF_DATA *, KMF_DATA *, - const KMF_DATA *); - -extern KMF_RETURN KMF_EncryptWithCert(KMF_HANDLE_T, KMF_DATA *, - KMF_DATA *, KMF_DATA *); +extern KMF_RETURN kmf_delete_cert_from_keystore(KMF_HANDLE_T, int, + KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_DecryptWithCert(KMF_HANDLE_T, - KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, KMF_DATA *, KMF_DATA *); +extern KMF_RETURN kmf_validate_cert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_StoreCert(KMF_HANDLE_T, - KMF_STORECERT_PARAMS *, KMF_DATA *); -extern KMF_RETURN KMF_ImportCert(KMF_HANDLE_T, KMF_IMPORTCERT_PARAMS *); -extern KMF_RETURN KMF_DeleteCertFromKeystore(KMF_HANDLE_T, - KMF_DELETECERT_PARAMS *); +extern KMF_RETURN kmf_create_cert_file(const KMF_DATA *, KMF_ENCODE_FORMAT, + char *); -extern KMF_RETURN KMF_ValidateCert(KMF_HANDLE_T, - KMF_VALIDATECERT_PARAMS *, int *); +extern KMF_RETURN kmf_download_cert(KMF_HANDLE_T, char *, char *, int, + unsigned int, char *, KMF_ENCODE_FORMAT *); -extern KMF_RETURN KMF_CreateCertFile(KMF_DATA *, KMF_ENCODE_FORMAT, char *); +extern KMF_RETURN kmf_is_cert_file(KMF_HANDLE_T, char *, KMF_ENCODE_FORMAT *); -extern KMF_RETURN KMF_DownloadCert(KMF_HANDLE_T, char *, char *, int, - unsigned int, char *, KMF_ENCODE_FORMAT *); -extern KMF_RETURN KMF_IsCertFile(KMF_HANDLE_T, char *, KMF_ENCODE_FORMAT *); +extern KMF_RETURN kmf_check_cert_date(KMF_HANDLE_T, const KMF_DATA *); -extern KMF_RETURN KMF_CheckCertDate(KMF_HANDLE_T, KMF_DATA *); +/* + * Crypto operations with key or cert. + */ +extern KMF_RETURN kmf_encrypt(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern KMF_RETURN kmf_decrypt(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern KMF_RETURN kmf_sign_cert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern KMF_RETURN kmf_sign_data(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern KMF_RETURN kmf_verify_cert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern KMF_RETURN kmf_verify_data(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); /* * CRL operations. */ -extern KMF_RETURN KMF_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *); -extern KMF_RETURN KMF_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *); -extern KMF_RETURN KMF_ListCRL(KMF_HANDLE_T, KMF_LISTCRL_PARAMS *, char **); -extern KMF_RETURN KMF_FindCRL(KMF_HANDLE_T, KMF_FINDCRL_PARAMS *, - char **, int *); - -extern KMF_RETURN KMF_FindCertInCRL(KMF_HANDLE_T, - KMF_FINDCERTINCRL_PARAMS *); -extern KMF_RETURN KMF_VerifyCRLFile(KMF_HANDLE_T, - KMF_VERIFYCRL_PARAMS *); - -extern KMF_RETURN KMF_CheckCRLDate(KMF_HANDLE_T, - KMF_CHECKCRLDATE_PARAMS *); -extern KMF_RETURN KMF_DownloadCRL(KMF_HANDLE_T, char *, char *, +extern KMF_RETURN kmf_import_crl(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern KMF_RETURN kmf_delete_crl(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern KMF_RETURN kmf_list_crl(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern KMF_RETURN kmf_find_crl(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern KMF_RETURN kmf_find_cert_in_crl(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern KMF_RETURN kmf_verify_crl_file(KMF_HANDLE_T, char *, KMF_DATA *); +extern KMF_RETURN kmf_check_crl_date(KMF_HANDLE_T, char *); +extern KMF_RETURN kmf_download_crl(KMF_HANDLE_T, char *, char *, int, unsigned int, char *, KMF_ENCODE_FORMAT *); -extern KMF_RETURN KMF_IsCRLFile(KMF_HANDLE_T, char *, KMF_ENCODE_FORMAT *); +extern KMF_RETURN kmf_is_crl_file(KMF_HANDLE_T, char *, KMF_ENCODE_FORMAT *); /* * CSR operations. */ -extern KMF_RETURN KMF_SetCSRPubKey(KMF_HANDLE_T, +extern KMF_RETURN kmf_create_csr_file(KMF_DATA *, KMF_ENCODE_FORMAT, char *); +extern KMF_RETURN kmf_set_csr_pubkey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_CSR_DATA *); -extern KMF_RETURN KMF_SetCSRVersion(KMF_CSR_DATA *, uint32_t); -extern KMF_RETURN KMF_SetCSRSubjectName(KMF_CSR_DATA *, KMF_X509_NAME *); -extern KMF_RETURN KMF_CreateCSRFile(KMF_DATA *, KMF_ENCODE_FORMAT, char *); -extern KMF_RETURN KMF_SetCSRExtension(KMF_CSR_DATA *, KMF_X509_EXTENSION *); -extern KMF_RETURN KMF_SetCSRSignatureAlgorithm(KMF_CSR_DATA *, - KMF_ALGORITHM_INDEX); -extern KMF_RETURN KMF_SetCSRSubjectAltName(KMF_CSR_DATA *, char *, +extern KMF_RETURN kmf_set_csr_version(KMF_CSR_DATA *, uint32_t); +extern KMF_RETURN kmf_set_csr_subject(KMF_CSR_DATA *, KMF_X509_NAME *); +extern KMF_RETURN kmf_set_csr_extn(KMF_CSR_DATA *, KMF_X509_EXTENSION *); +extern KMF_RETURN kmf_set_csr_sig_alg(KMF_CSR_DATA *, KMF_ALGORITHM_INDEX); +extern KMF_RETURN kmf_set_csr_subject_altname(KMF_CSR_DATA *, char *, int, KMF_GENERALNAMECHOICES); -extern KMF_RETURN KMF_SetCSRKeyUsage(KMF_CSR_DATA *, int, uint16_t); -extern KMF_RETURN KMF_SignCSR(KMF_HANDLE_T, const KMF_CSR_DATA *, +extern KMF_RETURN kmf_set_csr_ku(KMF_CSR_DATA *, int, uint16_t); +extern KMF_RETURN kmf_sign_csr(KMF_HANDLE_T, const KMF_CSR_DATA *, KMF_KEY_HANDLE *, KMF_DATA *); /* * GetCert operations. */ -extern KMF_RETURN KMF_GetCertExtensionData(const KMF_DATA *, KMF_OID *, +extern KMF_RETURN kmf_get_cert_extn(const KMF_DATA *, KMF_OID *, KMF_X509_EXTENSION *); -extern KMF_RETURN KMF_GetCertCriticalExtensions(const KMF_DATA *, +extern KMF_RETURN kmf_get_cert_extns(const KMF_DATA *, KMF_FLAG_CERT_EXTN, KMF_X509_EXTENSION **, int *); -extern KMF_RETURN KMF_GetCertNonCriticalExtensions(const KMF_DATA *, - KMF_X509_EXTENSION **, int *); - -extern KMF_RETURN KMF_GetCertKeyUsageExt(const KMF_DATA *, - KMF_X509EXT_KEY_USAGE *); +extern KMF_RETURN kmf_get_cert_ku(const KMF_DATA *, KMF_X509EXT_KEY_USAGE *); -extern KMF_RETURN KMF_GetCertEKU(const KMF_DATA *, KMF_X509EXT_EKU *); +extern KMF_RETURN kmf_get_cert_eku(const KMF_DATA *, KMF_X509EXT_EKU *); -extern KMF_RETURN KMF_GetCertBasicConstraintExt(const KMF_DATA *, +extern KMF_RETURN kmf_get_cert_basic_constraint(const KMF_DATA *, KMF_BOOL *, KMF_X509EXT_BASICCONSTRAINTS *); -extern KMF_RETURN KMF_GetCertPoliciesExt(const KMF_DATA *, +extern KMF_RETURN kmf_get_cert_policies(const KMF_DATA *, KMF_BOOL *, KMF_X509EXT_CERT_POLICIES *); -extern KMF_RETURN KMF_GetCertAuthInfoAccessExt(const KMF_DATA *, +extern KMF_RETURN kmf_get_cert_auth_info_access(const KMF_DATA *, KMF_X509EXT_AUTHINFOACCESS *); -extern KMF_RETURN KMF_GetCertCRLDistributionPointsExt(const KMF_DATA *, +extern KMF_RETURN kmf_get_cert_crl_dist_pts(const KMF_DATA *, KMF_X509EXT_CRLDISTPOINTS *); -extern KMF_RETURN KMF_GetCertVersionString(KMF_HANDLE_T, - const KMF_DATA *, char **); +extern KMF_RETURN kmf_get_cert_version_str(KMF_HANDLE_T, const KMF_DATA *, + char **); -extern KMF_RETURN KMF_GetCertSubjectNameString(KMF_HANDLE_T, const KMF_DATA *, +extern KMF_RETURN kmf_get_cert_subject_str(KMF_HANDLE_T, const KMF_DATA *, char **); -extern KMF_RETURN KMF_GetCertIssuerNameString(KMF_HANDLE_T, - const KMF_DATA *, char **); +extern KMF_RETURN kmf_get_cert_issuer_str(KMF_HANDLE_T, const KMF_DATA *, + char **); -extern KMF_RETURN KMF_GetCertSerialNumberString(KMF_HANDLE_T, const KMF_DATA *, +extern KMF_RETURN kmf_get_cert_serial_str(KMF_HANDLE_T, const KMF_DATA *, char **); -extern KMF_RETURN KMF_GetCertStartDateString(KMF_HANDLE_T, - const KMF_DATA *, char **); +extern KMF_RETURN kmf_get_cert_start_date_str(KMF_HANDLE_T, const KMF_DATA *, + char **); -extern KMF_RETURN KMF_GetCertEndDateString(KMF_HANDLE_T, - const KMF_DATA *, char **); +extern KMF_RETURN kmf_get_cert_end_date_str(KMF_HANDLE_T, const KMF_DATA *, + char **); -extern KMF_RETURN KMF_GetCertPubKeyAlgString(KMF_HANDLE_T, - const KMF_DATA *, char **); +extern KMF_RETURN kmf_get_cert_pubkey_alg_str(KMF_HANDLE_T, const KMF_DATA *, + char **); -extern KMF_RETURN KMF_GetCertSignatureAlgString(KMF_HANDLE_T, - const KMF_DATA *, char **); +extern KMF_RETURN kmf_get_cert_sig_alg_str(KMF_HANDLE_T, const KMF_DATA *, + char **); -extern KMF_RETURN KMF_GetCertPubKeyDataString(KMF_HANDLE_T, - const KMF_DATA *, char **); +extern KMF_RETURN kmf_get_cert_pubkey_str(KMF_HANDLE_T, const KMF_DATA *, + char **); -extern KMF_RETURN KMF_GetCertEmailString(KMF_HANDLE_T, - const KMF_DATA *, char **); +extern KMF_RETURN kmf_get_cert_email_str(KMF_HANDLE_T, const KMF_DATA *, + char **); -extern KMF_RETURN KMF_GetCertExtensionString(KMF_HANDLE_T, const KMF_DATA *, +extern KMF_RETURN kmf_get_cert_extn_str(KMF_HANDLE_T, const KMF_DATA *, KMF_PRINTABLE_ITEM, char **); -extern KMF_RETURN KMF_GetCertIDData(const KMF_DATA *, KMF_DATA *); -extern KMF_RETURN KMF_GetCertIDString(const KMF_DATA *, char **); -extern KMF_RETURN KMF_GetCertValidity(const KMF_DATA *, time_t *, time_t *); +extern KMF_RETURN kmf_get_cert_id_data(const KMF_DATA *, KMF_DATA *); + +extern KMF_RETURN kmf_get_cert_id_str(const KMF_DATA *, char **); + +extern KMF_RETURN kmf_get_cert_validity(const KMF_DATA *, time_t *, time_t *); + /* * SetCert operations */ -extern KMF_RETURN KMF_SetCertPubKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, +extern KMF_RETURN kmf_set_cert_pubkey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_X509_CERTIFICATE *); -extern KMF_RETURN KMF_SetCertSubjectName(KMF_X509_CERTIFICATE *, +extern KMF_RETURN kmf_set_cert_subject(KMF_X509_CERTIFICATE *, KMF_X509_NAME *); -extern KMF_RETURN KMF_SetCertKeyUsage(KMF_X509_CERTIFICATE *, int, uint16_t); +extern KMF_RETURN kmf_set_cert_ku(KMF_X509_CERTIFICATE *, int, uint16_t); -extern KMF_RETURN KMF_SetCertIssuerName(KMF_X509_CERTIFICATE *, +extern KMF_RETURN kmf_set_cert_issuer(KMF_X509_CERTIFICATE *, KMF_X509_NAME *); -extern KMF_RETURN KMF_SetCertSignatureAlgorithm(KMF_X509_CERTIFICATE *, +extern KMF_RETURN kmf_set_cert_sig_alg(KMF_X509_CERTIFICATE *, KMF_ALGORITHM_INDEX); -extern KMF_RETURN KMF_SetCertValidityTimes(KMF_X509_CERTIFICATE *, +extern KMF_RETURN kmf_set_cert_validity(KMF_X509_CERTIFICATE *, time_t, uint32_t); -extern KMF_RETURN KMF_SetCertSerialNumber(KMF_X509_CERTIFICATE *, +extern KMF_RETURN kmf_set_cert_serial(KMF_X509_CERTIFICATE *, KMF_BIGINT *); -extern KMF_RETURN KMF_SetCertVersion(KMF_X509_CERTIFICATE *, uint32_t); +extern KMF_RETURN kmf_set_cert_version(KMF_X509_CERTIFICATE *, uint32_t); -extern KMF_RETURN KMF_SetCertIssuerAltName(KMF_X509_CERTIFICATE *, +extern KMF_RETURN kmf_set_cert_issuer_altname(KMF_X509_CERTIFICATE *, int, KMF_GENERALNAMECHOICES, char *); -extern KMF_RETURN KMF_SetCertSubjectAltName(KMF_X509_CERTIFICATE *, +extern KMF_RETURN kmf_set_cert_subject_altname(KMF_X509_CERTIFICATE *, int, KMF_GENERALNAMECHOICES, char *); -extern KMF_RETURN KMF_AddCertEKU(KMF_X509_CERTIFICATE *, KMF_OID *, int); +extern KMF_RETURN kmf_add_cert_eku(KMF_X509_CERTIFICATE *, KMF_OID *, int); -extern KMF_RETURN KMF_SetCertExtension(KMF_X509_CERTIFICATE *, +extern KMF_RETURN kmf_set_cert_extn(KMF_X509_CERTIFICATE *, KMF_X509_EXTENSION *); -extern KMF_RETURN KMF_SetCertBasicConstraintExt(KMF_X509_CERTIFICATE *, +extern KMF_RETURN kmf_set_cert_basic_constraint(KMF_X509_CERTIFICATE *, KMF_BOOL, KMF_X509EXT_BASICCONSTRAINTS *); -extern KMF_RETURN KMF_ExportPK12(KMF_HANDLE_T, KMF_EXPORTP12_PARAMS *, char *); -extern KMF_RETURN KMF_ImportPK12(KMF_HANDLE_T, char *, KMF_CREDENTIAL *, - KMF_DATA **, int *, KMF_RAW_KEY_DATA **, int *); -extern KMF_RETURN KMF_ImportKeypair(KMF_HANDLE_T, char *, KMF_CREDENTIAL *, + +/* + * PK12 operations + */ +extern KMF_RETURN kmf_export_pk12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); + +extern KMF_RETURN kmf_build_pk12(KMF_HANDLE_T, int, KMF_X509_DER_CERT *, + int, KMF_KEY_HANDLE *, KMF_CREDENTIAL *, char *); + +extern KMF_RETURN kmf_import_objects(KMF_HANDLE_T, char *, KMF_CREDENTIAL *, KMF_DATA **, int *, KMF_RAW_KEY_DATA **, int *); /* - * Get OCSP response operation. + * OCSP operations */ -extern KMF_RETURN KMF_GetOCSPForCert(KMF_HANDLE_T, KMF_DATA *, KMF_DATA *, +extern KMF_RETURN kmf_get_ocsp_for_cert(KMF_HANDLE_T, KMF_DATA *, KMF_DATA *, KMF_DATA *); -extern KMF_RETURN KMF_CreateOCSPRequest(KMF_HANDLE_T, KMF_OCSPREQUEST_PARAMS *, - char *); +extern KMF_RETURN kmf_create_ocsp_request(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); -extern KMF_RETURN KMF_GetEncodedOCSPResponse(KMF_HANDLE_T, char *, char *, int, - char *, int, char *, unsigned int); +extern KMF_RETURN kmf_get_encoded_ocsp_response(KMF_HANDLE_T, char *, + char *, int, char *, int, char *, unsigned int); -extern KMF_RETURN KMF_GetOCSPStatusForCert(KMF_HANDLE_T, - KMF_OCSPRESPONSE_PARAMS_INPUT *, - KMF_OCSPRESPONSE_PARAMS_OUTPUT *); +extern KMF_RETURN kmf_get_ocsp_status_for_cert(KMF_HANDLE_T, int, + KMF_ATTRIBUTE *); /* * Policy Operations */ -extern KMF_RETURN KMF_SetPolicy(KMF_HANDLE_T, char *, char *); +extern KMF_RETURN kmf_set_policy(KMF_HANDLE_T, char *, char *); /* * Error handling. */ -extern KMF_RETURN KMF_GetPluginErrorString(KMF_HANDLE_T, char **); -extern KMF_RETURN KMF_GetKMFErrorString(KMF_RETURN, char **); +extern KMF_RETURN kmf_get_plugin_error_str(KMF_HANDLE_T, char **); +extern KMF_RETURN kmf_get_kmf_error_str(KMF_RETURN, char **); /* * Miscellaneous */ -extern KMF_RETURN KMF_DNParser(char *, KMF_X509_NAME *); -extern KMF_RETURN KMF_DN2Der(KMF_X509_NAME *, KMF_DATA *); -extern KMF_RETURN KMF_ReadInputFile(KMF_HANDLE_T, char *, KMF_DATA *); -extern KMF_RETURN KMF_Der2Pem(KMF_OBJECT_TYPE, unsigned char *, +extern KMF_RETURN kmf_dn_parser(char *, KMF_X509_NAME *); +extern KMF_RETURN kmf_read_input_file(KMF_HANDLE_T, char *, KMF_DATA *); +extern KMF_RETURN kmf_der_to_pem(KMF_OBJECT_TYPE, unsigned char *, int, unsigned char **, int *); -extern KMF_RETURN KMF_Pem2Der(unsigned char *, int, unsigned char **, int *); -extern char *KMF_OID2String(KMF_OID *); -extern KMF_RETURN KMF_String2OID(char *, KMF_OID *); -extern int KMF_CompareRDNs(KMF_X509_NAME *, KMF_X509_NAME *); -extern KMF_RETURN KMF_GetFileFormat(char *, KMF_ENCODE_FORMAT *); -extern uint16_t KMF_StringToKeyUsage(char *); -extern KMF_RETURN KMF_SetTokenPin(KMF_HANDLE_T, KMF_SETPIN_PARAMS *, - KMF_CREDENTIAL *); -extern KMF_RETURN KMF_HexString2Bytes(unsigned char *, unsigned char **, +extern KMF_RETURN kmf_pem_to_der(unsigned char *, int, unsigned char **, int *); +extern char *kmf_oid_to_string(KMF_OID *); +extern KMF_RETURN kmf_string_to_oid(char *, KMF_OID *); +extern int kmf_compare_rdns(KMF_X509_NAME *, KMF_X509_NAME *); +extern KMF_RETURN kmf_get_file_format(char *, KMF_ENCODE_FORMAT *); +extern uint32_t kmf_string_to_ku(char *); +extern char *kmf_ku_to_string(uint32_t); +extern KMF_RETURN kmf_hexstr_to_bytes(unsigned char *, unsigned char **, size_t *); +#define KMF_CompareRDNs kmf_compare_rdns + /* * Memory cleanup operations */ -extern void KMF_FreeDN(KMF_X509_NAME *); -extern void KMF_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); -extern void KMF_FreeData(KMF_DATA *); -extern void KMF_FreeAlgOID(KMF_X509_ALGORITHM_IDENTIFIER *); -extern void KMF_FreeExtension(KMF_X509_EXTENSION *); -extern void KMF_FreeTBSCSR(KMF_TBS_CSR *); -extern void KMF_FreeSignedCSR(KMF_CSR_DATA *); -extern void KMF_FreeTBSCert(KMF_X509_TBS_CERT *); -extern void KMF_FreeSignedCert(KMF_X509_CERTIFICATE *); -extern void KMF_FreeString(char *); -extern void KMF_FreeEKU(KMF_X509EXT_EKU *); -extern void KMF_FreeSPKI(KMF_X509_SPKI *); -extern void KMF_FreeKMFKey(KMF_HANDLE_T, KMF_KEY_HANDLE *); -extern void KMF_FreeBigint(KMF_BIGINT *); -extern void KMF_FreeRawKey(KMF_RAW_KEY_DATA *); -extern void KMF_FreeRawSymKey(KMF_RAW_SYM_KEY *); -extern void KMF_FreeCRLDistributionPoints(KMF_X509EXT_CRLDISTPOINTS *); +extern void kmf_free_dn(KMF_X509_NAME *); +extern void kmf_free_kmf_cert(KMF_HANDLE_T, KMF_X509_DER_CERT *); +extern void kmf_free_data(KMF_DATA *); +extern void kmf_free_algoid(KMF_X509_ALGORITHM_IDENTIFIER *); +extern void kmf_free_extn(KMF_X509_EXTENSION *); +extern void kmf_free_tbs_csr(KMF_TBS_CSR *); +extern void kmf_free_signed_csr(KMF_CSR_DATA *); +extern void kmf_free_tbs_cert(KMF_X509_TBS_CERT *); +extern void kmf_free_signed_cert(KMF_X509_CERTIFICATE *); +extern void kmf_free_str(char *); +extern void kmf_free_eku(KMF_X509EXT_EKU *); +extern void kmf_free_spki(KMF_X509_SPKI *); +extern void kmf_free_kmf_key(KMF_HANDLE_T, KMF_KEY_HANDLE *); +extern void kmf_free_bigint(KMF_BIGINT *); +extern void kmf_free_raw_key(KMF_RAW_KEY_DATA *); +extern void kmf_free_raw_sym_key(KMF_RAW_SYM_KEY *); +extern void kmf_free_crl_dist_pts(KMF_X509EXT_CRLDISTPOINTS *); /* APIs for PKCS#11 token */ -extern KMF_RETURN KMF_PK11TokenLookup(KMF_HANDLE_T, char *, CK_SLOT_ID *); -extern CK_SESSION_HANDLE KMF_GetPK11Handle(KMF_HANDLE_T); +extern KMF_RETURN kmf_pk11_token_lookup(KMF_HANDLE_T, char *, CK_SLOT_ID *); +extern KMF_RETURN kmf_set_token_pin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); +extern CK_SESSION_HANDLE kmf_get_pk11_handle(KMF_HANDLE_T); + +/* + * Attribute management routines. + */ +int kmf_find_attr(KMF_ATTR_TYPE, KMF_ATTRIBUTE *, int); +void *kmf_get_attr_ptr(KMF_ATTR_TYPE, KMF_ATTRIBUTE *, int); +KMF_RETURN kmf_get_attr(KMF_ATTR_TYPE, KMF_ATTRIBUTE *, int, void *, + uint32_t *); +KMF_RETURN kmf_get_string_attr(KMF_ATTR_TYPE, KMF_ATTRIBUTE *, int, char **); +KMF_RETURN kmf_set_attr(KMF_ATTRIBUTE *, int, KMF_ATTR_TYPE, void *, uint32_t); +void kmf_set_attr_at_index(KMF_ATTRIBUTE *, int, KMF_ATTR_TYPE, + void *, uint32_t); + +/* + * Legacy support only - do not use these APIs - they can be removed at any + * time. + */ +extern KMF_RETURN KMF_ConfigureKeystore(KMF_HANDLE_T, KMF_CONFIG_PARAMS *); +extern KMF_RETURN KMF_CreateCSRFile(KMF_DATA *, KMF_ENCODE_FORMAT, char *); +extern KMF_RETURN KMF_CreateKeypair(KMF_HANDLE_T, + KMF_CREATEKEYPAIR_PARAMS *, KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); +extern KMF_RETURN KMF_DNParser(char *, KMF_X509_NAME *); +extern KMF_RETURN KMF_Finalize(KMF_HANDLE_T); +extern KMF_RETURN KMF_FindCert(KMF_HANDLE_T, KMF_FINDCERT_PARAMS *, + KMF_X509_DER_CERT *, uint32_t *); +extern KMF_RETURN KMF_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, + KMF_KEY_HANDLE *, uint32_t *); +extern void KMF_FreeData(KMF_DATA *); +extern void KMF_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); +extern void KMF_FreeKMFKey(KMF_HANDLE_T, KMF_KEY_HANDLE *); +extern void KMF_FreeSignedCSR(KMF_CSR_DATA *); +extern KMF_RETURN KMF_GetCertIDString(const KMF_DATA *, char **); +extern KMF_RETURN KMF_GetCertIssuerNameString(KMF_HANDLE_T, + const KMF_DATA *, char **); +extern KMF_RETURN KMF_GetCertSubjectNameString(KMF_HANDLE_T, + const KMF_DATA *, char **); +extern KMF_RETURN KMF_GetKMFErrorString(KMF_RETURN, char **); +extern KMF_RETURN KMF_Initialize(KMF_HANDLE_T *, char *, char *); +extern KMF_RETURN KMF_ReadInputFile(KMF_HANDLE_T, char *, KMF_DATA *); +extern KMF_RETURN KMF_SetCSRPubKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, + KMF_CSR_DATA *); +extern KMF_RETURN KMF_SetCSRSignatureAlgorithm(KMF_CSR_DATA *, + KMF_ALGORITHM_INDEX); +extern KMF_RETURN KMF_SetCSRSubjectName(KMF_CSR_DATA *, KMF_X509_NAME *); +extern KMF_RETURN KMF_SetCSRVersion(KMF_CSR_DATA *, uint32_t); +extern KMF_RETURN KMF_SignCSR(KMF_HANDLE_T, const KMF_CSR_DATA *, + KMF_KEY_HANDLE *, KMF_DATA *); +extern KMF_RETURN KMF_SignDataWithKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, + KMF_OID *, KMF_DATA *, KMF_DATA *); +extern KMF_RETURN KMF_VerifyCertWithCert(KMF_HANDLE_T, const KMF_DATA *, + const KMF_DATA *); +extern KMF_RETURN KMF_VerifyDataWithCert(KMF_HANDLE_T, + KMF_KEYSTORE_TYPE, KMF_ALGORITHM_INDEX, KMF_DATA *, KMF_DATA *, + const KMF_DATA *); #ifdef __cplusplus } diff --git a/usr/src/lib/libkmf/include/kmfapiP.h b/usr/src/lib/libkmf/include/kmfapiP.h index 715abfaf31..ac89acb565 100644 --- a/usr/src/lib/libkmf/include/kmfapiP.h +++ b/usr/src/lib/libkmf/include/kmfapiP.h @@ -39,13 +39,13 @@ typedef struct { ushort_t version; KMF_RETURN (*ConfigureKeystore) ( KMF_HANDLE_T, - KMF_CONFIG_PARAMS *); + int, + KMF_ATTRIBUTE *); KMF_RETURN (*FindCert) ( KMF_HANDLE_T, - KMF_FINDCERT_PARAMS *, - KMF_X509_DER_CERT *, - uint32_t *); + int, + KMF_ATTRIBUTE *); void (*FreeKMFCert) ( KMF_HANDLE_T, @@ -53,36 +53,33 @@ typedef struct { KMF_RETURN (*StoreCert) ( KMF_HANDLE_T, - KMF_STORECERT_PARAMS *, - KMF_DATA *); + int, KMF_ATTRIBUTE *); KMF_RETURN (*ImportCert) ( KMF_HANDLE_T, - KMF_IMPORTCERT_PARAMS *); + int, KMF_ATTRIBUTE *); KMF_RETURN (*ImportCRL) ( KMF_HANDLE_T, - KMF_IMPORTCRL_PARAMS *); + int, KMF_ATTRIBUTE *); KMF_RETURN (*DeleteCert) ( KMF_HANDLE_T, - KMF_DELETECERT_PARAMS *); + int, KMF_ATTRIBUTE *); KMF_RETURN (*DeleteCRL) ( KMF_HANDLE_T, - KMF_DELETECRL_PARAMS *); + int, KMF_ATTRIBUTE *); KMF_RETURN (*CreateKeypair) ( KMF_HANDLE_T, - KMF_CREATEKEYPAIR_PARAMS *, - KMF_KEY_HANDLE *, - KMF_KEY_HANDLE *); + int, + KMF_ATTRIBUTE *); KMF_RETURN (*FindKey) ( KMF_HANDLE_T, - KMF_FINDKEY_PARAMS *, - KMF_KEY_HANDLE *, - uint32_t *); + int, + KMF_ATTRIBUTE *); KMF_RETURN (*EncodePubkeyData) ( KMF_HANDLE_T, @@ -98,35 +95,29 @@ typedef struct { KMF_RETURN (*DeleteKey) ( KMF_HANDLE_T, - KMF_DELETEKEY_PARAMS *, - KMF_KEY_HANDLE *, - boolean_t); + int, + KMF_ATTRIBUTE *); KMF_RETURN (*ListCRL) ( KMF_HANDLE_T, - KMF_LISTCRL_PARAMS *, - char **); + int, KMF_ATTRIBUTE *); KMF_RETURN (*FindCRL) ( KMF_HANDLE_T, - KMF_FINDCRL_PARAMS *, - char **, - int *); + int, KMF_ATTRIBUTE *); KMF_RETURN (*FindCertInCRL) ( KMF_HANDLE_T, - KMF_FINDCERTINCRL_PARAMS *); + int, KMF_ATTRIBUTE *); KMF_RETURN (*GetErrorString) ( KMF_HANDLE_T, char **); - KMF_RETURN (*GetPrikeyByCert) ( + KMF_RETURN (*FindPrikeyByCert) ( KMF_HANDLE_T, - KMF_CRYPTOWITHCERT_PARAMS *, - KMF_DATA *, - KMF_KEY_HANDLE *, - KMF_KEY_ALG); + int, + KMF_ATTRIBUTE *); KMF_RETURN (*DecryptData) ( KMF_HANDLE_T, @@ -135,22 +126,15 @@ typedef struct { KMF_DATA *, KMF_DATA *); - KMF_RETURN (*ExportP12)( - KMF_HANDLE_T, - KMF_EXPORTP12_PARAMS *, - int, KMF_X509_DER_CERT *, - int, KMF_KEY_HANDLE *, - char *); - - KMF_RETURN (*StorePrivateKey)( + KMF_RETURN (*ExportPK12)( KMF_HANDLE_T, - KMF_STOREKEY_PARAMS *, - KMF_RAW_KEY_DATA *); + int, + KMF_ATTRIBUTE *); KMF_RETURN (*CreateSymKey) ( KMF_HANDLE_T, - KMF_CREATESYMKEY_PARAMS *, - KMF_KEY_HANDLE *); + int, + KMF_ATTRIBUTE *); KMF_RETURN (*GetSymKeyValue) ( KMF_HANDLE_T, @@ -159,8 +143,7 @@ typedef struct { KMF_RETURN (*SetTokenPin) ( KMF_HANDLE_T, - KMF_SETPIN_PARAMS *, - KMF_CREDENTIAL *); + int, KMF_ATTRIBUTE *); KMF_RETURN (*VerifyDataWithCert) ( KMF_HANDLE_T, @@ -169,11 +152,23 @@ typedef struct { KMF_DATA *, KMF_DATA *); + KMF_RETURN (*StoreKey) ( + KMF_HANDLE_T, + int, + KMF_ATTRIBUTE *); + void (*Finalize) (); } KMF_PLUGIN_FUNCLIST; typedef struct { + KMF_ATTR_TYPE type; + boolean_t null_value_ok; /* Is the pValue required */ + uint32_t minlen; + uint32_t maxlen; +} KMF_ATTRIBUTE_TESTER; + +typedef struct { KMF_KEYSTORE_TYPE type; char *applications; char *path; @@ -188,7 +183,7 @@ typedef struct _KMF_PLUGIN_LIST { typedef struct _kmf_handle { /* - * session handle opened by KMF_SelectToken() to talk + * session handle opened by kmf_select_token() to talk * to a specific slot in Crypto framework. It is used * by pkcs11 plugin module. */ @@ -228,11 +223,7 @@ KMF_RETURN VerifyDataWithKey(KMF_HANDLE_T, KMF_DATA *, KMF_ALGORITHM_INDEX, KMF_DATA *, KMF_DATA *); -KMF_RETURN -SignCsr(KMF_HANDLE_T, const KMF_DATA *, KMF_KEY_HANDLE *, - KMF_X509_ALGORITHM_IDENTIFIER *, KMF_DATA *); - -KMF_BOOL PKCS_ConvertAlgorithmId2PKCSKeyType( +KMF_BOOL pkcs_algid_to_keytype( KMF_ALGORITHM_INDEX, CK_KEY_TYPE *); KMF_RETURN PKCS_VerifyData( @@ -252,15 +243,19 @@ KMF_PLUGIN *FindPlugin(KMF_HANDLE_T, KMF_KEYSTORE_TYPE); KMF_BOOL IsEqualOid(KMF_OID *, KMF_OID *); -KMF_OID *X509_AlgIdToAlgorithmOid(KMF_ALGORITHM_INDEX); -KMF_ALGORITHM_INDEX X509_AlgorithmOidToAlgId(KMF_OID *); +KMF_RETURN copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid, + KMF_X509_ALGORITHM_IDENTIFIER *srcid); + +KMF_OID *x509_algid_to_algoid(KMF_ALGORITHM_INDEX); +KMF_ALGORITHM_INDEX x509_algoid_to_algid(KMF_OID *); + KMF_RETURN PKCS_AcquirePublicKeyHandle(CK_SESSION_HANDLE ckSession, const KMF_X509_SPKI *, CK_KEY_TYPE, CK_OBJECT_HANDLE *, KMF_BOOL *); KMF_RETURN GetIDFromSPKI(KMF_X509_SPKI *, KMF_DATA *); -KMF_RETURN KMF_SetAltName(KMF_X509_EXTENSIONS *, +KMF_RETURN kmf_set_altname(KMF_X509_EXTENSIONS *, KMF_OID *, int, KMF_GENERALNAMECHOICES, char *); KMF_RETURN GetSequenceContents(char *, size_t, char **, size_t *); KMF_X509_EXTENSION *FindExtn(KMF_X509_EXTENSIONS *, KMF_OID *); @@ -275,7 +270,10 @@ void free_dp(KMF_CRL_DIST_POINT *); KMF_RETURN set_key_usage_extension(KMF_X509_EXTENSIONS *, int, uint32_t); KMF_RETURN init_pk11(); -KMF_RETURN KMF_SelectToken(KMF_HANDLE_T, char *, int); +KMF_RETURN kmf_select_token(KMF_HANDLE_T, char *, int); + +KMF_RETURN test_attributes(int, KMF_ATTRIBUTE_TESTER *, + int, KMF_ATTRIBUTE_TESTER *, int, KMF_ATTRIBUTE *); /* Indexes into the key parts array for RSA keys */ diff --git a/usr/src/lib/libkmf/include/kmfpolicy.h b/usr/src/lib/libkmf/include/kmfpolicy.h index e00c55e620..e1cec2b56a 100644 --- a/usr/src/lib/libkmf/include/kmfpolicy.h +++ b/usr/src/lib/libkmf/include/kmfpolicy.h @@ -18,7 +18,7 @@ * * CDDL HEADER END * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _KMFPOLICY_H @@ -175,21 +175,18 @@ typedef struct { #define TMPFILE_TEMPLATE "policyXXXXXX" -extern char *ku2str(uint32_t); -extern uint32_t str2ku(char *); extern int parsePolicyElement(xmlNodePtr, KMF_POLICY_RECORD *); -extern char *KMF_OID2EKUString(KMF_OID *); -extern KMF_OID *kmf_ekuname2oid(char *); -extern KMF_OID *kmf_string2oid(char *); +extern char *kmf_oid_to_eku_string(KMF_OID *); +extern KMF_OID *kmf_ekuname_to_oid(char *); -extern KMF_RETURN KMF_GetPolicy(char *, char *, KMF_POLICY_RECORD *); -extern KMF_RETURN KMF_AddPolicyToDB(KMF_POLICY_RECORD *, char *, boolean_t); -extern KMF_RETURN KMF_DeletePolicyFromDB(char *, char *); -extern KMF_RETURN KMF_VerifyPolicy(KMF_POLICY_RECORD *); +extern KMF_RETURN kmf_get_policy(char *, char *, KMF_POLICY_RECORD *); +extern KMF_RETURN kmf_add_policy_to_db(KMF_POLICY_RECORD *, char *, boolean_t); +extern KMF_RETURN kmf_delete_policy_from_db(char *, char *); +extern KMF_RETURN kmf_verify_policy(KMF_POLICY_RECORD *); -extern void KMF_FreePolicyRecord(KMF_POLICY_RECORD *); -extern void KMF_FreeEKUPolicy(KMF_EKU_POLICY *); +extern void kmf_free_policy_record(KMF_POLICY_RECORD *); +extern void kmf_free_eku_policy(KMF_EKU_POLICY *); #ifdef __cplusplus } diff --git a/usr/src/lib/libkmf/include/kmftypes.h b/usr/src/lib/libkmf/include/kmftypes.h index c6bfa51f7b..e820b68b13 100644 --- a/usr/src/lib/libkmf/include/kmftypes.h +++ b/usr/src/lib/libkmf/include/kmftypes.h @@ -60,7 +60,7 @@ typedef struct kmf_x509_private { char *label; #define KMF_FLAG_CERT_VALID 1 /* contains valid certificate */ #define KMF_FLAG_CERT_SIGNED 2 /* this is a signed certificate */ -} KMF_X509_PRIVATE, KMF_X509_PRIVATE_PTR; +} KMF_X509_PRIVATE; /* * KMF_X509_DER_CERT @@ -92,6 +92,7 @@ typedef enum { KMF_FORMAT_RAWKEY = 4, /* For FindKey operation */ KMF_FORMAT_PEM_KEYPAIR = 5 } KMF_ENCODE_FORMAT; + #define KMF_FORMAT_NATIVE KMF_FORMAT_UNDEF typedef enum { @@ -100,6 +101,14 @@ typedef enum { KMF_EXPIRED_CERTS = 2 } KMF_CERT_VALIDITY; + +typedef enum { + KMF_ALL_EXTNS = 0, + KMF_CRITICAL_EXTNS = 1, + KMF_NONCRITICAL_EXTNS = 2 +} KMF_FLAG_CERT_EXTN; + + typedef enum { KMF_KU_SIGN_CERT = 0, KMF_KU_SIGN_DATA = 1, @@ -123,29 +132,6 @@ typedef enum { KMF_ALGID_SHA1WithDSA } KMF_ALGORITHM_INDEX; -/* Keystore Configuration */ -typedef struct { - char *configdir; - char *certPrefix; - char *keyPrefix; - char *secModName; -} KMF_NSS_CONFIG; - -typedef struct { - char *label; - boolean_t readonly; -} KMF_PKCS11_CONFIG; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - union { - KMF_NSS_CONFIG nss_conf; - KMF_PKCS11_CONFIG pkcs11_conf; - } ks_config_u; -} KMF_CONFIG_PARAMS; - -#define nssconfig ks_config_u.nss_conf -#define pkcs11config ks_config_u.pkcs11_conf /* * Generic credential structure used by other structures below @@ -157,78 +143,6 @@ typedef struct { uint32_t credlen; } KMF_CREDENTIAL; -typedef struct -{ - char *trustflag; - char *slotlabel; /* "internal" by default */ - int issuerId; - int subjectId; - char *crlfile; /* for ImportCRL */ - boolean_t crl_check; /* for ImportCRL */ - - /* - * The following 2 variables are for FindCertInCRL. The caller can - * either specify certLabel or provide the entire certificate in - * DER format as input. - */ - char *certLabel; /* for FindCertInCRL */ - KMF_DATA *certificate; /* for FindCertInCRL */ - - /* - * crl_subjName and crl_issuerName are used as the CRL deletion - * criteria. One should be non-NULL and the other one should be NULL. - * If crl_subjName is not NULL, then delete CRL by the subject name. - * Othewise, delete by the issuer name. - */ - char *crl_subjName; - char *crl_issuerName; -} KMF_NSS_PARAMS; - -typedef struct { - char *dirpath; - char *certfile; - char *crlfile; - char *keyfile; - char *outcrlfile; - boolean_t crl_check; /* CRL import check; default is true */ - KMF_ENCODE_FORMAT format; /* output file format */ -} KMF_OPENSSL_PARAMS; - -typedef struct { - boolean_t private; /* for finding CKA_PRIVATE objects */ - boolean_t sensitive; - boolean_t not_extractable; - boolean_t token; /* true == token object, false == session */ -} KMF_PKCS11_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - char *certLabel; - char *issuer; - char *subject; - char *idstr; - KMF_BIGINT *serial; - KMF_CERT_VALIDITY find_cert_validity; - - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - KMF_PKCS11_PARAMS pkcs11_opts; - } ks_opt_u; -} KMF_FINDCERT_PARAMS, KMF_DELETECERT_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - KMF_DATA *certificate; - KMF_DATA *ocsp_response; - - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - KMF_PKCS11_PARAMS pkcs11_opts; - } ks_opt_u; -} KMF_VALIDATECERT_PARAMS; - typedef enum { KMF_KEYALG_NONE = 0, KMF_RSA = 1, @@ -247,59 +161,6 @@ typedef enum { KMF_SYMMETRIC = 3 /* symmetric key */ }KMF_KEY_CLASS; -typedef struct { - KMF_KEYSTORE_TYPE kstype; - KMF_CREDENTIAL cred; - KMF_KEY_CLASS keyclass; - KMF_KEY_ALG keytype; - KMF_ENCODE_FORMAT format; /* for key */ - char *findLabel; - char *idstr; - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - KMF_PKCS11_PARAMS pkcs11_opts; - } ks_opt_u; -} KMF_FINDKEY_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; /* all */ - char *certLabel; - - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - } ks_opt_u; -} KMF_STORECERT_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - KMF_CREDENTIAL cred; - KMF_DATA *certificate; - char *label; - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - } ks_opt_u; -} KMF_STOREKEY_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - KMF_CREDENTIAL cred; - union { - KMF_NSS_PARAMS nss_opts; - } ks_opt_u; -} KMF_DELETEKEY_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - char *certfile; - char *certLabel; - - union { - KMF_NSS_PARAMS nss_opts; - } ks_opt_u; -} KMF_IMPORTCERT_PARAMS; typedef enum { KMF_CERT = 0, @@ -307,93 +168,6 @@ typedef enum { KMF_CRL = 2 }KMF_OBJECT_TYPE; -typedef struct { - KMF_KEYSTORE_TYPE kstype; - KMF_KEY_ALG keytype; - uint32_t keylength; - char *keylabel; - KMF_CREDENTIAL cred; - KMF_BIGINT rsa_exponent; - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - }ks_opt_u; -} KMF_CREATEKEYPAIR_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - } ks_opt_u; -} KMF_IMPORTCRL_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - } ks_opt_u; -} KMF_DELETECRL_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - } ks_opt_u; -} KMF_LISTCRL_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - union { - KMF_NSS_PARAMS nss_opts; - } ks_opt_u; -} KMF_FINDCRL_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - } ks_opt_u; -} KMF_FINDCERTINCRL_PARAMS; - -typedef struct { - char *crl_name; - KMF_DATA *tacert; -} KMF_VERIFYCRL_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - KMF_CREDENTIAL cred; - KMF_ENCODE_FORMAT format; /* for key */ - char *certLabel; - KMF_ALGORITHM_INDEX algid; - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - }ks_opt_u; -} KMF_CRYPTOWITHCERT_PARAMS; - -typedef struct { - char *crl_name; -} KMF_CHECKCRLDATE_PARAMS; - -typedef struct { - CK_SLOT_ID slot; -} pk11_setpin_opts; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - char *tokenname; - KMF_CREDENTIAL cred; /* current token PIN */ - union { - KMF_NSS_PARAMS nss_opts; - pk11_setpin_opts pkcs11_opts; - }ks_opt_u; -} KMF_SETPIN_PARAMS; typedef struct { KMF_BIGINT mod; @@ -411,6 +185,7 @@ typedef struct { KMF_BIGINT subprime; KMF_BIGINT base; KMF_BIGINT value; + KMF_BIGINT pubvalue; } KMF_RAW_DSA_KEY; typedef struct { @@ -418,7 +193,9 @@ typedef struct { } KMF_RAW_SYM_KEY; typedef struct { - KMF_KEY_ALG keytype; + KMF_KEY_ALG keytype; + boolean_t sensitive; + boolean_t not_extractable; union { KMF_RAW_RSA_KEY rsa; KMF_RAW_DSA_KEY dsa; @@ -426,65 +203,6 @@ typedef struct { }rawdata; } KMF_RAW_KEY_DATA; -typedef struct { - KMF_KEYSTORE_TYPE kstype; - char *certLabel; - char *issuer; - char *subject; - char *idstr; - KMF_BIGINT *serial; - KMF_CREDENTIAL cred; /* cred for accessing the token */ - KMF_CREDENTIAL p12cred; /* cred used for securing the file */ - - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - }ks_opt_u; -} KMF_EXPORTP12_PARAMS; - -typedef struct { - KMF_KEYSTORE_TYPE kstype; - KMF_KEY_ALG keytype; - uint32_t keylength; - char *keylabel; - KMF_CREDENTIAL cred; - union { - KMF_NSS_PARAMS nss_opts; - KMF_OPENSSL_PARAMS openssl_opts; - KMF_PKCS11_PARAMS pkcs11_opts; - }ks_opt_u; -} KMF_CREATESYMKEY_PARAMS; - -/* Data structures for OCSP support */ -typedef struct { - KMF_DATA *issuer_cert; - KMF_DATA *user_cert; -} KMF_OCSPREQUEST_PARAMS; - -typedef struct { - KMF_DATA *response; - KMF_DATA *issuer_cert; - KMF_DATA *user_cert; - KMF_DATA *signer_cert; /* can be NULL */ - boolean_t ignore_response_sign; /* default is FALSE */ - uint32_t response_lifetime; /* in seconds */ -} KMF_OCSPRESPONSE_PARAMS_INPUT; - -typedef enum { - OCSP_GOOD = 0, - OCSP_REVOKED = 1, - OCSP_UNKNOWN = 2 -} KMF_OCSP_CERT_STATUS; - -typedef struct { - int response_status; - int reason; /* if revoked */ - KMF_OCSP_CERT_STATUS cert_status; -} KMF_OCSPRESPONSE_PARAMS_OUTPUT; - -#define nssparms ks_opt_u.nss_opts -#define sslparms ks_opt_u.openssl_opts -#define pkcs11parms ks_opt_u.pkcs11_opts typedef struct { KMF_KEYSTORE_TYPE kstype; @@ -605,9 +323,17 @@ typedef enum { KMF_KEYSTORE_ALREADY_INITIALIZED = 0x50, KMF_ERR_SENSITIVE_KEY = 0x51, KMF_ERR_UNEXTRACTABLE_KEY = 0x52, - KMF_ERR_KEY_MISMATCH = 0x53 + KMF_ERR_KEY_MISMATCH = 0x53, + KMF_ERR_ATTR_NOT_FOUND = 0x54 } KMF_RETURN; +/* Data structures for OCSP support */ +typedef enum { + OCSP_GOOD = 0, + OCSP_REVOKED = 1, + OCSP_UNKNOWN = 2 +} KMF_OCSP_CERT_STATUS; + typedef enum { OCSP_SUCCESS = 0, OCSP_MALFORMED_REQUEST = 1, @@ -984,6 +710,90 @@ typedef struct { KMF_CRL_DIST_POINT *dplist; } KMF_X509EXT_CRLDISTPOINTS; +typedef enum { + KMF_DATA_ATTR, + KMF_OID_ATTR, + KMF_BIGINT_ATTR, + KMF_X509_DER_CERT_ATTR, + KMF_KEYSTORE_TYPE_ATTR, + KMF_ENCODE_FORMAT_ATTR, + KMF_CERT_VALIDITY_ATTR, + KMF_KU_PURPOSE_ATTR, + KMF_ALGORITHM_INDEX_ATTR, + KMF_TOKEN_LABEL_ATTR, + KMF_READONLY_ATTR, + KMF_DIRPATH_ATTR, + KMF_CERTPREFIX_ATTR, + KMF_KEYPREFIX_ATTR, + KMF_SECMODNAME_ATTR, + KMF_CREDENTIAL_ATTR, + KMF_TRUSTFLAG_ATTR, + KMF_CRL_FILENAME_ATTR, + KMF_CRL_CHECK_ATTR, + KMF_CRL_DATA_ATTR, + KMF_CRL_SUBJECT_ATTR, + KMF_CRL_ISSUER_ATTR, + KMF_CRL_NAMELIST_ATTR, + KMF_CRL_COUNT_ATTR, + KMF_CRL_OUTFILE_ATTR, + KMF_CERT_LABEL_ATTR, + KMF_SUBJECT_NAME_ATTR, + KMF_ISSUER_NAME_ATTR, + KMF_CERT_FILENAME_ATTR, + KMF_KEY_FILENAME_ATTR, + KMF_OUTPUT_FILENAME_ATTR, + KMF_IDSTR_ATTR, + KMF_CERT_DATA_ATTR, + KMF_OCSP_RESPONSE_DATA_ATTR, + KMF_OCSP_RESPONSE_STATUS_ATTR, + KMF_OCSP_RESPONSE_REASON_ATTR, + KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, + KMF_OCSP_REQUEST_FILENAME_ATTR, + KMF_KEYALG_ATTR, + KMF_KEYCLASS_ATTR, + KMF_KEYLABEL_ATTR, + KMF_KEYLENGTH_ATTR, + KMF_RSAEXP_ATTR, + KMF_TACERT_DATA_ATTR, + KMF_SLOT_ID_ATTR, + KMF_PK12CRED_ATTR, + KMF_ISSUER_CERT_DATA_ATTR, + KMF_USER_CERT_DATA_ATTR, + KMF_SIGNER_CERT_DATA_ATTR, + KMF_IGNORE_RESPONSE_SIGN_ATTR, + KMF_RESPONSE_LIFETIME_ATTR, + KMF_KEY_HANDLE_ATTR, + KMF_PRIVKEY_HANDLE_ATTR, + KMF_PUBKEY_HANDLE_ATTR, + KMF_ERROR_ATTR, + KMF_X509_NAME_ATTR, + KMF_X509_SPKI_ATTR, + KMF_X509_CERTIFICATE_ATTR, + KMF_RAW_KEY_ATTR, + KMF_CSR_DATA_ATTR, + KMF_GENERALNAMECHOICES_ATTR, + KMF_STOREKEY_BOOL_ATTR, + KMF_SENSITIVE_BOOL_ATTR, + KMF_NON_EXTRACTABLE_BOOL_ATTR, + KMF_TOKEN_BOOL_ATTR, + KMF_PRIVATE_BOOL_ATTR, + KMF_NEWPIN_ATTR, + KMF_IN_SIGN_ATTR, + KMF_OUT_DATA_ATTR, + KMF_COUNT_ATTR, + KMF_DESTROY_BOOL_ATTR, + KMF_TBS_CERT_DATA_ATTR, + KMF_PLAINTEXT_DATA_ATTR, + KMF_CIPHERTEXT_DATA_ATTR, + KMF_VALIDATE_RESULT_ATTR, + KMF_KEY_DATA_ATTR +} KMF_ATTR_TYPE; + +typedef struct { + KMF_ATTR_TYPE type; + void *pValue; + uint32_t valueLen; +} KMF_ATTRIBUTE; /* * Definitions for common X.509v3 certificate attribute OIDs @@ -1356,6 +1166,145 @@ KMFOID_X9CM_DSAWithSHA1; #define KMF_EKU_OCSPSIGNING 0x20 +/* + * Legacy support only - do not use these data structures - they can be + * removed at any time. + */ + +/* Keystore Configuration */ +typedef struct { + char *configdir; + char *certPrefix; + char *keyPrefix; + char *secModName; +} KMF_NSS_CONFIG; + +typedef struct { + char *label; + boolean_t readonly; +} KMF_PKCS11_CONFIG; + +typedef struct { + KMF_KEYSTORE_TYPE kstype; + union { + KMF_NSS_CONFIG nss_conf; + KMF_PKCS11_CONFIG pkcs11_conf; + } ks_config_u; +} KMF_CONFIG_PARAMS; + +#define nssconfig ks_config_u.nss_conf +#define pkcs11config ks_config_u.pkcs11_conf + + +typedef struct +{ + char *trustflag; + char *slotlabel; /* "internal" by default */ + int issuerId; + int subjectId; + char *crlfile; /* for ImportCRL */ + boolean_t crl_check; /* for ImportCRL */ + + /* + * The following 2 variables are for FindCertInCRL. The caller can + * either specify certLabel or provide the entire certificate in + * DER format as input. + */ + char *certLabel; /* for FindCertInCRL */ + KMF_DATA *certificate; /* for FindCertInCRL */ + + /* + * crl_subjName and crl_issuerName are used as the CRL deletion + * criteria. One should be non-NULL and the other one should be NULL. + * If crl_subjName is not NULL, then delete CRL by the subject name. + * Othewise, delete by the issuer name. + */ + char *crl_subjName; + char *crl_issuerName; +} KMF_NSS_PARAMS; + +typedef struct { + char *dirpath; + char *certfile; + char *crlfile; + char *keyfile; + char *outcrlfile; + boolean_t crl_check; /* CRL import check; default is true */ + KMF_ENCODE_FORMAT format; /* output file format */ +} KMF_OPENSSL_PARAMS; + +typedef struct { + boolean_t private; /* for finding CKA_PRIVATE objects */ + boolean_t sensitive; + boolean_t not_extractable; + boolean_t token; /* true == token object, false == session */ +} KMF_PKCS11_PARAMS; + +typedef struct { + KMF_KEYSTORE_TYPE kstype; + char *certLabel; + char *issuer; + char *subject; + char *idstr; + KMF_BIGINT *serial; + KMF_CERT_VALIDITY find_cert_validity; + + union { + KMF_NSS_PARAMS nss_opts; + KMF_OPENSSL_PARAMS openssl_opts; + KMF_PKCS11_PARAMS pkcs11_opts; + } ks_opt_u; +} KMF_FINDCERT_PARAMS, KMF_DELETECERT_PARAMS; + +typedef struct { + KMF_KEYSTORE_TYPE kstype; + KMF_CREDENTIAL cred; + KMF_KEY_CLASS keyclass; + KMF_KEY_ALG keytype; + KMF_ENCODE_FORMAT format; /* for key */ + char *findLabel; + char *idstr; + union { + KMF_NSS_PARAMS nss_opts; + KMF_OPENSSL_PARAMS openssl_opts; + KMF_PKCS11_PARAMS pkcs11_opts; + } ks_opt_u; +} KMF_FINDKEY_PARAMS; + +typedef struct { + KMF_KEYSTORE_TYPE kstype; + KMF_KEY_ALG keytype; + uint32_t keylength; + char *keylabel; + KMF_CREDENTIAL cred; + KMF_BIGINT rsa_exponent; + union { + KMF_NSS_PARAMS nss_opts; + KMF_OPENSSL_PARAMS openssl_opts; + }ks_opt_u; +} KMF_CREATEKEYPAIR_PARAMS; + + +typedef struct { + KMF_KEYSTORE_TYPE kstype; + KMF_CREDENTIAL cred; + KMF_ENCODE_FORMAT format; /* for key */ + char *certLabel; + KMF_ALGORITHM_INDEX algid; + union { + KMF_NSS_PARAMS nss_opts; + KMF_OPENSSL_PARAMS openssl_opts; + }ks_opt_u; +} KMF_CRYPTOWITHCERT_PARAMS; + +typedef struct { + char *crl_name; +} KMF_CHECKCRLDATE_PARAMS; + +#define nssparms ks_opt_u.nss_opts +#define sslparms ks_opt_u.openssl_opts +#define pkcs11parms ks_opt_u.pkcs11_opts + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/libkmf/include/rdn_parser.h b/usr/src/lib/libkmf/include/rdn_parser.h index 80c7e61d93..22eecda324 100644 --- a/usr/src/lib/libkmf/include/rdn_parser.h +++ b/usr/src/lib/libkmf/include/rdn_parser.h @@ -98,8 +98,6 @@ struct NameToKind { ((c) == '?')) -KMF_RETURN ParseDistinguishedName(char *, int, KMF_X509_NAME *); - #ifdef __cplusplus } #endif diff --git a/usr/src/lib/libkmf/libkmf/common/algoid.c b/usr/src/lib/libkmf/libkmf/common/algoid.c index d78541d1f0..f33634f007 100644 --- a/usr/src/lib/libkmf/libkmf/common/algoid.c +++ b/usr/src/lib/libkmf/libkmf/common/algoid.c @@ -36,7 +36,7 @@ static KMF_OID_ID ALGOID_ID_Table[] = { #define NUM_ALGOIDS ((sizeof (ALGOID_ID_Table))/(sizeof (ALGOID_ID_Table[0]))) /* - * Name: X509_AlgIdToAlgorithmOid + * Name: x509_algid_to_algoid * * Description: * This function maps the specified AlgID to the corresponding @@ -50,7 +50,7 @@ static KMF_OID_ID ALGOID_ID_Table[] = { * */ KMF_OID * -X509_AlgIdToAlgorithmOid(KMF_ALGORITHM_INDEX alg_int) +x509_algid_to_algoid(KMF_ALGORITHM_INDEX alg_int) { int i; @@ -70,7 +70,7 @@ X509_AlgIdToAlgorithmOid(KMF_ALGORITHM_INDEX alg_int) } /* - * Name: X509_AlgorithmOidToAlgId + * Name: x509_algoid_to_algid * * Description: * This function maps the specified Algorithm OID to the corresponding @@ -83,13 +83,11 @@ X509_AlgIdToAlgorithmOid(KMF_ALGORITHM_INDEX alg_int) * Algorithm ID and KMF_ALGID_NONE in case of failures. */ KMF_ALGORITHM_INDEX -X509_AlgorithmOidToAlgId(KMF_OID * Oid) +x509_algoid_to_algid(KMF_OID * Oid) { int i; - if ((Oid == NULL) || - (Oid->Data == NULL) || - (Oid->Length == 0)) { + if ((Oid == NULL) || (Oid->Data == NULL) || (Oid->Length == 0)) { return (KMF_ALGID_NONE); } diff --git a/usr/src/lib/libkmf/libkmf/common/algorithm.c b/usr/src/lib/libkmf/libkmf/common/algorithm.c index 23c303d63b..d0ed3912a3 100644 --- a/usr/src/lib/libkmf/libkmf/common/algorithm.c +++ b/usr/src/lib/libkmf/libkmf/common/algorithm.c @@ -101,7 +101,7 @@ SUP(CKM_SHA_1, KMF_ALGID_SHA1, KMF_ALGCLASS_DIGEST, KMF_ALGMODE_NONE, #define PKCS_ALGORITHM_NOT_FOUND ((uint32_t)(~0)) /* - * Name: PKCS_GetAlgorithmMap + * Name: pkcs_get_alg_map * * Description: * Searches the _PKCS2KMFMap table for a matching set of alg. @@ -118,14 +118,14 @@ SUP(CKM_SHA_1, KMF_ALGID_SHA1, KMF_ALGCLASS_DIGEST, KMF_ALGMODE_NONE, * Ptr->keylength will equal PKCS11CONVERT_NOT_FOUND if no match is found. */ PKCS_ALGORITHM_MAP * -PKCS_GetAlgorithmMap(KMF_ALGCLASS algType, uint32_t algID, uint32_t mode) +pkcs_get_alg_map(KMF_ALGCLASS algType, uint32_t algID, uint32_t mode) { uint32_t i = 0; for (i = 0; i < _PKCS2KMFMapCount; i++) { if ((_PKCS2KMFMap[i].context_type == algType) && - (_PKCS2KMFMap[i].algorithm == algID) && - (_PKCS2KMFMap[i].enc_mode == mode)) { + (_PKCS2KMFMap[i].algorithm == algID) && + (_PKCS2KMFMap[i].enc_mode == mode)) { return ((PKCS_ALGORITHM_MAP *)&(_PKCS2KMFMap[i])); } } @@ -134,12 +134,12 @@ PKCS_GetAlgorithmMap(KMF_ALGCLASS algType, uint32_t algID, uint32_t mode) } KMF_BOOL -PKCS_ConvertAlgorithmId2PKCSKeyType(KMF_ALGORITHM_INDEX AlgId, +pkcs_algid_to_keytype(KMF_ALGORITHM_INDEX AlgId, CK_KEY_TYPE *pckKeyType) { uint32_t uIndex; - uint32_t uMapSize = sizeof (_PKCS2KMFKeyTypeMap) / - sizeof (PKCS_KEY_TYPE_MAP); + uint32_t uMapSize = + sizeof (_PKCS2KMFKeyTypeMap) / sizeof (PKCS_KEY_TYPE_MAP); for (uIndex = 0; uIndex < uMapSize; uIndex++) { if (_PKCS2KMFKeyTypeMap[uIndex].kmfAlgorithmId == AlgId) { diff --git a/usr/src/lib/libkmf/libkmf/common/certgetsetop.c b/usr/src/lib/libkmf/libkmf/common/certgetsetop.c index d3ffb0dac7..35dad63b69 100644 --- a/usr/src/lib/libkmf/libkmf/common/certgetsetop.c +++ b/usr/src/lib/libkmf/libkmf/common/certgetsetop.c @@ -88,10 +88,10 @@ copy_extension_data(KMF_X509_EXTENSION *dstext, goto cleanup; } (void) memset(dstext->value.tagAndValue, 0, - sizeof (KMF_X509EXT_TAGandVALUE)); + sizeof (KMF_X509EXT_TAGandVALUE)); ret = copy_data(&dstext->value.tagAndValue->value, - &srcext->value.tagAndValue->value); + &srcext->value.tagAndValue->value); if (ret != KMF_OK) goto cleanup; @@ -100,13 +100,13 @@ copy_extension_data(KMF_X509_EXTENSION *dstext, cleanup: if (ret != KMF_OK) { if (dstext->extnId.Data != NULL) - KMF_FreeData(&dstext->extnId); + kmf_free_data(&dstext->extnId); if (dstext->BERvalue.Data != NULL) - KMF_FreeData(&dstext->BERvalue); + kmf_free_data(&dstext->BERvalue); if (dstext->value.tagAndValue->value.Data == NULL) - KMF_FreeData(&dstext->value.tagAndValue->value); + kmf_free_data(&dstext->value.tagAndValue->value); } return (ret); @@ -124,7 +124,7 @@ cleanup: * parsing and memory allocation errors are also possible. */ KMF_RETURN -KMF_GetCertExtensionData(const KMF_DATA *certdata, +kmf_get_cert_extn(const KMF_DATA *certdata, KMF_OID *extoid, KMF_X509_EXTENSION *extdata) { KMF_RETURN ret = KMF_OK; @@ -156,7 +156,7 @@ KMF_GetCertExtensionData(const KMF_DATA *certdata, ret = KMF_ERR_EXTENSION_NOT_FOUND; if (cert != NULL) { - KMF_FreeSignedCert(cert); + kmf_free_signed_cert(cert); free(cert); } @@ -164,10 +164,9 @@ KMF_GetCertExtensionData(const KMF_DATA *certdata, } /* - * Given a block of DER encoded X.509 certificate data, - * search the extensions and return the OIDs for all - * extensions marked "critical". - * + * Given a block of DER encoded X.509 certificate data and + * a "crit/non-crit/all" flag, search the extensions and + * return the OIDs for critical, non-critical or all extensions. * * RETURNS: * KMF_OK - if extension found and copied OK. @@ -178,7 +177,7 @@ KMF_GetCertExtensionData(const KMF_DATA *certdata, * NumOIDs - number of critical extensions found. */ KMF_RETURN -KMF_GetCertCriticalExtensions(const KMF_DATA *certdata, +kmf_get_cert_extns(const KMF_DATA *certdata, KMF_FLAG_CERT_EXTN flag, KMF_X509_EXTENSION **extlist, int *nextns) { KMF_RETURN ret = KMF_OK; @@ -189,71 +188,7 @@ KMF_GetCertCriticalExtensions(const KMF_DATA *certdata, if (certdata == NULL || extlist == NULL || nextns == NULL) return (KMF_ERR_BAD_PARAMETER); - *nextns = 0; - *extlist = elist = NULL; - ret = DerDecodeSignedCertificate(certdata, &cert); - if (ret != KMF_OK) - return (ret); - - if (cert->certificate.extensions.numberOfExtensions == 0) - return (KMF_ERR_EXTENSION_NOT_FOUND); - - for (i = 0; i < cert->certificate.extensions.numberOfExtensions; - i++) { - eptr = &cert->certificate.extensions.extensions[i]; - if (eptr->critical != 0) { - (*nextns)++; - elist = realloc(elist, sizeof (KMF_X509_EXTENSION) * - (*nextns)); - if (elist == NULL) { - ret = KMF_ERR_MEMORY; - goto end; - } - ret = copy_extension_data(&elist[(*nextns) - 1], - eptr); - if (ret != KMF_OK) - goto end; - } - } -end: - KMF_FreeSignedCert(cert); - free(cert); - if (ret != KMF_OK) { - if (elist != NULL) { - free(elist); - elist = NULL; - } - *nextns = 0; - } - *extlist = elist; - - return (ret); -} - -/* - * Given a block of DER encoded X.509 certificate data, - * search the extensions and return the OIDs for all - * extensions NOT marked "critical". - * - * - * RETURNS: - * KMF_OK - if extension found and copied OK. - * parsing and memory allocation errors are also possible. - * - * OIDlist - array of KMF_OID records, allocated - * by this function. - * NumOIDs - number of critical extensions found. - */ -KMF_RETURN -KMF_GetCertNonCriticalExtensions(const KMF_DATA *certdata, - KMF_X509_EXTENSION **extlist, int *nextns) -{ - KMF_RETURN ret = KMF_OK; - KMF_X509_CERTIFICATE *cert; - KMF_X509_EXTENSION *eptr, *elist; - int i; - - if (certdata == NULL || extlist == NULL || nextns == NULL) + if (flag < KMF_ALL_EXTNS || flag > KMF_NONCRITICAL_EXTNS) return (KMF_ERR_BAD_PARAMETER); *nextns = 0; @@ -268,22 +203,27 @@ KMF_GetCertNonCriticalExtensions(const KMF_DATA *certdata, for (i = 0; i < cert->certificate.extensions.numberOfExtensions; i++) { eptr = &cert->certificate.extensions.extensions[i]; - if (eptr->critical == 0) { - (*nextns)++; - elist = realloc(elist, sizeof (KMF_X509_EXTENSION) * - (*nextns)); - if (elist == NULL) { - ret = KMF_ERR_MEMORY; - goto end; - } - ret = copy_extension_data(&elist[(*nextns) - 1], - eptr); - if (ret != KMF_OK) - goto end; + + if (flag == KMF_CRITICAL_EXTNS && eptr->critical == 0) + continue; + else if (flag == KMF_NONCRITICAL_EXTNS && eptr->critical != 0) + continue; + + (*nextns)++; + elist = realloc(elist, sizeof (KMF_X509_EXTENSION) * + (*nextns)); + if (elist == NULL) { + ret = KMF_ERR_MEMORY; + goto end; } + + ret = copy_extension_data(&elist[(*nextns) - 1], eptr); + if (ret != KMF_OK) + goto end; } + end: - KMF_FreeSignedCert(cert); + kmf_free_signed_cert(cert); free(cert); if (ret != KMF_OK) { if (elist != NULL) { @@ -292,8 +232,16 @@ end: } *nextns = 0; } - *extlist = elist; + /* + * If the flag is not all, then it is possible that we did not find + * any critical or non_critical extensions. When that happened, + * return KMF_ERR_EXTENSION_NOT_FOUND. + */ + if (flag != KMF_ALL_EXTNS && ret == KMF_OK && *nextns == 0) + ret = KMF_ERR_EXTENSION_NOT_FOUND; + + *extlist = elist; return (ret); } @@ -309,7 +257,7 @@ end: * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. */ KMF_RETURN -KMF_GetCertKeyUsageExt(const KMF_DATA *certdata, +kmf_get_cert_ku(const KMF_DATA *certdata, KMF_X509EXT_KEY_USAGE *keyusage) { KMF_RETURN ret = KMF_OK; @@ -322,8 +270,7 @@ KMF_GetCertKeyUsageExt(const KMF_DATA *certdata, /* * Check standard KeyUsage bits */ - ret = KMF_GetCertExtensionData(certdata, - (KMF_OID *)&KMFOID_KeyUsage, &extn); + ret = kmf_get_cert_extn(certdata, (KMF_OID *)&KMFOID_KeyUsage, &extn); if (ret != KMF_OK) { goto end; @@ -331,13 +278,12 @@ KMF_GetCertKeyUsageExt(const KMF_DATA *certdata, keyusage->critical = (extn.critical != 0); if (extn.value.tagAndValue->value.Length > 1) { keyusage->KeyUsageBits = - extn.value.tagAndValue->value.Data[1] << 8; + extn.value.tagAndValue->value.Data[1] << 8; } else { - keyusage->KeyUsageBits = - extn.value.tagAndValue->value.Data[0]; + keyusage->KeyUsageBits = extn.value.tagAndValue->value.Data[0]; } end: - KMF_FreeExtension(&extn); + kmf_free_extn(&extn); return (ret); } @@ -380,8 +326,7 @@ parse_eku_data(const KMF_DATA *asn1data, KMF_X509EXT_EKU *ekuptr) /* * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation */ - if (kmfber_first_element(asn1, &size, &end) != - BER_OBJECT_IDENTIFIER) { + if (kmfber_first_element(asn1, &size, &end) != BER_OBJECT_IDENTIFIER) { ret = KMF_ERR_BAD_CERT_FORMAT; goto end; } @@ -391,7 +336,7 @@ parse_eku_data(const KMF_DATA *asn1data, KMF_X509EXT_EKU *ekuptr) * the array. */ while (kmfber_next_element(asn1, &size, end) == - BER_OBJECT_IDENTIFIER) { + BER_OBJECT_IDENTIFIER) { /* Skip over the CONSTRUCTED SET tag */ if (kmfber_scanf(asn1, "D", &oid) == KMFBER_DEFAULT) { @@ -400,7 +345,7 @@ parse_eku_data(const KMF_DATA *asn1data, KMF_X509EXT_EKU *ekuptr) } ekuptr->nEKUs++; ekuptr->keyPurposeIdList = realloc(ekuptr->keyPurposeIdList, - ekuptr->nEKUs * sizeof (KMF_OID)); + ekuptr->nEKUs * sizeof (KMF_OID)); if (ekuptr->keyPurposeIdList == NULL) { ret = KMF_ERR_MEMORY; goto end; @@ -424,7 +369,7 @@ end: } KMF_RETURN -KMF_GetCertEKU(const KMF_DATA *certdata, +kmf_get_cert_eku(const KMF_DATA *certdata, KMF_X509EXT_EKU *ekuptr) { KMF_RETURN ret = KMF_OK; @@ -439,8 +384,8 @@ KMF_GetCertEKU(const KMF_DATA *certdata, ekuptr->keyPurposeIdList = NULL; ekuptr->critical = 0; - ret = KMF_GetCertExtensionData(certdata, - (KMF_OID *)&KMFOID_ExtendedKeyUsage, &extn); + ret = kmf_get_cert_extn(certdata, + (KMF_OID *)&KMFOID_ExtendedKeyUsage, &extn); if (ret != KMF_OK) { goto end; @@ -449,7 +394,7 @@ KMF_GetCertEKU(const KMF_DATA *certdata, ret = parse_eku_data(&extn.BERvalue, ekuptr); end: - KMF_FreeExtension(&extn); + kmf_free_extn(&extn); return (ret); } @@ -466,7 +411,7 @@ end: * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. */ KMF_RETURN -KMF_GetCertBasicConstraintExt(const KMF_DATA *certdata, +kmf_get_cert_basic_constraint(const KMF_DATA *certdata, KMF_BOOL *critical, KMF_X509EXT_BASICCONSTRAINTS *constraint) { KMF_RETURN ret = KMF_OK; @@ -481,8 +426,8 @@ KMF_GetCertBasicConstraintExt(const KMF_DATA *certdata, return (KMF_ERR_BAD_PARAMETER); (void) memset(&extn, 0, sizeof (KMF_X509_EXTENSION)); - ret = KMF_GetCertExtensionData(certdata, - (KMF_OID *)&KMFOID_BasicConstraints, &extn); + ret = kmf_get_cert_extn(certdata, + (KMF_OID *)&KMFOID_BasicConstraints, &extn); if (ret != KMF_OK) { goto end; @@ -507,14 +452,14 @@ KMF_GetCertBasicConstraintExt(const KMF_DATA *certdata, tag = kmfber_next_element(asn1, &size, end); if (tag == BER_INTEGER) { if (kmfber_scanf(asn1, "i", - &constraint->pathLenConstraint) == KMFBER_DEFAULT) { + &constraint->pathLenConstraint) == KMFBER_DEFAULT) { ret = KMF_ERR_BAD_CERT_FORMAT; goto end; } constraint->pathLenConstraintPresent = KMF_TRUE; } end: - KMF_FreeExtension(&extn); + kmf_free_extn(&extn); if (asn1 != NULL) kmfber_free(asn1, 1); @@ -554,13 +499,13 @@ get_pqinfo(BerElement *asn1) * so the ber/der code knows when to stop looking. */ if ((tag = kmfber_first_element(asn1, &size, &end)) != - BER_CONSTRUCTED_SEQUENCE) { + BER_CONSTRUCTED_SEQUENCE) { ret = KMF_ERR_BAD_CERT_FORMAT; goto end; } /* We found a sequence, loop until done */ while ((tag = kmfber_next_element(asn1, &size, end)) == - BER_CONSTRUCTED_SEQUENCE) { + BER_CONSTRUCTED_SEQUENCE) { /* Skip over the CONSTRUCTED SET tag */ if (kmfber_scanf(asn1, "T", &tag) == KMFBER_DEFAULT) { @@ -576,12 +521,12 @@ get_pqinfo(BerElement *asn1) goto end; } (void) memset((void *)pqinfo, 0, - sizeof (KMF_X509EXT_POLICYQUALIFIERINFO)); + sizeof (KMF_X509EXT_POLICYQUALIFIERINFO)); /* * Read the PolicyQualifier OID */ if (kmfber_scanf(asn1, "D", - &pqinfo->policyQualifierId) == KMFBER_DEFAULT) { + &pqinfo->policyQualifierId) == KMFBER_DEFAULT) { ret = KMF_ERR_BAD_CERT_FORMAT; goto end; } @@ -590,13 +535,13 @@ get_pqinfo(BerElement *asn1) * sort of data comes next. */ if (IsEqualOid(&pqinfo->policyQualifierId, - (KMF_OID *)&KMFOID_PKIX_PQ_CPSuri)) { + (KMF_OID *)&KMFOID_PKIX_PQ_CPSuri)) { /* * CPS uri must be an IA5STRING */ if (kmfber_scanf(asn1, "tl", &tag, &size) == - KMFBER_DEFAULT || tag != BER_IA5STRING || - size == 0) { + KMFBER_DEFAULT || tag != BER_IA5STRING || + size == 0) { ret = KMF_ERR_BAD_CERT_FORMAT; goto end; } @@ -605,15 +550,15 @@ get_pqinfo(BerElement *asn1) goto end; } if (kmfber_scanf(asn1, "s", pqinfo->value.Data, - &pqinfo->value.Length) == KMFBER_DEFAULT) { + &pqinfo->value.Length) == KMFBER_DEFAULT) { ret = KMF_ERR_BAD_CERT_FORMAT; goto end; } } else if (IsEqualOid(&pqinfo->policyQualifierId, - (KMF_OID *)&KMFOID_PKIX_PQ_Unotice)) { + (KMF_OID *)&KMFOID_PKIX_PQ_Unotice)) { if (kmfber_scanf(asn1, "tl", &tag, &size) == - KMFBER_DEFAULT || - tag != BER_CONSTRUCTED_SEQUENCE) { + KMFBER_DEFAULT || + tag != BER_CONSTRUCTED_SEQUENCE) { ret = KMF_ERR_BAD_CERT_FORMAT; goto end; } @@ -627,7 +572,7 @@ get_pqinfo(BerElement *asn1) goto end; } if (kmfber_scanf(asn1, "s", pqinfo->value.Data, - &pqinfo->value.Length) == KMFBER_DEFAULT) { + &pqinfo->value.Length) == KMFBER_DEFAULT) { ret = KMF_ERR_BAD_CERT_FORMAT; goto end; } @@ -639,8 +584,8 @@ get_pqinfo(BerElement *asn1) end: if (ret != KMF_OK) { if (pqinfo != NULL) { - KMF_FreeData(&pqinfo->value); - KMF_FreeData(&pqinfo->policyQualifierId); + kmf_free_data(&pqinfo->value); + kmf_free_data(&pqinfo->policyQualifierId); free(pqinfo); pqinfo = NULL; } @@ -661,7 +606,7 @@ end: * parsing and memory allocation errors are also possible. */ KMF_RETURN -KMF_GetCertPoliciesExt(const KMF_DATA *certdata, +kmf_get_cert_policies(const KMF_DATA *certdata, KMF_BOOL *critical, KMF_X509EXT_CERT_POLICIES *extptr) { KMF_RETURN ret = KMF_OK; @@ -678,8 +623,8 @@ KMF_GetCertPoliciesExt(const KMF_DATA *certdata, return (KMF_ERR_BAD_PARAMETER); (void) memset(&extn, 0, sizeof (extn)); - ret = KMF_GetCertExtensionData(certdata, - (KMF_OID *)&KMFOID_CertificatePolicies, &extn); + ret = kmf_get_cert_extn(certdata, + (KMF_OID *)&KMFOID_CertificatePolicies, &extn); if (ret != KMF_OK) { goto end; @@ -704,7 +649,7 @@ KMF_GetCertPoliciesExt(const KMF_DATA *certdata, * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation */ if ((tag = kmfber_first_element(asn1, &size, &end)) != - BER_CONSTRUCTED_SEQUENCE) { + BER_CONSTRUCTED_SEQUENCE) { ret = KMF_ERR_BAD_CERT_FORMAT; goto end; } @@ -721,7 +666,7 @@ KMF_GetCertPoliciesExt(const KMF_DATA *certdata, * Loop over the SEQUENCES of PolicyInfo */ while ((tag = kmfber_next_element(asn1, &size, end)) == - BER_CONSTRUCTED_SEQUENCE) { + BER_CONSTRUCTED_SEQUENCE) { /* Skip over the CONSTRUCTED SET tag */ if (kmfber_scanf(asn1, "T", &tag) == KMFBER_DEFAULT) { @@ -735,12 +680,12 @@ KMF_GetCertPoliciesExt(const KMF_DATA *certdata, goto end; } (void) memset((void *)pinfo, 0, - sizeof (KMF_X509EXT_POLICYINFO)); + sizeof (KMF_X509EXT_POLICYINFO)); /* * Decode the PolicyInformation SEQUENCE */ if ((tag = kmfber_scanf(asn1, "D", - &pinfo->policyIdentifier)) == KMFBER_DEFAULT) { + &pinfo->policyIdentifier)) == KMFBER_DEFAULT) { ret = KMF_ERR_BAD_CERT_FORMAT; goto end; } @@ -753,23 +698,22 @@ KMF_GetCertPoliciesExt(const KMF_DATA *certdata, pinfo->policyQualifiers.numberOfPolicyQualifiers; cnt++; pinfo->policyQualifiers.policyQualifier = realloc( - pinfo->policyQualifiers.policyQualifier, - cnt * sizeof (KMF_X509EXT_POLICYQUALIFIERINFO)); + pinfo->policyQualifiers.policyQualifier, + cnt * sizeof (KMF_X509EXT_POLICYQUALIFIERINFO)); if (pinfo->policyQualifiers.policyQualifier == NULL) { ret = KMF_ERR_MEMORY; goto end; } - pinfo->policyQualifiers.numberOfPolicyQualifiers = - cnt; + pinfo->policyQualifiers.numberOfPolicyQualifiers = cnt; pinfo->policyQualifiers.policyQualifier[cnt-1] = - *pqinfo; + *pqinfo; free(pqinfo); } extptr->numberOfPolicyInfo++; extptr->policyInfo = realloc(extptr->policyInfo, - extptr->numberOfPolicyInfo * - sizeof (KMF_X509EXT_POLICYINFO)); + extptr->numberOfPolicyInfo * + sizeof (KMF_X509EXT_POLICYINFO)); if (extptr->policyInfo == NULL) { ret = KMF_ERR_MEMORY; goto end; @@ -780,7 +724,7 @@ KMF_GetCertPoliciesExt(const KMF_DATA *certdata, end: - KMF_FreeExtension(&extn); + kmf_free_extn(&extn); if (asn1 != NULL) kmfber_free(asn1, 1); return (ret); @@ -798,7 +742,7 @@ end: * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. */ KMF_RETURN -KMF_GetCertAuthInfoAccessExt(const KMF_DATA *certdata, +kmf_get_cert_auth_info_access(const KMF_DATA *certdata, KMF_X509EXT_AUTHINFOACCESS *aia) { KMF_RETURN ret = KMF_OK; @@ -815,7 +759,7 @@ KMF_GetCertAuthInfoAccessExt(const KMF_DATA *certdata, } (void) memset(&extn, 0, sizeof (KMF_X509_EXTENSION)); - ret = KMF_GetCertExtensionData(certdata, + ret = kmf_get_cert_extn(certdata, (KMF_OID *)&KMFOID_AuthorityInfoAccess, &extn); if (ret != KMF_OK) { @@ -908,12 +852,12 @@ KMF_GetCertAuthInfoAccessExt(const KMF_DATA *certdata, if (kmfber_scanf(asn1, "s", access_info->AccessLocation.Data, &access_info->AccessLocation.Length) == - KMFBER_DEFAULT) { + KMFBER_DEFAULT) { ret = KMF_ERR_BAD_CERT_FORMAT; goto end; } } else if (IsEqualOid(&access_info->AccessMethod, - (KMF_OID *)&KMFOID_PkixAdCaIssuers)) { + (KMF_OID *)&KMFOID_PkixAdCaIssuers)) { /* will be supported later with PKIX */ free(access_info); access_info = NULL; @@ -940,7 +884,7 @@ KMF_GetCertAuthInfoAccessExt(const KMF_DATA *certdata, } end: - KMF_FreeExtension(&extn); + kmf_free_extn(&extn); if (access_info != NULL) free(access_info); if (asn1 != NULL) @@ -1040,11 +984,11 @@ parse_dp_name(char *dp_der_code, int dp_der_size, KMF_CRL_DIST_POINT *dp) } fullname->namelist[fullname->number - 1].choice = - GENNAME_URI; + GENNAME_URI; fullname->namelist[fullname->number - 1].name.Length = - size; + size; fullname->namelist[fullname->number - 1].name.Data = - (unsigned char *)url; + (unsigned char *)url; /* next */ tag = kmfber_next_element(asn1, &size, end); @@ -1079,7 +1023,7 @@ out: * extension data, and returns it in the KMF_X509EXT_CRLDISTPOINTS record. */ KMF_RETURN -KMF_GetCertCRLDistributionPointsExt(const KMF_DATA *certdata, +kmf_get_cert_crl_dist_pts(const KMF_DATA *certdata, KMF_X509EXT_CRLDISTPOINTS *crl_dps) { KMF_RETURN ret = KMF_OK; @@ -1098,7 +1042,7 @@ KMF_GetCertCRLDistributionPointsExt(const KMF_DATA *certdata, /* Get the ASN.1 data for this extension. */ (void) memset(&extn, 0, sizeof (KMF_X509_EXTENSION)); - ret = KMF_GetCertExtensionData(certdata, + ret = kmf_get_cert_extn(certdata, (KMF_OID *)&KMFOID_CrlDistributionPoints, &extn); if (ret != KMF_OK) { return (ret); @@ -1277,7 +1221,7 @@ KMF_GetCertCRLDistributionPointsExt(const KMF_DATA *certdata, } out: - KMF_FreeExtension(&extn); + kmf_free_extn(&extn); if (asn1 != NULL) kmfber_free(asn1, 1); @@ -1301,15 +1245,14 @@ KMF_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, { KMF_PLUGIN *plugin; KMF_RETURN (*getPrintableFn)(void *, const KMF_DATA *, - KMF_PRINTABLE_ITEM, char *); + KMF_PRINTABLE_ITEM, char *); KMF_RETURN ret; CLEAR_ERROR(handle, ret); if (ret != KMF_OK) return (ret); - if (SignedCert == NULL || - resultStr == NULL) { + if (SignedCert == NULL || resultStr == NULL) { return (KMF_ERR_BAD_PARAMETER); } @@ -1332,7 +1275,7 @@ KMF_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, } KMF_RETURN -KMF_GetCertVersionString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, +kmf_get_cert_version_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, char **result) { KMF_RETURN ret; @@ -1350,7 +1293,7 @@ KMF_GetCertVersionString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_VERSION, - tmpstr); + tmpstr); if (ret == KMF_OK) { *result = tmpstr; @@ -1362,8 +1305,9 @@ KMF_GetCertVersionString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, return (ret); } + KMF_RETURN -KMF_GetCertSubjectNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, +kmf_get_cert_subject_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, char **result) { KMF_RETURN ret; @@ -1381,7 +1325,7 @@ KMF_GetCertSubjectNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_SUBJECT, - tmpstr); + tmpstr); if (ret == KMF_OK) { *result = tmpstr; @@ -1395,7 +1339,7 @@ KMF_GetCertSubjectNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, } KMF_RETURN -KMF_GetCertIssuerNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, +kmf_get_cert_issuer_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, char **result) { KMF_RETURN ret; @@ -1414,7 +1358,7 @@ KMF_GetCertIssuerNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_ISSUER, - tmpstr); + tmpstr); if (ret == KMF_OK) { *result = tmpstr; @@ -1427,7 +1371,7 @@ KMF_GetCertIssuerNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, } KMF_RETURN -KMF_GetCertSerialNumberString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, +kmf_get_cert_serial_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, char **result) { KMF_RETURN ret; @@ -1445,7 +1389,7 @@ KMF_GetCertSerialNumberString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_SERIALNUM, - tmpstr); + tmpstr); if (ret == KMF_OK) { *result = tmpstr; @@ -1458,7 +1402,7 @@ KMF_GetCertSerialNumberString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, } KMF_RETURN -KMF_GetCertStartDateString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, +kmf_get_cert_start_date_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, char **result) { KMF_RETURN ret; @@ -1476,7 +1420,7 @@ KMF_GetCertStartDateString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_NOTBEFORE, - tmpstr); + tmpstr); if (ret == KMF_OK) { *result = tmpstr; @@ -1489,7 +1433,7 @@ KMF_GetCertStartDateString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, } KMF_RETURN -KMF_GetCertEndDateString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, +kmf_get_cert_end_date_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, char **result) { KMF_RETURN ret; @@ -1507,7 +1451,7 @@ KMF_GetCertEndDateString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_NOTAFTER, - tmpstr); + tmpstr); if (ret == KMF_OK) { *result = tmpstr; @@ -1520,7 +1464,7 @@ KMF_GetCertEndDateString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, } KMF_RETURN -KMF_GetCertPubKeyAlgString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, +kmf_get_cert_pubkey_alg_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, char **result) { KMF_RETURN ret; @@ -1538,7 +1482,7 @@ KMF_GetCertPubKeyAlgString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_PUBKEY_ALG, - tmpstr); + tmpstr); if (ret == KMF_OK) { *result = tmpstr; @@ -1551,7 +1495,7 @@ KMF_GetCertPubKeyAlgString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, } KMF_RETURN -KMF_GetCertSignatureAlgString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, +kmf_get_cert_sig_alg_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, char **result) { KMF_RETURN ret; @@ -1569,7 +1513,7 @@ KMF_GetCertSignatureAlgString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_SIGNATURE_ALG, - tmpstr); + tmpstr); if (ret == KMF_OK) { *result = tmpstr; @@ -1582,7 +1526,7 @@ KMF_GetCertSignatureAlgString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, } KMF_RETURN -KMF_GetCertPubKeyDataString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, +kmf_get_cert_pubkey_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, char **result) { KMF_RETURN ret; @@ -1600,7 +1544,7 @@ KMF_GetCertPubKeyDataString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_PUBKEY_DATA, - tmpstr); + tmpstr); if (ret == KMF_OK) { *result = tmpstr; @@ -1613,7 +1557,7 @@ KMF_GetCertPubKeyDataString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, } KMF_RETURN -KMF_GetCertEmailString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, +kmf_get_cert_email_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, char **result) { KMF_RETURN ret; @@ -1630,8 +1574,7 @@ KMF_GetCertEmailString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, return (KMF_ERR_MEMORY); (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); - ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_EMAIL, - tmpstr); + ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_EMAIL, tmpstr); if (ret == KMF_OK) { *result = tmpstr; @@ -1654,7 +1597,7 @@ KMF_GetCertEmailString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, * must be freed by the caller. */ KMF_RETURN -KMF_GetCertExtensionString(KMF_HANDLE_T handle, const KMF_DATA *cert, +kmf_get_cert_extn_str(KMF_HANDLE_T handle, const KMF_DATA *cert, KMF_PRINTABLE_ITEM extension, char **result) { KMF_RETURN ret; @@ -1685,7 +1628,7 @@ KMF_GetCertExtensionString(KMF_HANDLE_T handle, const KMF_DATA *cert, } KMF_RETURN -KMF_GetCertIDData(const KMF_DATA *SignedCert, KMF_DATA *ID) +kmf_get_cert_id_data(const KMF_DATA *SignedCert, KMF_DATA *ID) { KMF_RETURN ret; KMF_X509_CERTIFICATE *cert = NULL; @@ -1699,14 +1642,13 @@ KMF_GetCertIDData(const KMF_DATA *SignedCert, KMF_DATA *ID) ret = GetIDFromSPKI(&cert->certificate.subjectPublicKeyInfo, ID); - KMF_FreeSignedCert(cert); + kmf_free_signed_cert(cert); free(cert); return (ret); } KMF_RETURN -KMF_GetCertIDString(const KMF_DATA *SignedCert, - char **idstr) +kmf_get_cert_id_str(const KMF_DATA *SignedCert, char **idstr) { KMF_RETURN ret; KMF_DATA ID = {NULL, 0}; @@ -1716,9 +1658,9 @@ KMF_GetCertIDString(const KMF_DATA *SignedCert, if (SignedCert == NULL || idstr == NULL) return (KMF_ERR_BAD_PARAMETER); - ret = KMF_GetCertIDData(SignedCert, &ID); + ret = kmf_get_cert_id_data(SignedCert, &ID); if (ret != KMF_OK) { - KMF_FreeData(&ID); + kmf_free_data(&ID); return (ret); } @@ -1726,7 +1668,7 @@ KMF_GetCertIDString(const KMF_DATA *SignedCert, for (i = 0; i < ID.Length; i++) { int len = strlen(tmpstr); (void) snprintf(&tmpstr[len], sizeof (tmpstr) - len, - "%02x", (uchar_t)ID.Data[i]); + "%02x", (uchar_t)ID.Data[i]); if ((i+1) < ID.Length) (void) strcat(tmpstr, ":"); } @@ -1734,17 +1676,18 @@ KMF_GetCertIDString(const KMF_DATA *SignedCert, if ((*idstr) == NULL) ret = KMF_ERR_MEMORY; - KMF_FreeData(&ID); + kmf_free_data(&ID); return (ret); } + /* * This function gets the time_t values of the notbefore and notafter dates * from a der-encoded certificate. */ KMF_RETURN -KMF_GetCertValidity(const KMF_DATA *cert, time_t *not_before, +kmf_get_cert_validity(const KMF_DATA *cert, time_t *not_before, time_t *not_after) { KMF_RETURN rv = KMF_OK; @@ -1796,7 +1739,7 @@ KMF_GetCertValidity(const KMF_DATA *cert, time_t *not_before, out: if (certData != NULL) { - KMF_FreeSignedCert(certData); + kmf_free_signed_cert(certData); free(certData); } @@ -1804,7 +1747,7 @@ out: } KMF_RETURN -KMF_SetCertPubKey(KMF_HANDLE_T handle, +kmf_set_cert_pubkey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *KMFKey, KMF_X509_CERTIFICATE *Cert) { @@ -1825,7 +1768,7 @@ KMF_SetCertPubKey(KMF_HANDLE_T handle, plugin = FindPlugin(handle, KMFKey->kstype); if (plugin != NULL && plugin->funclist->EncodePubkeyData != NULL) { ret = plugin->funclist->EncodePubkeyData(handle, - KMFKey, &KeyData); + KMFKey, &KeyData); } else { return (KMF_ERR_PLUGIN_NOTFOUND); } @@ -1841,7 +1784,7 @@ KMF_SetCertPubKey(KMF_HANDLE_T handle, } KMF_RETURN -KMF_SetCertSubjectName(KMF_X509_CERTIFICATE *CertData, +kmf_set_cert_subject(KMF_X509_CERTIFICATE *CertData, KMF_X509_NAME *subject_name_ptr) { @@ -1880,7 +1823,9 @@ set_key_usage_extension(KMF_X509_EXTENSIONS *extns, extn.critical = critical; extn.format = KMF_X509_DATAFORMAT_ENCODED; - for (i = 7; i <= 15 && !(kubits & (1 << i)); i++); + for (i = 7; i <= 15 && !(kubits & (1 << i)); i++) + /* empty body */ + ; bitlen = 16 - i; @@ -1914,7 +1859,7 @@ out: } KMF_RETURN -KMF_SetCertKeyUsage(KMF_X509_CERTIFICATE *CertData, +kmf_set_cert_ku(KMF_X509_CERTIFICATE *CertData, int critical, uint16_t kubits) { KMF_RETURN ret = KMF_OK; @@ -1922,15 +1867,14 @@ KMF_SetCertKeyUsage(KMF_X509_CERTIFICATE *CertData, if (CertData == NULL) return (KMF_ERR_BAD_PARAMETER); - ret = set_key_usage_extension( - &CertData->certificate.extensions, - critical, kubits); + ret = set_key_usage_extension(&CertData->certificate.extensions, + critical, kubits); return (ret); } KMF_RETURN -KMF_SetCertIssuerName(KMF_X509_CERTIFICATE *CertData, +kmf_set_cert_issuer(KMF_X509_CERTIFICATE *CertData, KMF_X509_NAME *issuer_name_ptr) { @@ -1950,7 +1894,7 @@ KMF_SetCertIssuerName(KMF_X509_CERTIFICATE *CertData, } KMF_RETURN -KMF_SetCertSignatureAlgorithm(KMF_X509_CERTIFICATE *CertData, +kmf_set_cert_sig_alg(KMF_X509_CERTIFICATE *CertData, KMF_ALGORITHM_INDEX sigAlg) { KMF_OID *alg; @@ -1958,7 +1902,7 @@ KMF_SetCertSignatureAlgorithm(KMF_X509_CERTIFICATE *CertData, if (CertData == NULL) return (KMF_ERR_BAD_PARAMETER); - alg = X509_AlgIdToAlgorithmOid(sigAlg); + alg = x509_algid_to_algoid(sigAlg); if (alg != NULL) { (void) copy_data((KMF_DATA *) @@ -1982,7 +1926,7 @@ KMF_SetCertSignatureAlgorithm(KMF_X509_CERTIFICATE *CertData, } KMF_RETURN -KMF_SetCertValidityTimes(KMF_X509_CERTIFICATE *CertData, +kmf_set_cert_validity(KMF_X509_CERTIFICATE *CertData, time_t notBefore, uint32_t delta) { time_t clock; @@ -2003,26 +1947,26 @@ KMF_SetCertValidityTimes(KMF_X509_CERTIFICATE *CertData, /* Build the format in 2 parts so SCCS doesn't get confused */ (void) strftime(szNotBefore, sizeof (szNotBefore), - "%y%m%d%H" "%M00Z", gmt); + "%y%m%d%H" "%M00Z", gmt); CertData->certificate.validity.notBefore.timeType = BER_UTCTIME; CertData->certificate.validity.notBefore.time.Length = - strlen((char *)szNotBefore); + strlen((char *)szNotBefore); CertData->certificate.validity.notBefore.time.Data = - (uchar_t *)strdup(szNotBefore); + (uchar_t *)strdup(szNotBefore); clock += delta; gmt = gmtime(&clock); /* Build the format in 2 parts so SCCS doesn't get confused */ (void) strftime(szNotAfter, sizeof (szNotAfter), - "%y%m%d%H" "%M00Z", gmt); + "%y%m%d%H" "%M00Z", gmt); CertData->certificate.validity.notAfter.timeType = BER_UTCTIME; CertData->certificate.validity.notAfter.time.Length = - strlen((char *)szNotAfter); + strlen((char *)szNotAfter); CertData->certificate.validity.notAfter.time.Data = - (uchar_t *)strdup(szNotAfter); + (uchar_t *)strdup(szNotAfter); return (KMF_OK); } @@ -2069,7 +2013,7 @@ set_bigint(KMF_BIGINT *data, KMF_BIGINT *bigint) } KMF_RETURN -KMF_SetCertSerialNumber(KMF_X509_CERTIFICATE *CertData, +kmf_set_cert_serial(KMF_X509_CERTIFICATE *CertData, KMF_BIGINT *serno) { if (CertData == NULL || serno == NULL || serno->len == 0) @@ -2078,7 +2022,7 @@ KMF_SetCertSerialNumber(KMF_X509_CERTIFICATE *CertData, } KMF_RETURN -KMF_SetCertVersion(KMF_X509_CERTIFICATE *CertData, +kmf_set_cert_version(KMF_X509_CERTIFICATE *CertData, uint32_t version) { if (CertData == NULL) @@ -2090,11 +2034,11 @@ KMF_SetCertVersion(KMF_X509_CERTIFICATE *CertData, if (version != 0 && version != 1 && version != 2) return (KMF_ERR_BAD_PARAMETER); return (set_integer(&CertData->certificate.version, (void *)&version, - sizeof (uint32_t))); + sizeof (uint32_t))); } KMF_RETURN -KMF_SetCertIssuerAltName(KMF_X509_CERTIFICATE *CertData, +kmf_set_cert_issuer_altname(KMF_X509_CERTIFICATE *CertData, int critical, KMF_GENERALNAMECHOICES nametype, char *namedata) @@ -2102,14 +2046,12 @@ KMF_SetCertIssuerAltName(KMF_X509_CERTIFICATE *CertData, if (CertData == NULL || namedata == NULL) return (KMF_ERR_BAD_PARAMETER); - return (KMF_SetAltName( - &CertData->certificate.extensions, - (KMF_OID *)&KMFOID_IssuerAltName, - critical, nametype, namedata)); + return (kmf_set_altname(&CertData->certificate.extensions, + (KMF_OID *)&KMFOID_IssuerAltName, critical, nametype, namedata)); } KMF_RETURN -KMF_SetCertSubjectAltName(KMF_X509_CERTIFICATE *CertData, +kmf_set_cert_subject_altname(KMF_X509_CERTIFICATE *CertData, int critical, KMF_GENERALNAMECHOICES nametype, char *namedata) @@ -2117,13 +2059,12 @@ KMF_SetCertSubjectAltName(KMF_X509_CERTIFICATE *CertData, if (CertData == NULL || namedata == NULL) return (KMF_ERR_BAD_PARAMETER); - return (KMF_SetAltName(&CertData->certificate.extensions, - (KMF_OID *)&KMFOID_SubjectAltName, - critical, nametype, namedata)); + return (kmf_set_altname(&CertData->certificate.extensions, + (KMF_OID *)&KMFOID_SubjectAltName, critical, nametype, namedata)); } KMF_RETURN -KMF_AddCertEKU(KMF_X509_CERTIFICATE *CertData, KMF_OID *ekuOID, +kmf_add_cert_eku(KMF_X509_CERTIFICATE *CertData, KMF_OID *ekuOID, int critical) { KMF_RETURN ret = KMF_OK; @@ -2142,12 +2083,10 @@ KMF_AddCertEKU(KMF_X509_CERTIFICATE *CertData, KMF_OID *ekuOID, (void) memset(&newextn, 0, sizeof (newextn)); foundextn = FindExtn(&CertData->certificate.extensions, - (KMF_OID *)&KMFOID_ExtendedKeyUsage); + (KMF_OID *)&KMFOID_ExtendedKeyUsage); if (foundextn != NULL) { - ret = GetSequenceContents( - (char *)foundextn->BERvalue.Data, - foundextn->BERvalue.Length, - &olddata, &oldsize); + ret = GetSequenceContents((char *)foundextn->BERvalue.Data, + foundextn->BERvalue.Length, &olddata, &oldsize); if (ret != KMF_OK) goto out; @@ -2199,20 +2138,20 @@ KMF_AddCertEKU(KMF_X509_CERTIFICATE *CertData, KMF_OID *ekuOID, foundextn->BERvalue.Length = extdata->bv_len; } else { ret = copy_data(&newextn.extnId, - (KMF_DATA *)&KMFOID_ExtendedKeyUsage); + (KMF_DATA *)&KMFOID_ExtendedKeyUsage); if (ret != KMF_OK) goto out; newextn.critical = critical; newextn.format = KMF_X509_DATAFORMAT_ENCODED; newextn.BERvalue.Data = (uchar_t *)extdata->bv_val; newextn.BERvalue.Length = extdata->bv_len; - ret = KMF_SetCertExtension(CertData, &newextn); + ret = kmf_set_cert_extn(CertData, &newextn); if (ret != KMF_OK) free(newextn.BERvalue.Data); } out: - KMF_FreeEKU(&ekudata); + kmf_free_eku(&ekudata); if (extdata != NULL) free(extdata); @@ -2223,13 +2162,13 @@ out: kmfber_free(asn1, 1); if (ret != KMF_OK) - KMF_FreeData(&newextn.extnId); + kmf_free_data(&newextn.extnId); return (ret); } KMF_RETURN -KMF_SetCertExtension(KMF_X509_CERTIFICATE *CertData, +kmf_set_cert_extn(KMF_X509_CERTIFICATE *CertData, KMF_X509_EXTENSION *extn) { KMF_RETURN ret = KMF_OK; @@ -2246,7 +2185,7 @@ KMF_SetCertExtension(KMF_X509_CERTIFICATE *CertData, } KMF_RETURN -KMF_SetCertBasicConstraintExt(KMF_X509_CERTIFICATE *CertData, +kmf_set_cert_basic_constraint(KMF_X509_CERTIFICATE *CertData, KMF_BOOL critical, KMF_X509EXT_BASICCONSTRAINTS *constraint) { KMF_RETURN ret = KMF_OK; @@ -2280,7 +2219,7 @@ KMF_SetCertBasicConstraintExt(KMF_X509_CERTIFICATE *CertData, if (constraint->pathLenConstraintPresent) { /* Write the pathLenConstraint value */ if (kmfber_printf(asn1, "i", - constraint->pathLenConstraint) == -1) { + constraint->pathLenConstraint) == -1) { ret = KMF_ERR_ENCODING; goto out; } @@ -2300,7 +2239,7 @@ KMF_SetCertBasicConstraintExt(KMF_X509_CERTIFICATE *CertData, extn.BERvalue.Length = extdata->bv_len; free(extdata); - ret = KMF_SetCertExtension(CertData, &extn); + ret = kmf_set_cert_extn(CertData, &extn); if (ret != KMF_OK) { free(extn.BERvalue.Data); } @@ -2311,3 +2250,27 @@ out: return (ret); } + + +/* + * Phase 1 APIs still needed to maintain compat with elfsign. + */ +KMF_RETURN +KMF_GetCertSubjectNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, + char **result) +{ + return (kmf_get_cert_subject_str(handle, SignedCert, result)); +} + +KMF_RETURN +KMF_GetCertIssuerNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, + char **result) +{ + return (kmf_get_cert_issuer_str(handle, SignedCert, result)); +} + +KMF_RETURN +KMF_GetCertIDString(const KMF_DATA *SignedCert, char **idstr) +{ + return (kmf_get_cert_id_str(SignedCert, idstr)); +} diff --git a/usr/src/lib/libkmf/libkmf/common/certop.c b/usr/src/lib/libkmf/libkmf/common/certop.c index 0757b5adcf..b01dfc6204 100644 --- a/usr/src/lib/libkmf/libkmf/common/certop.c +++ b/usr/src/lib/libkmf/libkmf/common/certop.c @@ -44,13 +44,14 @@ #define X509_FORMAT_VERSION 2 static KMF_RETURN -SignCert(KMF_HANDLE_T, const KMF_DATA *, KMF_KEY_HANDLE *, KMF_DATA *); +sign_cert(KMF_HANDLE_T, const KMF_DATA *, KMF_KEY_HANDLE *, KMF_DATA *); static KMF_RETURN -VerifyCertWithKey(KMF_HANDLE_T, KMF_DATA *, const KMF_DATA *); +verify_cert_with_key(KMF_HANDLE_T, KMF_DATA *, const KMF_DATA *); static KMF_RETURN -VerifyCertWithCert(KMF_HANDLE_T, const KMF_DATA *, const KMF_DATA *); +verify_cert_with_cert(KMF_HANDLE_T, const KMF_DATA *, const KMF_DATA *); + static KMF_RETURN get_keyalg_from_cert(KMF_DATA *cert, KMF_KEY_ALG *keyalg) @@ -65,7 +66,7 @@ get_keyalg_from_cert(KMF_DATA *cert, KMF_KEY_ALG *keyalg) return (rv); /* Get the algorithm info from the signer certificate */ - AlgorithmId = X509_AlgorithmOidToAlgId( + AlgorithmId = x509_algoid_to_algid( &SignerCert->signature.algorithmIdentifier.algorithm); switch (AlgorithmId) { @@ -81,67 +82,81 @@ get_keyalg_from_cert(KMF_DATA *cert, KMF_KEY_ALG *keyalg) rv = KMF_ERR_BAD_ALGORITHM; } - KMF_FreeSignedCert(SignerCert); + kmf_free_signed_cert(SignerCert); free(SignerCert); return (rv); } /* - * - * Name: find_private_key_by_cert + * Name: kmf_find_prikey_by_cert * * Description: * This function finds the corresponding private key in keystore - * for a certificate - * - * Parameters: - * handle(input) - opaque handle for KMF session - * params(input) - contains parameters used to find the private key - * SignerCertData(input) - pointer to a KMF_DATA structure containing a - * signer certificate - * key(output) - contains the found private key handle - * - * Returns: - * A KMF_RETURN value indicating success or specifying a particular - * error condition. - * The value KMF_OK indicates success. All other values represent - * an error condition. - * + * for a certificate */ -static KMF_RETURN -find_private_key_by_cert(KMF_HANDLE_T handle, - KMF_CRYPTOWITHCERT_PARAMS *params, - KMF_DATA *SignerCertData, - KMF_KEY_HANDLE *key) +KMF_RETURN +kmf_find_prikey_by_cert(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) { - - KMF_RETURN ret; - KMF_KEY_ALG keytype; KMF_PLUGIN *plugin; + KMF_RETURN ret = KMF_OK; + KMF_KEYSTORE_TYPE kstype; + KMF_KEY_ALG keyalg; + KMF_KEY_HANDLE *key = NULL; + KMF_DATA *cert = NULL; + + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, + {KMF_KEY_HANDLE_ATTR, TRUE, sizeof (KMF_KEY_HANDLE), + sizeof (KMF_KEY_HANDLE)} + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); + + CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); + if (ret != KMF_OK) + return (ret); - if (handle == NULL || params == NULL || - SignerCertData == NULL || key == NULL) + /* + * First, get the key algorithm info from the certificate and saves it + * in the returned key handle. + */ + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL) return (KMF_ERR_BAD_PARAMETER); - (void) memset(key, 0, sizeof (KMF_KEY_HANDLE)); - ret = get_keyalg_from_cert(SignerCertData, &keytype); + ret = get_keyalg_from_cert(cert, &keyalg); if (ret != KMF_OK) return (ret); - /* Find the private key from the keystore */ - plugin = FindPlugin(handle, params->kstype); + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (key == NULL) + return (KMF_ERR_BAD_PARAMETER); + key->keyalg = keyalg; - if (plugin != NULL && plugin->funclist->GetPrikeyByCert != NULL) { - CLEAR_ERROR(handle, ret); - return (plugin->funclist->GetPrikeyByCert(handle, - params, SignerCertData, key, keytype)); - } else { + /* Call the plugin to do the work. */ + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, + &kstype, NULL); + if (ret != KMF_OK) + return (ret); + + plugin = FindPlugin(handle, kstype); + if (plugin == NULL || plugin->funclist->FindPrikeyByCert == NULL) return (KMF_ERR_PLUGIN_NOTFOUND); - } + return (plugin->funclist->FindPrikeyByCert(handle, numattr, attrlist)); } -static KMF_RETURN + +KMF_RETURN check_key_usage(void *handle, const KMF_DATA *cert, const KMF_KU_PURPOSE purpose) @@ -157,7 +172,7 @@ check_key_usage(void *handle, (void) memset(&constraint, 0, sizeof (KMF_X509EXT_BASICCONSTRAINTS)); (void) memset(&keyusage, 0, sizeof (KMF_X509EXT_KEY_USAGE)); - ret = KMF_GetCertKeyUsageExt(cert, &keyusage); + ret = kmf_get_cert_ku(cert, &keyusage); if (ret != KMF_OK) /* * If absent or error, the cert is assumed to be invalid @@ -180,7 +195,7 @@ check_key_usage(void *handle, * contain public keys used to validate digital * signatures on certificates. */ - ret = KMF_GetCertBasicConstraintExt(cert, &critical, + ret = kmf_get_cert_basic_constraint(cert, &critical, &constraint); if ((ret != KMF_ERR_EXTENSION_NOT_FOUND) && (ret != KMF_OK)) { @@ -221,41 +236,47 @@ check_key_usage(void *handle, } KMF_RETURN -KMF_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *target, - KMF_X509_DER_CERT *kmf_cert, - uint32_t *num_certs) +kmf_find_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_PLUGIN *plugin; - KMF_RETURN rv = KMF_OK; - - - CLEAR_ERROR(handle, rv); - if (rv != KMF_OK) - return (rv); + KMF_RETURN ret = KMF_OK; + KMF_KEYSTORE_TYPE kstype; + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_COUNT_ATTR, FALSE, sizeof (uint32_t), sizeof (uint32_t)} + }; + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); - if (target == NULL || num_certs == NULL) - return (KMF_ERR_BAD_PARAMETER); /* ILLEGAL ARGS ERROR */ + CLEAR_ERROR(handle, ret); - if ((target->find_cert_validity < KMF_ALL_CERTS) || - (target->find_cert_validity > KMF_EXPIRED_CERTS)) - return (KMF_ERR_BAD_PARAMETER); + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); + if (ret != KMF_OK) + return (ret); - plugin = FindPlugin(handle, target->kstype); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, + &kstype, NULL); + if (ret != KMF_OK) + return (ret); - if (plugin != NULL && plugin->funclist->FindCert != NULL) { - return (plugin->funclist->FindCert(handle, target, - kmf_cert, num_certs)); - } + plugin = FindPlugin(handle, kstype); + if (plugin == NULL || plugin->funclist->FindCert == NULL) + return (KMF_ERR_PLUGIN_NOTFOUND); - return (KMF_ERR_PLUGIN_NOTFOUND); + return (plugin->funclist->FindCert(handle, numattr, attrlist)); } #define NODATA(d) (d.Data == NULL || d.Length == NULL) KMF_RETURN -KMF_EncodeCertRecord(KMF_X509_CERTIFICATE *CertData, KMF_DATA *encodedCert) +kmf_encode_cert_record(KMF_X509_CERTIFICATE *CertData, KMF_DATA *encodedCert) { KMF_RETURN ret; + KMF_X509_TBS_CERT *tbs_cert; if (CertData == NULL || encodedCert == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -263,13 +284,14 @@ KMF_EncodeCertRecord(KMF_X509_CERTIFICATE *CertData, KMF_DATA *encodedCert) /* * Validate that all required fields are present. */ - if (NODATA(CertData->certificate.version) || - NODATA(CertData->certificate.signature.algorithm) || - NODATA(CertData->certificate.subjectPublicKeyInfo.subjectPublicKey) || - CertData->certificate.serialNumber.val == NULL || - CertData->certificate.serialNumber.len == 0 || - CertData->certificate.subject.numberOfRDNs == 0 || - CertData->certificate.issuer.numberOfRDNs == 0) { + tbs_cert = &(CertData->certificate); + if (NODATA(tbs_cert->version) || + NODATA(tbs_cert->signature.algorithm) || + NODATA(tbs_cert->subjectPublicKeyInfo.subjectPublicKey) || + tbs_cert->serialNumber.val == NULL || + tbs_cert->serialNumber.len == 0 || + tbs_cert->subject.numberOfRDNs == 0 || + tbs_cert->issuer.numberOfRDNs == 0) { return (KMF_ERR_INCOMPLETE_TBS_CERT); } @@ -282,346 +304,612 @@ KMF_EncodeCertRecord(KMF_X509_CERTIFICATE *CertData, KMF_DATA *encodedCert) return (ret); } -KMF_RETURN -KMF_DecodeCertData(KMF_DATA *rawcert, KMF_X509_CERTIFICATE **certrec) -{ - KMF_RETURN ret = KMF_OK; - - if (rawcert == NULL || rawcert->Data == NULL || - rawcert->Length == 0 || certrec == NULL) - return (KMF_ERR_BAD_PARAMETER); - - ret = DerDecodeSignedCertificate(rawcert, certrec); - - return (ret); -} - /* + * This function is used to setup the attribute list before calling + * kmf_find_prikey_by_cert(). This function is used by + * kmf_decrypt_with_cert + * kmf_sign_cert + * kmf_sign_data * - * Name: KMF_SignCertWithKey - * - * Description: - * This function signs a certificate using the private key and - * returns the result as a signed, encoded certificate in SignedCert - * - * Parameters: - * handle(input) - opaque handle for KMF session - * CertToBeSigned(input) - pointer to a KMF_DATA structure containing a - * DER encoded certificate to be signed - * Signkey(input) - pointer to private key handle needed for signing - * SignedCert(output) - pointer to the KMF_DATA structure containing the - * signed certificate - * - * Returns: - * A KMF_RETURN value indicating success or specifying a particular - * error condition. - * The value KMF_OK indicates success. All other values represent - * an error condition. + * The attribute list in these callers contain all the attributes + * needed by kmf_find_prikey_by_cert(), except the + * KMF_KEY_HANDLE attribute and the KMF_CERT_DATA_ATTR attribute. + * These 2 attributes need to be added or reset. * + * The caller should free the new_attrlist after use it. */ -KMF_RETURN -KMF_SignCertWithKey(KMF_HANDLE_T handle, - const KMF_DATA *CertToBeSigned, - KMF_KEY_HANDLE *Signkey, - KMF_DATA *SignedCert) +static KMF_RETURN +setup_findprikey_attrlist(KMF_ATTRIBUTE *src_attrlist, int src_num, + KMF_ATTRIBUTE **new_attrlist, int *new_num, KMF_KEY_HANDLE *key, + KMF_DATA *cert) { - KMF_RETURN err; - - CLEAR_ERROR(handle, err); - if (err != KMF_OK) - return (err); + KMF_ATTRIBUTE *attrlist = NULL; + int cur_num = src_num; + int index; + int i; - if (CertToBeSigned == NULL || - Signkey == NULL || SignedCert == NULL) + if (src_attrlist == NULL || new_num == NULL || key == NULL || + cert == NULL) return (KMF_ERR_BAD_PARAMETER); - err = SignCert(handle, CertToBeSigned, Signkey, SignedCert); + /* Create a new attribute list with 2 more elements */ + attrlist = (KMF_ATTRIBUTE *) malloc( + (src_num + 2) * sizeof (KMF_ATTRIBUTE)); + if (attrlist == NULL) + return (KMF_ERR_MEMORY); + + /* Copy the src_attrlist to the new list */ + for (i = 0; i < src_num; i++) { + attrlist[i].type = src_attrlist[i].type; + attrlist[i].pValue = src_attrlist[i].pValue; + attrlist[i].valueLen = src_attrlist[i].valueLen; + } - return (err); + /* Add or reset the key handle attribute */ + index = kmf_find_attr(KMF_KEY_HANDLE_ATTR, attrlist, cur_num); + if (index == -1) { + /* not found; add it */ + kmf_set_attr_at_index(attrlist, cur_num, + KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); + cur_num++; + } else { + /* found; just reset it */ + kmf_set_attr_at_index(attrlist, index, + KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); + } + + /* add or reset the cert data attribute */ + index = kmf_find_attr(KMF_CERT_DATA_ATTR, attrlist, cur_num); + if (index == -1) { + /* not found; add it */ + kmf_set_attr_at_index(attrlist, cur_num, + KMF_CERT_DATA_ATTR, cert, sizeof (KMF_DATA)); + cur_num++; + } else { + /* found; just reset it */ + kmf_set_attr_at_index(attrlist, index, + KMF_CERT_DATA_ATTR, cert, sizeof (KMF_DATA)); + } + + *new_attrlist = attrlist; + *new_num = cur_num; + return (KMF_OK); } + /* - * - * Name: KMF_SignCertWithCert + * Name: kmf_sign_cert * * Description: * This function signs a certificate using the signer cert and - * returns the result as a signed, encoded certificate in SignedCert + * returns a signed and DER-encoded certificate. * - * Parameters: - * handle(input) - opaque handle for KMF session - * params(input) - contains parameters to be used for signing - * CertToBeSigned(input) - pointer to a KMF_DATA structure containing a - * DER encoded certificate to be signed - * SignerCert(input) - pointer to a KMF_DATA structure containing a - * signer certificate - * SignedCert(output) - pointer to the KMF_DATA structure containing the - * DER encoded signed certificate - * - * Returns: - * A KMF_RETURN value indicating success or specifying a particular - * error condition. - * The value KMF_OK indicates success. All other values represent - * an error condition. + * The following types of certificate data can be submitted to be signed: + * KMF_TBS_CERT_DATA_ATTR - a KMF_DATA ptr is provided in the attrlist + * and is signed directly. + * KMF_X509_CERTIFICATE_ATTR - a KMF_X509_CERTIFICATE record is provided + * in the attribute list. This is converted to raw KMF_DATA + * prior to signing. * + * The key for the signing operation can be provided as a KMF_KEY_HANDLE_ATTR + * or the caller may choose to provide a KMF_SIGNER_CERT_ATTR (KMF_DATA *). + * If the latter, this function will then attempt to find the private key + * associated with the certificate. The private key must be stored in + * the same keystore as the signer certificate. */ KMF_RETURN -KMF_SignCertWithCert(KMF_HANDLE_T handle, - KMF_CRYPTOWITHCERT_PARAMS *params, - const KMF_DATA *CertToBeSigned, - KMF_DATA *SignerCert, - KMF_DATA *SignedCert) +kmf_sign_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret; - KMF_KEY_HANDLE Signkey; + int new_numattr = numattr + 1; + KMF_ATTRIBUTE *new_attrlist = NULL; + KMF_DATA *signer_cert = NULL; + KMF_DATA *tbs_cert = NULL; /* to be signed cert */ + KMF_DATA *signed_cert = NULL; + KMF_DATA unsignedCert = {NULL, 0}; + KMF_KEY_HANDLE sign_key, *sign_key_ptr; + int freethekey = 0; + KMF_X509_CERTIFICATE *x509cert; + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)} + }; + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); if (ret != KMF_OK) return (ret); - if (CertToBeSigned == NULL || - SignerCert == NULL || SignedCert == NULL) + /* Get the signer cert and check its keyUsage */ + signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist, + numattr); + sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, + numattr); + if (signer_cert == NULL && sign_key_ptr == NULL) return (KMF_ERR_BAD_PARAMETER); - /* check the keyUsage of signer's certificate */ - ret = check_key_usage(handle, SignerCert, KMF_KU_SIGN_CERT); - if (ret != KMF_OK) - return (ret); + if (signer_cert != NULL) { + ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_CERT); + if (ret != KMF_OK) + return (ret); - /* - * Retrieve the private key from the keystore for the - * signer certificate. - */ - ret = find_private_key_by_cert(handle, params, SignerCert, &Signkey); - if (ret != KMF_OK) - return (ret); + /* + * Find the private key from the signer certificate by calling + * kmf_find_prikey_by_cert(). + */ + ret = setup_findprikey_attrlist(attrlist, numattr, + &new_attrlist, &new_numattr, &sign_key, signer_cert); + if (ret != KMF_OK) + goto out; + + ret = kmf_find_prikey_by_cert(handle, new_numattr, + new_attrlist); + if (ret != KMF_OK) { + goto out; + } + sign_key_ptr = &sign_key; + freethekey = 1; + } - ret = SignCert(handle, CertToBeSigned, &Signkey, SignedCert); + /* Now we are ready to sign */ + tbs_cert = kmf_get_attr_ptr(KMF_TBS_CERT_DATA_ATTR, attrlist, + numattr); + if (tbs_cert == NULL) { + x509cert = kmf_get_attr_ptr(KMF_X509_CERTIFICATE_ATTR, attrlist, + numattr); + if (x509cert == NULL) { + ret = KMF_ERR_BAD_PARAMETER; + goto out; + } + ret = kmf_encode_cert_record(x509cert, &unsignedCert); + if (ret == KMF_OK) + tbs_cert = &unsignedCert; + else + goto out; + } - KMF_FreeKMFKey(handle, &Signkey); + signed_cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, + numattr); + if (signed_cert == NULL) { + ret = KMF_ERR_BAD_PARAMETER; + goto out; + } + + ret = sign_cert(handle, tbs_cert, sign_key_ptr, signed_cert); + +out: + if (new_attrlist) + (void) free(new_attrlist); + + /* If we had to find the key, free it here. */ + if (freethekey) + kmf_free_kmf_key(handle, &sign_key); + kmf_free_data(&unsignedCert); return (ret); } /* - * - * Name: KMF_SignDataWithCert + * Name: kmf_sign_data * * Description: * This function signs a block of data using the signer cert and - * returns the the signature in output - * - * Parameters: - * handle(input) - opaque handle for KMF session - * params(input) - contains parameters to be used for signing - * tobesigned(input) - pointer to a KMF_DATA structure containing a - * the data to be signed - * output(output) - pointer to the KMF_DATA structure containing the - * signed data - * SignerCertData(input) - pointer to a KMF_DATA structure containing a - * signer certificate - * - * Returns: - * A KMF_RETURN value indicating success or specifying a particular - * error condition. - * The value KMF_OK indicates success. All other values represent - * an error condition. - * + * returns the the signature in output */ KMF_RETURN -KMF_SignDataWithCert(KMF_HANDLE_T handle, - KMF_CRYPTOWITHCERT_PARAMS *params, - KMF_DATA *tobesigned, - KMF_DATA *output, - KMF_DATA *SignerCertData) +kmf_sign_data(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) { - - KMF_RETURN ret; - KMF_KEY_HANDLE Signkey; - KMF_X509_CERTIFICATE *SignerCert = NULL; KMF_PLUGIN *plugin; + KMF_RETURN ret = KMF_OK; + KMF_ATTRIBUTE *new_attrlist = NULL; + int new_numattr = numattr; + KMF_DATA *signer_cert = NULL; + KMF_DATA *tbs_data = NULL; /* to be signed data */ + KMF_DATA *output = NULL; + KMF_KEY_HANDLE sign_key, *sign_key_ptr; + KMF_X509_CERTIFICATE *x509_cert = NULL; KMF_ALGORITHM_INDEX AlgId; KMF_DATA signature = {0, NULL}; + KMF_OID *oid; - CLEAR_ERROR(handle, ret); - if (ret != KMF_OK) - return (ret); + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, + {KMF_OUT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)} + }; + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); - if (tobesigned == NULL || - SignerCertData == NULL || output == NULL) + if (handle == NULL) return (KMF_ERR_BAD_PARAMETER); - /* check the keyUsage of signer's certificate */ - ret = check_key_usage(handle, SignerCertData, KMF_KU_SIGN_DATA); + CLEAR_ERROR(handle, ret); - /* Signing generic data does not require the KeyUsage extension. */ - if (ret == KMF_ERR_EXTENSION_NOT_FOUND) - ret = KMF_OK; + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); if (ret != KMF_OK) return (ret); + /* Get the signer cert and check its keyUsage. */ + signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist, + numattr); + sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, + numattr); + + if (signer_cert == NULL && sign_key_ptr == NULL) + return (KMF_ERR_BAD_PARAMETER); + /* - * Retrieve the private key from the keystore based on - * the signer certificate. + * If a signer cert was given, use it to find the private key + * to use for signing the data. */ - ret = find_private_key_by_cert(handle, params, SignerCertData, - &Signkey); - if (ret != KMF_OK) { - goto cleanup; + if (signer_cert != NULL) { + ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA); + + /* + * Signing generic data does not require the + * KeyUsage extension. + */ + if (ret == KMF_ERR_EXTENSION_NOT_FOUND) + ret = KMF_OK; + if (ret != KMF_OK) + return (ret); + + /* + * Find the private key from the signer certificate. + */ + ret = setup_findprikey_attrlist(attrlist, numattr, + &new_attrlist, &new_numattr, &sign_key, signer_cert); + if (ret != KMF_OK) { + goto cleanup; + } + + ret = kmf_find_prikey_by_cert(handle, new_numattr, + new_attrlist); + if (ret != KMF_OK) { + goto cleanup; + } + sign_key_ptr = &sign_key; } - ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert); - if (ret != KMF_OK) + /* Get the tbs_data and signed_data attributes now */ + tbs_data = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, numattr); + if (tbs_data == NULL) { + ret = KMF_ERR_BAD_PARAMETER; goto cleanup; + } - plugin = FindPlugin(handle, Signkey.kstype); - if (plugin != NULL && plugin->funclist->SignData != NULL) { - KMF_OID *oid; - - if (params->algid != KMF_ALGID_NONE) - oid = X509_AlgIdToAlgorithmOid(params->algid); - else - oid = CERT_ALG_OID(SignerCert); + output = kmf_get_attr_ptr(KMF_OUT_DATA_ATTR, attrlist, numattr); + if (output == NULL) { + ret = KMF_ERR_BAD_PARAMETER; + goto cleanup; + } - ret = plugin->funclist->SignData(handle, &Signkey, - oid, tobesigned, output); + /* + * Get the algorithm index attribute and its oid. If this attribute + * is not provided, then we use the algorithm in the signer cert. + */ + oid = kmf_get_attr_ptr(KMF_OID_ATTR, attrlist, numattr); + ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, numattr, + &AlgId, NULL); + /* + * We need to know the Algorithm ID, it can be found 3 ways: + * 1. caller supplied OID in the attribute list. + * 2. caller supplied Algorithm Index in the attribute list. + * 3. caller supplied neither, but did supply a certificate, find + * the ALG OID from the certificate. + */ + /* If none of the above, return error. */ + if (oid == NULL && ret != KMF_OK && signer_cert == NULL) { + ret = KMF_ERR_BAD_PARAMETER; + goto cleanup; + } else if (oid == NULL && ret != KMF_OK) { + /* if no OID and No AlgID, use the signer cert */ + ret = DerDecodeSignedCertificate(signer_cert, &x509_cert); if (ret != KMF_OK) goto cleanup; - AlgId = X509_AlgorithmOidToAlgId(CERT_ALG_OID(SignerCert)); - - /* - * For DSA, NSS returns an encoded signature. Decode the - * signature as DSA signature should be 40-byte long. - */ - if ((AlgId == KMF_ALGID_SHA1WithDSA) && - (plugin->type == KMF_KEYSTORE_NSS)) { - ret = DerDecodeDSASignature(output, &signature); - if (ret != KMF_OK) { - goto cleanup; - } else { - output->Length = signature.Length; - (void) memcpy(output->Data, signature.Data, - signature.Length); - } - } else if (AlgId == KMF_ALGID_NONE) { - ret = KMF_ERR_BAD_ALGORITHM; + oid = CERT_ALG_OID(x509_cert); + AlgId = x509_algoid_to_algid(oid); + if (AlgId == KMF_ALGID_NONE) { + ret = KMF_ERR_BAD_PARAMETER; + goto cleanup; } - } else { + } else if (oid == NULL && ret == KMF_OK) { + /* AlgID was given by caller, convert it to OID */ + oid = x509_algid_to_algoid(AlgId); + } else { /* Else, the OID must have been given */ + ret = KMF_OK; + } + + /* Now call the plugin function to sign it */ + plugin = FindPlugin(handle, sign_key_ptr->kstype); + if (plugin == NULL || plugin->funclist->SignData == NULL) { ret = KMF_ERR_PLUGIN_NOTFOUND; + goto cleanup; + } + + ret = plugin->funclist->SignData(handle, sign_key_ptr, oid, tbs_data, + output); + if (ret != KMF_OK) + goto cleanup; + + /* + * For DSA, NSS returns an encoded signature. Decode the + * signature as DSA signature should be 40-byte long. + */ + if (plugin->type == KMF_KEYSTORE_NSS && + AlgId == KMF_ALGID_SHA1WithDSA) { + ret = DerDecodeDSASignature(output, &signature); + if (ret != KMF_OK) + goto cleanup; + output->Length = signature.Length; + (void) memcpy(output->Data, signature.Data, signature.Length); } cleanup: + if (new_attrlist != NULL) + free(new_attrlist); + if (signature.Data) free(signature.Data); - KMF_FreeKMFKey(handle, &Signkey); - if (SignerCert != NULL) { - KMF_FreeSignedCert(SignerCert); - free(SignerCert); + if (signer_cert != NULL && sign_key_ptr != NULL) + kmf_free_kmf_key(handle, sign_key_ptr); + + if (x509_cert != NULL) { + kmf_free_signed_cert(x509_cert); + free(x509_cert); } return (ret); } /* + * kmf_verify_data * - * Name: KMF_VerifyCertWithKey - * - * Description: - * This function verifies that the CertToBeVerified was signed - * using a specific private key and that the certificate has not - * been altered since it was signed using that private key + * This routine will try to verify a block of data using + * either a public key or a certificate as the source + * of the verification (the key). * - * Parameters: - * handle(input) - opaque handle for KMF session - * KMFKey(input) - holds public key information for verification - * CertToBeVerified(input) - A signed certificate whose signature - * is to be verified + * The caller may provider either a KMF_KEY_HANDLE_ATTR or + * a KMF_SIGNER_CERT_DATA_ATTR (with a KMF_DATA record) to + * use for the key to the verification step. If a certificate + * is used and that certificate has the KeyUsage extension, + * the SIGN-DATA bit must be set. Also, if a certificate + * is used, the verification will be done in a specific + * keystore mechanism. * - * Returns: - * A KMF_RETURN value indicating success or specifying a particular - * error condition. The value KMF_OK indicates success. All other - * values represent an error condition. + * If a KMF_KEY_HANDLE is given in the attribute list, the + * verification will occur in the framework itself using + * PKCS#11 C_Verify functions. */ KMF_RETURN -KMF_VerifyCertWithKey(KMF_HANDLE_T handle, - KMF_KEY_HANDLE *KMFKey, - const KMF_DATA *CertToBeVerified) +kmf_verify_data(KMF_HANDLE_T handle, + int num_args, + KMF_ATTRIBUTE *attrlist) { - KMF_RETURN err; + KMF_RETURN ret = KMF_OK; + KMF_PLUGIN *plugin; + KMF_KEYSTORE_TYPE kstype; + uint32_t len; KMF_DATA derkey = {0, NULL}; - KMF_PLUGIN *plugin; + KMF_KEY_HANDLE *KMFKey; + KMF_ALGORITHM_INDEX sigAlg; + KMF_DATA *indata; + KMF_DATA *insig; + KMF_DATA *signer_cert; + KMF_X509_SPKI spki; + + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_DATA_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)}, + {KMF_IN_SIGN_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)} + }; - CLEAR_ERROR(handle, err); - if (err != KMF_OK) - return (err); + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); - if (KMFKey == NULL || - CertToBeVerified == NULL) + if (handle == NULL) return (KMF_ERR_BAD_PARAMETER); - /* The keystore must extract the pubkey data */ - plugin = FindPlugin(handle, KMFKey->kstype); - if (plugin != NULL && plugin->funclist->EncodePubkeyData != NULL) { - err = plugin->funclist->EncodePubkeyData(handle, - KMFKey, &derkey); - } else { - return (KMF_ERR_PLUGIN_NOTFOUND); + CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, num_args, attrlist); + + if (ret != KMF_OK) + return (ret); + + len = sizeof (kstype); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args, + &kstype, &len); + if (ret != KMF_OK) + return (ret); + + KMFKey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, num_args); + signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist, + num_args); + if (KMFKey == NULL && signer_cert == NULL) { + return (KMF_ERR_BAD_PARAMETER); } - if (err == KMF_OK && derkey.Length > 0) { - /* check the caller and do other setup for this SPI call */ - err = VerifyCertWithKey(handle, &derkey, CertToBeVerified); + len = sizeof (sigAlg); + ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, num_args, + &sigAlg, &len); + if (ret != KMF_OK) + return (ret); + + indata = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, num_args); + if (indata == NULL) + return (KMF_ERR_BAD_PARAMETER); + + insig = kmf_get_attr_ptr(KMF_IN_SIGN_ATTR, attrlist, num_args); + if (insig == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* If the caller passed a signer cert instead of a key use it. */ + if (signer_cert != NULL) { + ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA); + if (ret != KMF_OK) + return (ret); + + if (kstype == KMF_KEYSTORE_NSS) + kstype = KMF_KEYSTORE_PK11TOKEN; + plugin = FindPlugin(handle, kstype); + if (plugin == NULL) + return (KMF_ERR_PLUGIN_NOTFOUND); + if (plugin->funclist->VerifyDataWithCert == NULL) + return (KMF_ERR_FUNCTION_NOT_FOUND); + + CLEAR_ERROR(handle, ret); + ret = plugin->funclist->VerifyDataWithCert(handle, + sigAlg, indata, insig, signer_cert); + } else { + /* Retrieve public key data from keystore */ + plugin = FindPlugin(handle, kstype); + if (plugin != NULL && + plugin->funclist->EncodePubkeyData != NULL) { + ret = plugin->funclist->EncodePubkeyData(handle, + KMFKey, &derkey); + } else { + return (KMF_ERR_PLUGIN_NOTFOUND); + } + + ret = DerDecodeSPKI(&derkey, &spki); + if (ret == KMF_OK) { + ret = PKCS_VerifyData(handle, sigAlg, &spki, + indata, insig); + } if (derkey.Data != NULL) free(derkey.Data); + + kmf_free_algoid(&spki.algorithm); + kmf_free_data(&spki.subjectPublicKey); } - return (err); + return (ret); } - /* - * - * Name: KMF_VerifyCertWithCert + * Name: kmf_verify_cert * * Description: - * Function to verify the signature of a signed certificate + * This function verifies that the a certificate was signed + * using a specific private key and that the certificate has not + * been altered since it was signed using that private key + * The public key used for verification may be given in the + * attribute list as a KMF_KEY_HANDLE or the caller may give + * just the signing certificate (as KMF_SIGNER_CERT_DATA_ATTR) + * from which the public key needed for verification can be + * derived. * * Parameters: - * handle - pointer to KMF handle - * CertToBeVerified(input) - pointer to the signed certificate - * SignerCert(input) - pointer to certificate used in signing + * handle(input) - opaque handle for KMF session + * numattr - number of attributes in the list + * attrlist - KMF_ATTRIBUTES * * Returns: - * A KMF_RETURN value. - * The value KMF_OK indicates success. - * All other values represent an error condition. + * A KMF_RETURN value indicating success or specifying a particular + * error condition. The value KMF_OK indicates success. All other + * values represent an error condition. */ KMF_RETURN -KMF_VerifyCertWithCert(KMF_HANDLE_T handle, - const KMF_DATA *CertToBeVerified, - const KMF_DATA *SignerCert) +kmf_verify_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { - KMF_RETURN ret; + KMF_RETURN ret; + KMF_DATA derkey = {0, NULL}; + KMF_PLUGIN *plugin; + KMF_KEY_HANDLE *KMFKey; + KMF_DATA *CertToBeVerified; + KMF_DATA *SignerCert; + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)} + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); CLEAR_ERROR(handle, ret); if (ret != KMF_OK) return (ret); - if (CertToBeVerified == NULL || - SignerCert == NULL) - return (KMF_ERR_BAD_PARAMETER); - - /* check the keyUsage of signer's certificate */ - ret = check_key_usage(handle, SignerCert, KMF_KU_SIGN_CERT); + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); if (ret != KMF_OK) return (ret); - ret = VerifyCertWithCert(handle, CertToBeVerified, SignerCert); + KMFKey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + SignerCert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist, + numattr); + + /* + * Caller must provide at least a key handle or a cert to use + * as the "key" for verification. + */ + if (KMFKey == NULL && SignerCert == NULL) + return (KMF_ERR_BAD_PARAMETER); + + CertToBeVerified = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, + numattr); + if (CertToBeVerified == NULL) + return (KMF_ERR_BAD_PARAMETER); + + if (SignerCert != NULL) { + ret = verify_cert_with_cert(handle, CertToBeVerified, + SignerCert); + } else { + /* + * The keystore must extract the pubkey data because + * the framework doesn't have access to the raw key bytes + * that are needed to construct the DER encoded public + * key information needed for the verify operation. + */ + plugin = FindPlugin(handle, KMFKey->kstype); + if (plugin != NULL && plugin->funclist->EncodePubkeyData != + NULL) { + ret = plugin->funclist->EncodePubkeyData(handle, + KMFKey, &derkey); + } else { + return (KMF_ERR_PLUGIN_NOTFOUND); + } + + if (ret == KMF_OK && derkey.Length > 0) { + ret = verify_cert_with_key(handle, &derkey, + CertToBeVerified); + + if (derkey.Data != NULL) + free(derkey.Data); + } + } + return (ret); } +/* + * Utility routine for verifying generic data using a + * certificate to derive the public key. This is + * done in a specific plugin because there are situations + * where we want to force this operation to happen in + * a specific keystore. + * For example: + * libelfsign verifies signatures on crypto libraries. + * We cannot use libpkcs11 functions to verify the pkcs11 + * libraries because it results in a circular dependency. + * So, when libelfsign is verifying library sigs, it + * always forces the operation to happen in OpenSSL + * to avoid the circular dependency. + */ static KMF_RETURN plugin_verify_data_with_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype, @@ -651,69 +939,13 @@ plugin_verify_data_with_cert(KMF_HANDLE_T handle, CLEAR_ERROR(handle, ret); ret = (plugin->funclist->VerifyDataWithCert(handle, - algid, indata, insig, (KMF_DATA *)SignerCert)); + algid, indata, insig, (KMF_DATA *)SignerCert)); return (ret); } /* - * - * Name: KMF_VerifyDataWithCert - * - * Description: - * This function verifies the signature of a block of data using a signer - * certificate. - * - * Parameters: - * handle(input) - opaque handle for KMF session - * indata(input) - pointer to the block of data whose signature - * is to be verified - * insig(input) - pointer to the signature to be verified - * SignerCert(input) - pointer to signer cert for verification - * - * Returns: - * A KMF_RETURN value indicating success or specifying a particular - * error condition. - * The value KMF_OK indicates success. All other values represent - * an error condition. - * - */ -KMF_RETURN -KMF_VerifyDataWithCert(KMF_HANDLE_T handle, - KMF_KEYSTORE_TYPE kstype, - KMF_ALGORITHM_INDEX algid, - KMF_DATA *indata, - KMF_DATA *insig, - const KMF_DATA *SignerCert) -{ - KMF_RETURN ret; - - CLEAR_ERROR(handle, ret); - if (ret != KMF_OK) - return (ret); - - if (SignerCert == NULL || - indata == NULL || insig == NULL) - return (KMF_ERR_BAD_PARAMETER); - - /* check the keyUsage of signer's certificate */ - ret = check_key_usage(handle, SignerCert, KMF_KU_SIGN_DATA); - - /* For this operation, it is OK if KeyUsage is not present */ - if (ret == KMF_ERR_EXTENSION_NOT_FOUND) - ret = KMF_OK; - - if (ret != KMF_OK) - return (ret); - - ret = plugin_verify_data_with_cert(handle, kstype, - algid, indata, insig, SignerCert); - - return (ret); -} - -/* - * Name: KMF_EncryptWithCert + * Name: kmf_encrypt * * Description: * Uses the public key from the cert to encrypt the plaintext @@ -735,23 +967,45 @@ KMF_VerifyDataWithCert(KMF_HANDLE_T handle, * */ KMF_RETURN -KMF_EncryptWithCert(KMF_HANDLE_T handle, - KMF_DATA *cert, - KMF_DATA *plaintext, - KMF_DATA *ciphertext) +kmf_encrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret; KMF_X509_CERTIFICATE *x509cert = NULL; KMF_X509_SPKI *pubkey; KMF_OID *alg; KMF_ALGORITHM_INDEX algid; + KMF_DATA *cert; + KMF_DATA *plaintext; + KMF_DATA *ciphertext; + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)}, + {KMF_PLAINTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)}, + {KMF_CIPHERTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)} + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); CLEAR_ERROR(handle, ret); if (ret != KMF_OK) return (ret); - if (cert == NULL || - plaintext == NULL || ciphertext == NULL) + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); + if (ret != KMF_OK) + return (ret); + + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, + numattr); + plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist, + numattr); + ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist, + numattr); + + if (cert == NULL || plaintext == NULL || ciphertext == NULL) return (KMF_ERR_BAD_PARAMETER); /* check the keyUsage of the certificate */ @@ -771,68 +1025,72 @@ KMF_EncryptWithCert(KMF_HANDLE_T handle, /* Use the algorithm in SPKI to encrypt data */ alg = &pubkey->algorithm.algorithm; - algid = X509_AlgorithmOidToAlgId(alg); + algid = x509_algoid_to_algid(alg); /* DSA does not support encrypt */ if (algid == KMF_ALGID_DSA || algid == KMF_ALGID_NONE) { - KMF_FreeSignedCert(x509cert); + kmf_free_signed_cert(x509cert); free(x509cert); return (KMF_ERR_BAD_ALGORITHM); } + /* + * Encrypt using the crypto framework (not the KMF plugin mechanism). + */ ret = PKCS_EncryptData(handle, algid, pubkey, plaintext, ciphertext); - KMF_FreeSignedCert(x509cert); + kmf_free_signed_cert(x509cert); free(x509cert); return (ret); } /* - * Name: KMF_DecryptWithCert + * Name: kmf_decrypt * * Description: * Uses the private key associated with the cert to decrypt * the ciphertext into the plaintext. - * - * Parameters: - * handle(input) - opaque handle for KMF session - * params(input) - contains parameters to be used to find the private - * key for decryption - * cert(input) - pointer to a DER encoded certificate for decryption - * by using its private key - * ciphertext(input) - pointer to the ciphertext contains to be - * decrypted data - * plaintext(output) - pointer to the plaintext after decryption - * - * Returns: - * A KMF_RETURN value indicating success or specifying a particular - * error condition. - * The value KMF_OK indicates success. All other values represent - * an error condition. - * */ KMF_RETURN -KMF_DecryptWithCert(KMF_HANDLE_T handle, - KMF_CRYPTOWITHCERT_PARAMS *params, - KMF_DATA *cert, - KMF_DATA *ciphertext, - KMF_DATA *plaintext) +kmf_decrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret; - KMF_KEY_HANDLE Signkey; KMF_X509_CERTIFICATE *x509cert = NULL; KMF_X509_SPKI *spki_ptr; KMF_PLUGIN *plugin; KMF_ALGORITHM_INDEX AlgorithmId; - - + KMF_ATTRIBUTE *new_attrlist = NULL; + int new_numattr; + KMF_DATA *cert = NULL; + KMF_DATA *ciphertext = NULL; + KMF_DATA *plaintext = NULL; + KMF_KEY_HANDLE prikey; + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, + {KMF_PLAINTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)}, + {KMF_CIPHERTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)}, + }; + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); if (ret != KMF_OK) return (ret); - if (cert == NULL || - plaintext == NULL || ciphertext == NULL) + + /* Get the cert and check its keyUsage */ + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, + numattr); + if (cert == NULL) return (KMF_ERR_BAD_PARAMETER); /* check the keyUsage of the certificate */ @@ -842,14 +1100,29 @@ KMF_DecryptWithCert(KMF_HANDLE_T handle, if (ret != KMF_OK) return (ret); + /* Get the ciphertext and plaintext attributes */ + ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist, + numattr); + if (ciphertext == NULL) + return (KMF_ERR_BAD_PARAMETER); + + plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist, + numattr); + if (plaintext == NULL) + return (KMF_ERR_BAD_PARAMETER); + /* * Retrieve the private key from the keystore based on * the certificate. */ - ret = find_private_key_by_cert(handle, params, cert, &Signkey); - if (ret != KMF_OK) { - return (ret); - } + ret = setup_findprikey_attrlist(attrlist, numattr, &new_attrlist, + &new_numattr, &prikey, cert); + if (ret != KMF_OK) + goto cleanup; + + ret = kmf_find_prikey_by_cert(handle, new_numattr, new_attrlist); + if (ret != KMF_OK) + goto cleanup; /* Decode the cert so we can get the alogorithm */ ret = DerDecodeSignedCertificate(cert, &x509cert); @@ -857,7 +1130,7 @@ KMF_DecryptWithCert(KMF_HANDLE_T handle, goto cleanup; spki_ptr = &x509cert->certificate.subjectPublicKeyInfo; - AlgorithmId = X509_AlgorithmOidToAlgId((KMF_OID *) + AlgorithmId = x509_algoid_to_algid((KMF_OID *) &spki_ptr->algorithm.algorithm); /* DSA does not support decrypt */ @@ -866,93 +1139,137 @@ KMF_DecryptWithCert(KMF_HANDLE_T handle, goto cleanup; } - plugin = FindPlugin(handle, Signkey.kstype); + plugin = FindPlugin(handle, prikey.kstype); if (plugin != NULL && plugin->funclist->DecryptData != NULL) { ret = plugin->funclist->DecryptData(handle, - &Signkey, &spki_ptr->algorithm.algorithm, + &prikey, &spki_ptr->algorithm.algorithm, ciphertext, plaintext); } else { ret = KMF_ERR_PLUGIN_NOTFOUND; } cleanup: - KMF_FreeKMFKey(handle, &Signkey); - KMF_FreeSignedCert(x509cert); + if (new_attrlist != NULL) + free(new_attrlist); + + kmf_free_kmf_key(handle, &prikey); + kmf_free_signed_cert(x509cert); free(x509cert); return (ret); } KMF_RETURN -KMF_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *target, - KMF_DATA *pcert) +kmf_store_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_PLUGIN *plugin; - KMF_RETURN ret; + KMF_RETURN ret = KMF_OK; + KMF_KEYSTORE_TYPE kstype; + + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); if (ret != KMF_OK) return (ret); - if (target == NULL || pcert == NULL) - return (KMF_ERR_BAD_PARAMETER); - - plugin = FindPlugin(handle, target->kstype); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, + &kstype, NULL); + if (ret != KMF_OK) + return (ret); - if (plugin != NULL && plugin->funclist->StoreCert != NULL) { - return (plugin->funclist->StoreCert(handle, target, pcert)); - } else { + plugin = FindPlugin(handle, kstype); + if (plugin == NULL || plugin->funclist->StoreCert == NULL) return (KMF_ERR_PLUGIN_NOTFOUND); - } + + return (plugin->funclist->StoreCert(handle, numattr, attrlist)); } KMF_RETURN -KMF_ImportCert(KMF_HANDLE_T handle, KMF_IMPORTCERT_PARAMS *target) +kmf_import_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_PLUGIN *plugin; - KMF_RETURN ret; + KMF_RETURN ret = KMF_OK; + KMF_KEYSTORE_TYPE kstype; + + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_CERT_FILENAME_ATTR, TRUE, 1, 0}, + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, 0, NULL, + numattr, attrlist); if (ret != KMF_OK) return (ret); - if (target == NULL) - return (KMF_ERR_BAD_PARAMETER); - - plugin = FindPlugin(handle, target->kstype); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, + &kstype, NULL); + if (ret != KMF_OK) + return (ret); - if (plugin != NULL && plugin->funclist->ImportCert != NULL) { - return (plugin->funclist->ImportCert(handle, target)); - } else { + plugin = FindPlugin(handle, kstype); + if (plugin == NULL || plugin->funclist->ImportCert == NULL) return (KMF_ERR_PLUGIN_NOTFOUND); - } + + return (plugin->funclist->ImportCert(handle, numattr, attrlist)); } KMF_RETURN -KMF_DeleteCertFromKeystore(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *target) +kmf_delete_cert_from_keystore(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) { KMF_PLUGIN *plugin; - KMF_RETURN ret; + KMF_RETURN ret = KMF_OK; + KMF_KEYSTORE_TYPE kstype; + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)} + }; + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); if (ret != KMF_OK) return (ret); - if (target == NULL || - (target->find_cert_validity < KMF_ALL_CERTS) || - (target->find_cert_validity > KMF_EXPIRED_CERTS)) - return (KMF_ERR_BAD_PARAMETER); - - plugin = FindPlugin(handle, target->kstype); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, + &kstype, NULL); + if (ret != KMF_OK) + return (ret); - if (plugin != NULL && plugin->funclist->DeleteCert != NULL) { - return (plugin->funclist->DeleteCert(handle, target)); - } else { + plugin = FindPlugin(handle, kstype); + if (plugin == NULL || plugin->funclist->DeleteCert == NULL) return (KMF_ERR_PLUGIN_NOTFOUND); - } + + return (plugin->funclist->DeleteCert(handle, numattr, attrlist)); } + /* * This function gets the CRL URI entries from the certificate's Distribution * points extension, and downloads the CRL file. The function also returns @@ -995,7 +1312,7 @@ cert_get_crl(KMF_HANDLE_T handle, const KMF_DATA *cert, char *proxy, * the process until a CRL file is sucessfully downloaded or we * are running out the CRL URI's. */ - ret = KMF_GetCertCRLDistributionPointsExt((const KMF_DATA *)cert, + ret = kmf_get_cert_crl_dist_pts((const KMF_DATA *)cert, &crl_dps); if (ret != KMF_OK) goto out; @@ -1011,7 +1328,7 @@ cert_get_crl(KMF_HANDLE_T handle, const KMF_DATA *cert, char *proxy, data = &(fullname->namelist[j].name); (void) memcpy(uri, data->Data, data->Length); uri[data->Length] = '\0'; - ret = KMF_DownloadCRL(handle, uri, proxyname, + ret = kmf_download_crl(handle, uri, proxyname, proxy_port, 30, filename, format); if (ret == KMF_OK) { done = B_TRUE; @@ -1028,25 +1345,21 @@ cert_get_crl(KMF_HANDLE_T handle, const KMF_DATA *cert, char *proxy, } out: - KMF_FreeCRLDistributionPoints(&crl_dps); + kmf_free_crl_dist_pts(&crl_dps); return (ret); } static KMF_RETURN -cert_crl_check(KMF_HANDLE_T handle, - KMF_VALIDATECERT_PARAMS *params, - KMF_DATA *user_cert, - KMF_DATA *issuer_cert) +cert_crl_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, + KMF_DATA *user_cert, KMF_DATA *issuer_cert) { KMF_POLICY_RECORD *policy; KMF_RETURN ret = KMF_OK; - KMF_IMPORTCRL_PARAMS icrl_params; - KMF_FINDCERTINCRL_PARAMS fcrl_params; - KMF_OPENSSL_PARAMS ssl_params; - KMF_VERIFYCRL_PARAMS vcrl_params; + KMF_ATTRIBUTE attrlist[16]; + int numattr = 0; + boolean_t crlchk; char user_certfile[MAXPATHLEN]; char crlfile_tmp[MAXPATHLEN]; - KMF_CHECKCRLDATE_PARAMS ccrldate_params; char *basefilename = NULL; char *dir = NULL; char *crlfilename = NULL; @@ -1054,17 +1367,14 @@ cert_crl_check(KMF_HANDLE_T handle, char *uri = NULL; KMF_ENCODE_FORMAT format; - if (handle == NULL || params == NULL || - user_cert == NULL || issuer_cert == NULL) + if (handle == NULL || kstype == NULL || user_cert == NULL || + issuer_cert == NULL) return (KMF_ERR_BAD_PARAMETER); - policy = handle->policy; + if (!VALID_KEYSTORE_TYPE(*kstype)) + return (KMF_ERR_BAD_PARAMETER); - (void) memset(&icrl_params, 0, sizeof (icrl_params)); - (void) memset(&vcrl_params, 0, sizeof (vcrl_params)); - (void) memset(&ccrldate_params, 0, sizeof (ccrldate_params)); - (void) memset(&fcrl_params, 0, sizeof (fcrl_params)); - (void) memset(&ssl_params, 0, sizeof (ssl_params)); + policy = handle->policy; /* * If the get-crl-uri policy is TRUE, then download the CRL @@ -1104,16 +1414,27 @@ cert_crl_check(KMF_HANDLE_T handle, } /* Cache the CRL file. */ - if (params->kstype == KMF_KEYSTORE_NSS) { + if (*kstype == KMF_KEYSTORE_NSS) { /* * For NSS keystore, import this CRL file into th * internal database. */ - icrl_params.kstype = KMF_KEYSTORE_NSS; - icrl_params.nssparms.slotlabel = NULL; - icrl_params.nssparms.crlfile = crlfile_tmp; - icrl_params.nssparms.crl_check = B_FALSE; - ret = KMF_ImportCRL(handle, &icrl_params); + numattr = 0; + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYSTORE_TYPE_ATTR, kstype, sizeof (kstype)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_CRL_FILENAME_ATTR, crlfile_tmp, + strlen(crlfile_tmp)); + numattr++; + + crlchk = B_FALSE; + kmf_set_attr_at_index(attrlist, numattr, + KMF_CRL_CHECK_ATTR, &crlchk, sizeof (boolean_t)); + numattr++; + + ret = kmf_import_crl(handle, numattr, attrlist); (void) unlink(crlfile_tmp); if (ret != KMF_OK) goto cleanup; @@ -1145,7 +1466,7 @@ cert_crl_check(KMF_HANDLE_T handle, * If the get_crl_uri policy is FALSE, for File-based CRL * plugins, get the input CRL file from the policy. */ - if (params->kstype != KMF_KEYSTORE_NSS) { + if (*kstype != KMF_KEYSTORE_NSS) { if (basefilename == NULL) { ret = KMF_ERR_BAD_PARAMETER; goto cleanup; @@ -1168,11 +1489,9 @@ cert_crl_check(KMF_HANDLE_T handle, * NSS CRL is not file based, and its signature * has been verified during CRL import. */ - if (params->kstype != KMF_KEYSTORE_NSS) { - vcrl_params.crl_name = crlfilename; - vcrl_params.tacert = issuer_cert; - - ret = KMF_VerifyCRLFile(handle, &vcrl_params); + if (*kstype != KMF_KEYSTORE_NSS) { + ret = kmf_verify_crl_file(handle, crlfilename, + issuer_cert); if (ret != KMF_OK) { goto cleanup; } @@ -1186,10 +1505,8 @@ cert_crl_check(KMF_HANDLE_T handle, /* * This is for file-based CRL, but not for NSS CRL. */ - if (params->kstype != KMF_KEYSTORE_NSS) { - ccrldate_params.crl_name = crlfilename; - - ret = KMF_CheckCRLDate(handle, &ccrldate_params); + if (*kstype != KMF_KEYSTORE_NSS) { + ret = kmf_check_crl_date(handle, crlfilename); if (ret != KMF_OK) { goto cleanup; } @@ -1199,12 +1516,20 @@ cert_crl_check(KMF_HANDLE_T handle, /* * Check the CRL revocation for the certificate. */ - fcrl_params.kstype = params->kstype; - switch (params->kstype) { + numattr = 0; + + kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, + kstype, sizeof (kstype)); + numattr++; + + switch (*kstype) { case KMF_KEYSTORE_NSS: - fcrl_params.nssparms.certificate = params->certificate; + kmf_set_attr_at_index(attrlist, numattr, + KMF_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA)); + numattr++; break; case KMF_KEYSTORE_PK11TOKEN: + case KMF_KEYSTORE_OPENSSL: /* * Create temporary file to hold the user certificate. */ @@ -1215,27 +1540,28 @@ cert_crl_check(KMF_HANDLE_T handle, goto cleanup; } - ret = KMF_CreateCertFile(user_cert, KMF_FORMAT_ASN1, + ret = kmf_create_cert_file(user_cert, KMF_FORMAT_ASN1, user_certfile); if (ret != KMF_OK) { goto cleanup; } - ssl_params.certfile = user_certfile; - ssl_params.crlfile = crlfilename; - fcrl_params.sslparms = ssl_params; - break; - case KMF_KEYSTORE_OPENSSL: - ssl_params.certfile = params->ks_opt_u.openssl_opts.certfile; - ssl_params.crlfile = crlfilename; - fcrl_params.sslparms = ssl_params; + kmf_set_attr_at_index(attrlist, numattr, + KMF_CERT_FILENAME_ATTR, + user_certfile, strlen(user_certfile)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_CRL_FILENAME_ATTR, + crlfilename, strlen(crlfilename)); + numattr++; break; default: ret = KMF_ERR_PLUGIN_NOTFOUND; goto cleanup; } - ret = KMF_FindCertInCRL(handle, &fcrl_params); + ret = kmf_find_cert_in_crl(handle, numattr, attrlist); if (ret == KMF_ERR_NOT_REVOKED) { ret = KMF_OK; } @@ -1253,24 +1579,24 @@ cleanup: } static KMF_RETURN -cert_ocsp_check(KMF_HANDLE_T handle, - KMF_VALIDATECERT_PARAMS *params, - KMF_DATA *user_cert, - KMF_DATA *issuer_cert, - KMF_DATA *response) +cert_ocsp_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, + KMF_DATA *user_cert, KMF_DATA *issuer_cert, KMF_DATA *response, + char *slotlabel, char *dirpath) { KMF_RETURN ret = KMF_OK; KMF_POLICY_RECORD *policy; - KMF_FINDCERT_PARAMS fc_target; - KMF_OCSPRESPONSE_PARAMS_INPUT resp_params_in; - KMF_OCSPRESPONSE_PARAMS_OUTPUT resp_params_out; KMF_DATA *new_response = NULL; boolean_t ignore_response_sign = B_FALSE; - uint32_t ltime; + uint32_t ltime = 0; KMF_DATA *signer_cert = NULL; KMF_BIGINT sernum = { NULL, 0 }; + int response_status; + int reason; + int cert_status; + KMF_ATTRIBUTE attrlist[32]; + int numattr; - if (handle == NULL || params == NULL || user_cert == NULL || + if (handle == NULL || kstype == NULL || user_cert == NULL || issuer_cert == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -1296,11 +1622,13 @@ cert_ocsp_check(KMF_HANDLE_T handle, if (ignore_response_sign == B_FALSE && policy->VAL_OCSP.has_resp_cert == B_TRUE) { char *signer_name; - KMF_OPENSSL_PARAMS ssl_params; KMF_X509_DER_CERT signer_retrcert; uchar_t *bytes = NULL; size_t bytelen; uint32_t num = 0; + KMF_ATTRIBUTE fc_attrlist[16]; + int fc_numattr = 0; + char *dir = "./"; if (policy->VAL_OCSP_RESP_CERT.name == NULL || policy->VAL_OCSP_RESP_CERT.serial == NULL) @@ -1314,49 +1642,55 @@ cert_ocsp_check(KMF_HANDLE_T handle, (void) memset(signer_cert, 0, sizeof (KMF_DATA)); signer_name = policy->VAL_OCSP_RESP_CERT.name; - ret = KMF_HexString2Bytes( + ret = kmf_hexstr_to_bytes( (uchar_t *)policy->VAL_OCSP_RESP_CERT.serial, &bytes, &bytelen); if (ret != KMF_OK || bytes == NULL) { ret = KMF_ERR_OCSP_POLICY; goto out; } - sernum.val = bytes; sernum.len = bytelen; - (void) memset(&fc_target, 0, sizeof (fc_target)); - (void) memset(&ssl_params, 0, sizeof (ssl_params)); + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_KEYSTORE_TYPE_ATTR, kstype, + sizeof (KMF_KEYSTORE_TYPE)); + fc_numattr++; - fc_target.subject = signer_name; - fc_target.serial = &sernum; + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_SUBJECT_NAME_ATTR, signer_name, strlen(signer_name)); + fc_numattr++; - switch (params->kstype) { - case KMF_KEYSTORE_NSS: - fc_target.kstype = KMF_KEYSTORE_NSS; - params->nssparms.slotlabel = - params->nssparms.slotlabel; - break; + kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_BIGINT_ATTR, + &sernum, sizeof (KMF_BIGINT)); + fc_numattr++; - case KMF_KEYSTORE_OPENSSL: - fc_target.kstype = KMF_KEYSTORE_OPENSSL; - ssl_params.dirpath = - params->sslparms.dirpath == NULL ? - "./" : params->sslparms.dirpath; - fc_target.sslparms = ssl_params; - break; + if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) { + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_TOKEN_LABEL_ATTR, slotlabel, + strlen(slotlabel)); + fc_numattr++; + } - case KMF_KEYSTORE_PK11TOKEN: - fc_target.kstype = KMF_KEYSTORE_PK11TOKEN; - break; - default: - ret = KMF_ERR_BAD_PARAMETER; - goto out; - break; + if (*kstype == KMF_KEYSTORE_OPENSSL) { + if (dirpath == NULL) { + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_DIRPATH_ATTR, dir, strlen(dir)); + fc_numattr++; + } else { + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_DIRPATH_ATTR, dirpath, + strlen(dirpath)); + fc_numattr++; + } } num = 0; - ret = KMF_FindCert(handle, &fc_target, NULL, &num); + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_COUNT_ATTR, &num, sizeof (uint32_t)); + fc_numattr++; + + ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); if (ret != KMF_OK || num != 1) { if (num == 0) ret = KMF_ERR_CERT_NOT_FOUND; @@ -1366,7 +1700,12 @@ cert_ocsp_check(KMF_HANDLE_T handle, } (void) memset(&signer_retrcert, 0, sizeof (KMF_X509_DER_CERT)); - ret = KMF_FindCert(handle, &fc_target, &signer_retrcert, &num); + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_X509_DER_CERT_ATTR, &signer_retrcert, + sizeof (KMF_X509_DER_CERT)); + fc_numattr++; + + ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); if (ret == KMF_OK) { signer_cert->Length = signer_retrcert.certificate.Length; @@ -1390,7 +1729,7 @@ cert_ocsp_check(KMF_HANDLE_T handle, new_response->Data = NULL; new_response->Length = 0; - ret = KMF_GetOCSPForCert(handle, user_cert, issuer_cert, + ret = kmf_get_ocsp_for_cert(handle, user_cert, issuer_cert, new_response); if (ret != KMF_OK) goto out; @@ -1399,18 +1738,49 @@ cert_ocsp_check(KMF_HANDLE_T handle, /* * Process the OCSP response and retrieve the certificate status. */ - resp_params_in.issuer_cert = issuer_cert; - resp_params_in.user_cert = user_cert; - resp_params_in.signer_cert = signer_cert; - resp_params_in.response = - response == NULL ? new_response : response; - resp_params_in.response_lifetime = ltime; - resp_params_in.ignore_response_sign = ignore_response_sign; - - ret = KMF_GetOCSPStatusForCert(handle, &resp_params_in, - &resp_params_out); + numattr = 0; + kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_CERT_DATA_ATTR, + issuer_cert, sizeof (KMF_DATA)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, KMF_USER_CERT_DATA_ATTR, + user_cert, sizeof (KMF_DATA)); + numattr++; + + if (signer_cert != NULL) { + kmf_set_attr_at_index(attrlist, numattr, + KMF_SIGNER_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA)); + numattr++; + } + + kmf_set_attr_at_index(attrlist, numattr, KMF_OCSP_RESPONSE_DATA_ATTR, + response == NULL ? new_response : response, sizeof (KMF_DATA)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, KMF_RESPONSE_LIFETIME_ATTR, + <ime, sizeof (uint32_t)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_IGNORE_RESPONSE_SIGN_ATTR, &ignore_response_sign, + sizeof (boolean_t)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_OCSP_RESPONSE_STATUS_ATTR, &response_status, sizeof (int)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_OCSP_RESPONSE_REASON_ATTR, &reason, sizeof (int)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, &cert_status, sizeof (int)); + numattr++; + + ret = kmf_get_ocsp_status_for_cert(handle, numattr, attrlist); if (ret == KMF_OK) { - switch (resp_params_out.cert_status) { + switch (cert_status) { case OCSP_GOOD: break; case OCSP_UNKNOWN: @@ -1424,12 +1794,12 @@ cert_ocsp_check(KMF_HANDLE_T handle, out: if (new_response) { - KMF_FreeData(new_response); + kmf_free_data(new_response); free(new_response); } if (signer_cert) { - KMF_FreeData(signer_cert); + kmf_free_data(signer_cert); free(signer_cert); } @@ -1453,7 +1823,7 @@ cert_ku_check(KMF_HANDLE_T handle, KMF_DATA *cert) policy = handle->policy; (void) memset(&keyusage, 0, sizeof (keyusage)); - ret = KMF_GetCertKeyUsageExt(cert, &keyusage); + ret = kmf_get_cert_ku(cert, &keyusage); if (ret == KMF_ERR_EXTENSION_NOT_FOUND) { if (policy->ku_bits) { @@ -1476,8 +1846,8 @@ cert_ku_check(KMF_HANDLE_T handle, KMF_DATA *cert) */ if ((keyusage.KeyUsageBits & KMF_keyCertSign)) { (void) memset(&constraint, 0, sizeof (constraint)); - ret = KMF_GetCertBasicConstraintExt(cert, - &critical, &constraint); + ret = kmf_get_cert_basic_constraint(cert, + &critical, &constraint); if (ret != KMF_OK) { /* real error */ @@ -1519,7 +1889,7 @@ cert_eku_check(KMF_HANDLE_T handle, KMF_DATA *cert) if (policy->eku_set.eku_count == 0) return (KMF_OK); - ret = KMF_GetCertEKU(cert, &eku); + ret = kmf_get_cert_eku(cert, &eku); if ((ret != KMF_ERR_EXTENSION_NOT_FOUND) && (ret != KMF_OK)) { /* real error */ return (ret); @@ -1596,58 +1966,61 @@ cert_eku_check(KMF_HANDLE_T handle, KMF_DATA *cert) } static KMF_RETURN -kmf_find_issuer_cert(KMF_HANDLE_T handle, - KMF_VALIDATECERT_PARAMS *params, - char *user_issuer, - KMF_DATA *issuer_cert) +find_issuer_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, + char *user_issuer, KMF_DATA *issuer_cert, + char *slotlabel, char *dirpath) { - KMF_RETURN ret = KMF_OK; - KMF_FINDCERT_PARAMS fc_target; - KMF_OPENSSL_PARAMS ssl_params; KMF_X509_DER_CERT *certlist = NULL; uint32_t i, num = 0; time_t t_notbefore; time_t t_notafter; time_t latest; KMF_DATA tmp_cert = {0, NULL}; + KMF_ATTRIBUTE fc_attrlist[16]; + int fc_numattr = 0; + char *dir = "./"; - if (handle == NULL || params == NULL || - user_issuer == NULL || issuer_cert == NULL) + if (handle == NULL || kstype == NULL || user_issuer == NULL || + issuer_cert == NULL) return (KMF_ERR_BAD_PARAMETER); - (void) memset(&fc_target, 0, sizeof (fc_target)); - (void) memset(&ssl_params, 0, sizeof (ssl_params)); + if (!VALID_KEYSTORE_TYPE(*kstype)) + return (KMF_ERR_BAD_PARAMETER); - fc_target.subject = user_issuer; + kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR, + kstype, sizeof (KMF_KEYSTORE_TYPE)); + fc_numattr++; - switch (params->kstype) { - case KMF_KEYSTORE_NSS: - fc_target.kstype = KMF_KEYSTORE_NSS; - fc_target.nssparms.slotlabel = params->nssparms.slotlabel; - break; + kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_SUBJECT_NAME_ATTR, + user_issuer, strlen(user_issuer)); + fc_numattr++; - case KMF_KEYSTORE_OPENSSL: - fc_target.kstype = KMF_KEYSTORE_OPENSSL; - /* setup dirpath to search for TA in a directory */ - if (params->sslparms.dirpath == NULL) { - ssl_params.dirpath = "./"; + if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) { + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel)); + fc_numattr++; + } + + if (*kstype == KMF_KEYSTORE_OPENSSL) { + if (dirpath == NULL) { + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_DIRPATH_ATTR, dir, strlen(dir)); + fc_numattr++; } else { - ssl_params.dirpath = params->sslparms.dirpath; + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); + fc_numattr++; } - ssl_params.certfile = NULL; - fc_target.sslparms = ssl_params; - break; - - case KMF_KEYSTORE_PK11TOKEN: - fc_target.kstype = KMF_KEYSTORE_PK11TOKEN; - break; - default: - return (KMF_ERR_PLUGIN_NOTFOUND); } num = 0; - ret = KMF_FindCert(handle, &fc_target, NULL, &num); + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_COUNT_ATTR, &num, sizeof (uint32_t)); + fc_numattr++; + + ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); + if (ret == KMF_OK && num > 0) { certlist = (KMF_X509_DER_CERT *)malloc(num * sizeof (KMF_X509_DER_CERT)); @@ -1657,10 +2030,12 @@ kmf_find_issuer_cert(KMF_HANDLE_T handle, goto out; } - (void) memset(certlist, 0, num * + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_X509_DER_CERT_ATTR, certlist, sizeof (KMF_X509_DER_CERT)); + fc_numattr++; - ret = KMF_FindCert(handle, &fc_target, certlist, &num); + ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); if (ret != KMF_OK) { free(certlist); certlist = NULL; @@ -1681,7 +2056,7 @@ kmf_find_issuer_cert(KMF_HANDLE_T handle, */ latest = 0; for (i = 0; i < num; i++) { - ret = KMF_GetCertValidity(&certlist[i].certificate, + ret = kmf_get_cert_validity(&certlist[i].certificate, &t_notbefore, &t_notafter); if (ret != KMF_OK) { ret = KMF_ERR_VALIDITY_PERIOD; @@ -1711,7 +2086,7 @@ kmf_find_issuer_cert(KMF_HANDLE_T handle, out: if (certlist != NULL) { for (i = 0; i < num; i++) - KMF_FreeKMFCert(handle, &certlist[i]); + kmf_free_kmf_cert(handle, &certlist[i]); free(certlist); } @@ -1720,16 +2095,12 @@ out: } static KMF_RETURN -kmf_find_ta_cert(KMF_HANDLE_T handle, - KMF_VALIDATECERT_PARAMS *params, - KMF_DATA *ta_cert, - KMF_X509_NAME *user_issuerDN) +find_ta_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, + KMF_DATA *ta_cert, KMF_X509_NAME *user_issuerDN, + char *slotlabel, char *dirpath) { - KMF_POLICY_RECORD *policy; KMF_RETURN ret = KMF_OK; - KMF_FINDCERT_PARAMS fc_target; - KMF_OPENSSL_PARAMS ssl_params; uint32_t num = 0; char *ta_name; KMF_BIGINT serial = { NULL, 0 }; @@ -1738,57 +2109,66 @@ kmf_find_ta_cert(KMF_HANDLE_T handle, KMF_X509_DER_CERT ta_retrCert; char *ta_subject = NULL; KMF_X509_NAME ta_subjectDN; + KMF_ATTRIBUTE fc_attrlist[16]; + int fc_numattr = 0; + char *dir = "./"; + + if (handle == NULL || kstype == NULL || ta_cert == NULL || + user_issuerDN == NULL) + return (KMF_ERR_BAD_PARAMETER); - if (handle == NULL || params == NULL || - ta_cert == NULL || user_issuerDN == NULL) + if (!VALID_KEYSTORE_TYPE(*kstype)) return (KMF_ERR_BAD_PARAMETER); + /* Get the TA name and serial number from the policy */ policy = handle->policy; ta_name = policy->ta_name; - - ret = KMF_HexString2Bytes((uchar_t *)policy->ta_serial, + ret = kmf_hexstr_to_bytes((uchar_t *)policy->ta_serial, &bytes, &bytelen); if (ret != KMF_OK || bytes == NULL) { ret = KMF_ERR_TA_POLICY; goto out; } - - (void) memset(&fc_target, 0, sizeof (fc_target)); - (void) memset(&ssl_params, 0, sizeof (ssl_params)); - serial.val = bytes; serial.len = bytelen; - fc_target.serial = &serial; - fc_target.subject = ta_name; - switch (params->kstype) { - case KMF_KEYSTORE_NSS: - fc_target.kstype = KMF_KEYSTORE_NSS; - fc_target.nssparms.slotlabel = params->nssparms.slotlabel; - break; + /* set up fc_attrlist for kmf_find_cert */ + kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR, + kstype, sizeof (KMF_KEYSTORE_TYPE)); + fc_numattr++; - case KMF_KEYSTORE_OPENSSL: - fc_target.kstype = KMF_KEYSTORE_OPENSSL; - /* setup dirpath to search for TA in a directory */ - if (params->sslparms.dirpath == NULL) { - ssl_params.dirpath = "./"; + kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_SUBJECT_NAME_ATTR, + ta_name, strlen(ta_name)); + fc_numattr++; + + kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_BIGINT_ATTR, + &serial, sizeof (KMF_BIGINT)); + fc_numattr++; + + if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) { + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel)); + fc_numattr++; + } + + if (*kstype == KMF_KEYSTORE_OPENSSL) { + if (dirpath == NULL) { + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_DIRPATH_ATTR, dir, strlen(dir)); + fc_numattr++; } else { - ssl_params.dirpath = params->sslparms.dirpath; + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); + fc_numattr++; } - ssl_params.certfile = NULL; - fc_target.sslparms = ssl_params; - break; - - case KMF_KEYSTORE_PK11TOKEN: - fc_target.kstype = KMF_KEYSTORE_PK11TOKEN; - break; - default: - ret = KMF_ERR_PLUGIN_NOTFOUND; - goto out; } num = 0; - ret = KMF_FindCert(handle, &fc_target, NULL, &num); + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_COUNT_ATTR, &num, sizeof (uint32_t)); + fc_numattr++; + + ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); if (ret != KMF_OK || num != 1) { if (num == 0) ret = KMF_ERR_CERT_NOT_FOUND; @@ -1797,9 +2177,11 @@ kmf_find_ta_cert(KMF_HANDLE_T handle, goto out; } - (void) memset(&ta_retrCert, 0, sizeof (KMF_X509_DER_CERT)); + kmf_set_attr_at_index(fc_attrlist, fc_numattr, + KMF_X509_DER_CERT_ATTR, &ta_retrCert, sizeof (KMF_X509_DER_CERT)); + fc_numattr++; - ret = KMF_FindCert(handle, &fc_target, &ta_retrCert, &num); + ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); if (ret == KMF_OK) { ta_cert->Length = ta_retrCert.certificate.Length; ta_cert->Data = malloc(ta_retrCert.certificate.Length); @@ -1819,25 +2201,25 @@ kmf_find_ta_cert(KMF_HANDLE_T handle, */ (void) memset(&ta_subjectDN, 0, sizeof (ta_subjectDN)); - ret = KMF_GetCertSubjectNameString(handle, ta_cert, &ta_subject); + ret = kmf_get_cert_subject_str(handle, ta_cert, &ta_subject); if (ret != KMF_OK) goto out; - ret = KMF_DNParser(ta_subject, &ta_subjectDN); + ret = kmf_dn_parser(ta_subject, &ta_subjectDN); if (ret != KMF_OK) goto out; - if (KMF_CompareRDNs(user_issuerDN, &ta_subjectDN) != 0) + if (kmf_compare_rdns(user_issuerDN, &ta_subjectDN) != 0) ret = KMF_ERR_CERT_NOT_FOUND; - KMF_FreeDN(&ta_subjectDN); + kmf_free_dn(&ta_subjectDN); /* Make sure the TA cert has the correct extensions */ if (ret == KMF_OK) ret = check_key_usage(handle, ta_cert, KMF_KU_SIGN_CERT); out: if (ta_retrCert.certificate.Data) - KMF_FreeKMFCert(handle, &ta_retrCert); + kmf_free_kmf_cert(handle, &ta_retrCert); if ((ret != KMF_OK) && (ta_cert->Data != NULL)) free(ta_cert->Data); @@ -1852,12 +2234,15 @@ out: } KMF_RETURN -KMF_ValidateCert(KMF_HANDLE_T handle, - KMF_VALIDATECERT_PARAMS *params, - int *result) +kmf_validate_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; + KMF_KEYSTORE_TYPE *kstype = NULL; KMF_DATA *pcert = NULL; + int *result = NULL; + char *slotlabel = NULL; + char *dirpath = NULL; + KMF_DATA *ocsp_response = NULL; KMF_DATA ta_cert = {0, NULL}; KMF_DATA issuer_cert = {0, NULL}; char *user_issuer = NULL, *user_subject = NULL; @@ -1865,27 +2250,51 @@ KMF_ValidateCert(KMF_HANDLE_T handle, boolean_t self_signed = B_FALSE; KMF_POLICY_RECORD *policy; + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, + {KMF_VALIDATE_RESULT_ATTR, FALSE, 1, sizeof (int)} + }; + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); + CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); if (ret != KMF_OK) return (ret); - if (params == NULL || params->certificate == NULL || result == NULL) + policy = handle->policy; + + /* Get the attribute values */ + kstype = kmf_get_attr_ptr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr); + pcert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + result = kmf_get_attr_ptr(KMF_VALIDATE_RESULT_ATTR, attrlist, numattr); + if (kstype == NULL || pcert == NULL || result == NULL) return (KMF_ERR_BAD_PARAMETER); - policy = handle->policy; + slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr); + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + ocsp_response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, attrlist, + numattr); + + /* Initialize the returned result */ *result = KMF_CERT_VALIDATE_OK; - pcert = params->certificate; /* * Get the issuer information from the input certficate first. */ - if ((ret = KMF_GetCertIssuerNameString(handle, pcert, + if ((ret = kmf_get_cert_issuer_str(handle, pcert, &user_issuer)) != KMF_OK) { *result |= KMF_CERT_VALIDATE_ERR_USER; goto out; } - if ((ret = KMF_DNParser(user_issuer, &user_issuerDN)) != KMF_OK) { + if ((ret = kmf_dn_parser(user_issuer, &user_issuerDN)) != KMF_OK) { *result |= KMF_CERT_VALIDATE_ERR_USER; goto out; } @@ -1893,27 +2302,27 @@ KMF_ValidateCert(KMF_HANDLE_T handle, /* * Check if the certificate is a self-signed cert. */ - if ((ret = KMF_GetCertSubjectNameString(handle, pcert, + if ((ret = kmf_get_cert_subject_str(handle, pcert, &user_subject)) != KMF_OK) { *result |= KMF_CERT_VALIDATE_ERR_USER; - KMF_FreeDN(&user_issuerDN); + kmf_free_dn(&user_issuerDN); goto out; } - if ((ret = KMF_DNParser(user_subject, &user_subjectDN)) != KMF_OK) { + if ((ret = kmf_dn_parser(user_subject, &user_subjectDN)) != KMF_OK) { *result |= KMF_CERT_VALIDATE_ERR_USER; - KMF_FreeDN(&user_issuerDN); + kmf_free_dn(&user_issuerDN); goto out; } - if ((KMF_CompareRDNs(&user_issuerDN, &user_subjectDN)) == 0) { + if ((kmf_compare_rdns(&user_issuerDN, &user_subjectDN)) == 0) { /* * this is a self-signed cert */ self_signed = B_TRUE; } - KMF_FreeDN(&user_subjectDN); + kmf_free_dn(&user_subjectDN); /* * Check KeyUsage extension of the subscriber's certificate @@ -1943,7 +2352,7 @@ KMF_ValidateCert(KMF_HANDLE_T handle, /* * Validate expiration date */ - ret = KMF_CheckCertDate(handle, pcert); + ret = kmf_check_cert_date(handle, pcert); if (ret != KMF_OK) { *result |= KMF_CERT_VALIDATE_ERR_TIME; goto out; @@ -1969,16 +2378,20 @@ KMF_ValidateCert(KMF_HANDLE_T handle, * TA certificate. */ if (self_signed) { - ret = KMF_VerifyCertWithCert(handle, pcert, pcert); + ret = verify_cert_with_cert(handle, pcert, pcert); } else { - ret = kmf_find_ta_cert(handle, params, &ta_cert, - &user_issuerDN); + ret = find_ta_cert(handle, kstype, &ta_cert, + &user_issuerDN, slotlabel, dirpath); if (ret != KMF_OK) { *result |= KMF_CERT_VALIDATE_ERR_TA; goto out; } - ret = KMF_VerifyCertWithCert(handle, pcert, &ta_cert); + ret = check_key_usage(handle, &ta_cert, KMF_KU_SIGN_CERT); + if (ret != KMF_OK) + goto out; + + ret = verify_cert_with_cert(handle, pcert, &ta_cert); } if (ret != KMF_OK) { *result |= KMF_CERT_VALIDATE_ERR_SIGNATURE; @@ -2006,16 +2419,15 @@ check_revocation: goto out; } - ret = kmf_find_issuer_cert(handle, params, user_issuer, - &issuer_cert); + ret = find_issuer_cert(handle, kstype, user_issuer, &issuer_cert, + slotlabel, dirpath); if (ret != KMF_OK) { *result |= KMF_CERT_VALIDATE_ERR_ISSUER; goto out; } if (policy->revocation & KMF_REVOCATION_METHOD_CRL) { - ret = cert_crl_check(handle, params, - pcert, &issuer_cert); + ret = cert_crl_check(handle, kstype, pcert, &issuer_cert); if (ret != KMF_OK) { *result |= KMF_CERT_VALIDATE_ERR_CRL; goto out; @@ -2023,16 +2435,17 @@ check_revocation: } if (policy->revocation & KMF_REVOCATION_METHOD_OCSP) { - ret = cert_ocsp_check(handle, params, - pcert, &issuer_cert, params->ocsp_response); + ret = cert_ocsp_check(handle, kstype, pcert, &issuer_cert, + ocsp_response, slotlabel, dirpath); if (ret != KMF_OK) { *result |= KMF_CERT_VALIDATE_ERR_OCSP; goto out; } } + out: if (user_issuer) { - KMF_FreeDN(&user_issuerDN); + kmf_free_dn(&user_issuerDN); free(user_issuer); } @@ -2050,7 +2463,7 @@ out: } KMF_RETURN -KMF_CreateCertFile(KMF_DATA *certdata, KMF_ENCODE_FORMAT format, +kmf_create_cert_file(const KMF_DATA *certdata, KMF_ENCODE_FORMAT format, char *certfile) { KMF_RETURN rv = KMF_OK; @@ -2065,27 +2478,27 @@ KMF_CreateCertFile(KMF_DATA *certdata, KMF_ENCODE_FORMAT format, if (format == KMF_FORMAT_PEM) { int len; - rv = KMF_Der2Pem(KMF_CERT, - certdata->Data, certdata->Length, - &pemdata.Data, &len); + rv = kmf_der_to_pem(KMF_CERT, + certdata->Data, certdata->Length, + &pemdata.Data, &len); if (rv != KMF_OK) goto cleanup; pemdata.Length = (size_t)len; } - if ((fd = open(certfile, O_CREAT |O_RDWR, 0644)) == -1) { + if ((fd = open(certfile, O_CREAT | O_RDWR | O_TRUNC, 0644)) == -1) { rv = KMF_ERR_OPEN_FILE; goto cleanup; } if (format == KMF_FORMAT_PEM) { if (write(fd, pemdata.Data, pemdata.Length) != - pemdata.Length) { + pemdata.Length) { rv = KMF_ERR_WRITE_FILE; } } else { if (write(fd, certdata->Data, certdata->Length) != - certdata->Length) { + certdata->Length) { rv = KMF_ERR_WRITE_FILE; } } @@ -2094,13 +2507,14 @@ cleanup: if (fd != -1) (void) close(fd); - KMF_FreeData(&pemdata); + kmf_free_data(&pemdata); return (rv); } KMF_RETURN -KMF_IsCertFile(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat) +kmf_is_cert_file(KMF_HANDLE_T handle, char *filename, + KMF_ENCODE_FORMAT *pformat) { KMF_PLUGIN *plugin; KMF_RETURN (*IsCertFileFn)(void *, char *, KMF_ENCODE_FORMAT *); @@ -2137,7 +2551,7 @@ KMF_IsCertFile(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat) * This function checks the validity period of a der-encoded certificate. */ KMF_RETURN -KMF_CheckCertDate(KMF_HANDLE_T handle, KMF_DATA *cert) +kmf_check_cert_date(KMF_HANDLE_T handle, const KMF_DATA *cert) { KMF_RETURN rv; struct tm *gmt; @@ -2151,12 +2565,11 @@ KMF_CheckCertDate(KMF_HANDLE_T handle, KMF_DATA *cert) if (rv != KMF_OK) return (rv); - if (cert == NULL || cert->Data == NULL || - cert->Length == 0) + if (cert == NULL || cert->Data == NULL || cert->Length == 0) return (KMF_ERR_BAD_PARAMETER); policy = handle->policy; - rv = KMF_GetCertValidity(cert, &t_notbefore, &t_notafter); + rv = kmf_get_cert_validity(cert, &t_notbefore, &t_notafter); if (rv != KMF_OK) return (rv); @@ -2191,187 +2604,96 @@ KMF_CheckCertDate(KMF_HANDLE_T handle, KMF_DATA *cert) } KMF_RETURN -KMF_ExportPK12(KMF_HANDLE_T handle, - KMF_EXPORTP12_PARAMS *params, - char *filename) +kmf_export_pk12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { - KMF_RETURN rv; KMF_PLUGIN *plugin; + KMF_RETURN ret = KMF_OK; KMF_KEYSTORE_TYPE kstype; - KMF_X509_DER_CERT *certlist = NULL; - KMF_KEY_HANDLE *keys = NULL; - uint32_t numkeys; - uint32_t numcerts; - int i; - CLEAR_ERROR(handle, rv); - if (rv != KMF_OK) - return (rv); + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_OUTPUT_FILENAME_ATTR, TRUE, 1, 0}, + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); - if (params == NULL || filename == NULL) + if (handle == NULL) return (KMF_ERR_BAD_PARAMETER); - kstype = params->kstype; - if (kstype == KMF_KEYSTORE_PK11TOKEN) { - KMF_FINDCERT_PARAMS fcargs; - (void) memset(&fcargs, 0, sizeof (fcargs)); + CLEAR_ERROR(handle, ret); - fcargs.kstype = kstype; - fcargs.certLabel = params->certLabel; - fcargs.issuer = params->issuer; - fcargs.subject = params->subject; - fcargs.serial = params->serial; - fcargs.idstr = params->idstr; + ret = test_attributes(num_req_attrs, required_attrs, 0, NULL, + numattr, attrlist); + if (ret != KMF_OK) + return (ret); - /* - * Special processing because PKCS11 doesn't have - * a native PKCS12 operation. - */ - rv = KMF_FindCert(handle, &fcargs, NULL, &numcerts); - if (rv == KMF_OK && numcerts > 0) { - certlist = (KMF_X509_DER_CERT *)malloc(numcerts * - sizeof (KMF_X509_DER_CERT)); - if (certlist == NULL) - return (KMF_ERR_MEMORY); - (void) memset(certlist, 0, numcerts * - sizeof (KMF_X509_DER_CERT)); - rv = KMF_FindCert(handle, &fcargs, - certlist, &numcerts); - if (rv != KMF_OK) { - free(certlist); - return (rv); - } - } else { - return (rv); - } + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, + &kstype, NULL); + if (ret != KMF_OK) + return (ret); - numkeys = 0; - for (i = 0; i < numcerts; i++) { - KMF_CRYPTOWITHCERT_PARAMS fkparms; - KMF_KEY_HANDLE newkey; - - fkparms.kstype = kstype; - fkparms.format = KMF_FORMAT_RAWKEY; - fkparms.cred = params->cred; - fkparms.certLabel = certlist[i].kmf_private.label; - - rv = find_private_key_by_cert(handle, &fkparms, - &certlist[i].certificate, &newkey); - if (rv == KMF_OK) { - numkeys++; - keys = realloc(keys, - numkeys * sizeof (KMF_KEY_HANDLE)); - if (keys == NULL) { - free(certlist); - rv = KMF_ERR_MEMORY; - goto out; - } - keys[numkeys - 1] = newkey; - } else if (rv == KMF_ERR_KEY_NOT_FOUND) { - /* it is OK if a key is not found */ - rv = KMF_OK; - } - } - if (rv == KMF_OK) { - /* - * Switch the keystore type to use OpenSSL for - * exporting the raw cert and key data as PKCS12. - */ - kstype = KMF_KEYSTORE_OPENSSL; - } else { - rv = KMF_ERR_KEY_NOT_FOUND; - goto out; - } - } plugin = FindPlugin(handle, kstype); - if (plugin != NULL && plugin->funclist->ExportP12 != NULL) { - rv = plugin->funclist->ExportP12(handle, - params, numcerts, certlist, - numkeys, keys, filename); - } else { - rv = KMF_ERR_PLUGIN_NOTFOUND; - } - -out: - if (certlist != NULL) { - for (i = 0; i < numcerts; i++) - KMF_FreeKMFCert(handle, &certlist[i]); - free(certlist); - } - if (keys != NULL) { - for (i = 0; i < numkeys; i++) - KMF_FreeKMFKey(handle, &keys[i]); - free(keys); - } + if (plugin == NULL || plugin->funclist->ExportPK12 == NULL) + return (KMF_ERR_PLUGIN_NOTFOUND); - return (rv); + return (plugin->funclist->ExportPK12(handle, numattr, attrlist)); } + KMF_RETURN -KMF_ImportPK12(KMF_HANDLE_T handle, char *filename, - KMF_CREDENTIAL *cred, - KMF_DATA **certs, int *ncerts, - KMF_RAW_KEY_DATA **rawkeys, int *nkeys) +kmf_build_pk12(KMF_HANDLE_T handle, int numcerts, + KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist, + KMF_CREDENTIAL *p12cred, char *filename) { KMF_RETURN rv; KMF_PLUGIN *plugin; - KMF_RETURN (*openpkcs12)(KMF_HANDLE *, - char *, KMF_CREDENTIAL *, - KMF_DATA **, int *, - KMF_RAW_KEY_DATA **, int *); + KMF_RETURN (*buildpk12)(KMF_HANDLE *, int, KMF_X509_DER_CERT *, + int, KMF_KEY_HANDLE *, KMF_CREDENTIAL *, char *); CLEAR_ERROR(handle, rv); if (rv != KMF_OK) return (rv); - if (filename == NULL || - cred == NULL || - certs == NULL || ncerts == NULL || - rawkeys == NULL || nkeys == NULL) + if (filename == NULL || p12cred == NULL || + (certlist == NULL && keylist == NULL)) return (KMF_ERR_BAD_PARAMETER); - /* - * Use the pkcs12 reader from the OpenSSL plugin. - */ plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); if (plugin == NULL || plugin->dldesc == NULL) { return (KMF_ERR_PLUGIN_NOTFOUND); } - openpkcs12 = (KMF_RETURN(*)())dlsym(plugin->dldesc, - "openssl_read_pkcs12"); - if (openpkcs12 == NULL) { + buildpk12 = (KMF_RETURN(*)())dlsym(plugin->dldesc, + "openssl_build_pk12"); + if (buildpk12 == NULL) { return (KMF_ERR_FUNCTION_NOT_FOUND); } - /* Use OpenSSL interfaces to get raw key and cert data */ - rv = openpkcs12(handle, filename, cred, certs, ncerts, - rawkeys, nkeys); + rv = buildpk12(handle, numcerts, certlist, numkeys, keylist, p12cred, + filename); return (rv); } + KMF_RETURN -KMF_ImportKeypair(KMF_HANDLE_T handle, char *filename, +kmf_import_objects(KMF_HANDLE_T handle, char *filename, KMF_CREDENTIAL *cred, KMF_DATA **certs, int *ncerts, KMF_RAW_KEY_DATA **rawkeys, int *nkeys) { KMF_RETURN rv; KMF_PLUGIN *plugin; - KMF_RETURN (*import_keypair)(KMF_HANDLE *, - char *, KMF_CREDENTIAL *, - KMF_DATA **, int *, - KMF_RAW_KEY_DATA **, int *); + KMF_RETURN (*import_objects)(KMF_HANDLE *, char *, KMF_CREDENTIAL *, + KMF_DATA **, int *, KMF_RAW_KEY_DATA **, int *); CLEAR_ERROR(handle, rv); if (rv != KMF_OK) return (rv); - if (filename == NULL || - cred == NULL || - certs == NULL || ncerts == NULL || - rawkeys == NULL || nkeys == NULL) + if (filename == NULL || cred == NULL || certs == NULL || + ncerts == NULL ||rawkeys == NULL || nkeys == NULL) return (KMF_ERR_BAD_PARAMETER); /* @@ -2382,15 +2704,15 @@ KMF_ImportKeypair(KMF_HANDLE_T handle, char *filename, return (KMF_ERR_PLUGIN_NOTFOUND); } - import_keypair = (KMF_RETURN(*)())dlsym(plugin->dldesc, - "openssl_import_keypair"); - if (import_keypair == NULL) { + import_objects = (KMF_RETURN(*)())dlsym(plugin->dldesc, + "openssl_import_objects"); + if (import_objects == NULL) { return (KMF_ERR_FUNCTION_NOT_FOUND); } /* Use OpenSSL interfaces to get raw key and cert data */ - rv = import_keypair(handle, filename, cred, certs, ncerts, - rawkeys, nkeys); + rv = import_objects(handle, filename, cred, certs, ncerts, + rawkeys, nkeys); return (rv); } @@ -2402,7 +2724,7 @@ IsEqualOid(KMF_OID *Oid1, KMF_OID *Oid2) !memcmp(Oid1->Data, Oid2->Data, Oid1->Length)); } -static KMF_RETURN +KMF_RETURN copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid, KMF_X509_ALGORITHM_IDENTIFIER *srcid) { @@ -2416,7 +2738,7 @@ copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid, return (KMF_ERR_MEMORY); (void) memcpy(destid->algorithm.Data, srcid->algorithm.Data, - destid->algorithm.Length); + destid->algorithm.Length); destid->parameters.Length = srcid->parameters.Length; if (destid->parameters.Length > 0) { @@ -2425,7 +2747,7 @@ copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid, return (KMF_ERR_MEMORY); (void) memcpy(destid->parameters.Data, srcid->parameters.Data, - destid->parameters.Length); + destid->parameters.Length); } else { destid->parameters.Data = NULL; } @@ -2433,7 +2755,7 @@ copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid, } static KMF_RETURN -SignCert(KMF_HANDLE_T handle, +sign_cert(KMF_HANDLE_T handle, const KMF_DATA *SubjectCert, KMF_KEY_HANDLE *Signkey, KMF_DATA *SignedCert) @@ -2443,6 +2765,9 @@ SignCert(KMF_HANDLE_T handle, KMF_DATA signed_data = {0, NULL}; KMF_RETURN ret = KMF_OK; KMF_ALGORITHM_INDEX algid; + int i = 0; + KMF_ATTRIBUTE attrlist[8]; + KMF_OID *oid; if (!SignedCert) return (KMF_ERR_BAD_PARAMETER); @@ -2451,7 +2776,7 @@ SignCert(KMF_HANDLE_T handle, SignedCert->Data = NULL; if (!SubjectCert) - return (KMF_ERR_BAD_PARAMETER); + return (KMF_ERR_BAD_PARAMETER); if (!SubjectCert->Data || !SubjectCert->Length) return (KMF_ERR_BAD_PARAMETER); @@ -2462,7 +2787,7 @@ SignCert(KMF_HANDLE_T handle, * there is no need to re-encode it. */ ret = ExtractX509CertParts((KMF_DATA *)SubjectCert, - &data_to_sign, NULL); + &data_to_sign, NULL); if (ret != KMF_OK) { goto cleanup; } @@ -2486,23 +2811,38 @@ SignCert(KMF_HANDLE_T handle, /* We are re-signing this cert, so clear out old signature data */ if (subj_cert->signature.algorithmIdentifier.algorithm.Length == 0) { - KMF_FreeAlgOID(&subj_cert->signature.algorithmIdentifier); + kmf_free_algoid(&subj_cert->signature.algorithmIdentifier); ret = copy_algoid(&subj_cert->signature.algorithmIdentifier, - &subj_cert->certificate.signature); + &subj_cert->certificate.signature); } if (ret) goto cleanup; + kmf_set_attr_at_index(attrlist, i, KMF_KEYSTORE_TYPE_ATTR, + &Signkey->kstype, sizeof (KMF_KEYSTORE_TYPE)); + i++; + kmf_set_attr_at_index(attrlist, i, KMF_KEY_HANDLE_ATTR, + Signkey, sizeof (KMF_KEY_HANDLE)); + i++; + kmf_set_attr_at_index(attrlist, i, KMF_DATA_ATTR, + &data_to_sign, sizeof (KMF_DATA)); + i++; + kmf_set_attr_at_index(attrlist, i, KMF_OUT_DATA_ATTR, + &signed_data, sizeof (KMF_DATA)); + i++; + oid = CERT_ALG_OID(subj_cert); + kmf_set_attr_at_index(attrlist, i, KMF_OID_ATTR, + oid, sizeof (KMF_OID)); + i++; + /* Sign the data */ - ret = KMF_SignDataWithKey(handle, Signkey, - CERT_ALG_OID(subj_cert), - &data_to_sign, &signed_data); + ret = kmf_sign_data(handle, i, attrlist); if (ret != KMF_OK) goto cleanup; - algid = X509_AlgorithmOidToAlgId(CERT_SIG_OID(subj_cert)); + algid = x509_algoid_to_algid(CERT_SIG_OID(subj_cert)); /* * For DSA, KMF_SignDataWithKey() returns a 40-bytes decoded @@ -2513,7 +2853,7 @@ SignCert(KMF_HANDLE_T handle, KMF_DATA signature; ret = DerEncodeDSASignature(&signed_data, &signature); - KMF_FreeData(&signed_data); + kmf_free_data(&signed_data); if (ret != KMF_OK) goto cleanup; @@ -2529,12 +2869,12 @@ SignCert(KMF_HANDLE_T handle, cleanup: /* Cleanup & return */ if (ret != KMF_OK) - KMF_FreeData(SignedCert); + kmf_free_data(SignedCert); - KMF_FreeData(&data_to_sign); + kmf_free_data(&data_to_sign); if (subj_cert != NULL) { - KMF_FreeSignedCert(subj_cert); + kmf_free_signed_cert(subj_cert); free(subj_cert); } @@ -2542,7 +2882,7 @@ cleanup: } static KMF_RETURN -VerifyCertWithKey(KMF_HANDLE_T handle, +verify_cert_with_key(KMF_HANDLE_T handle, KMF_DATA *derkey, const KMF_DATA *CertToBeVerified) { @@ -2556,13 +2896,13 @@ VerifyCertWithKey(KMF_HANDLE_T handle, /* check the caller and do other setup for this SPI call */ if (handle == NULL || CertToBeVerified == NULL || - derkey == NULL || derkey->Data == NULL) + derkey == NULL || derkey->Data == NULL) return (KMF_ERR_BAD_PARAMETER); (void) memset(&spki, 0, sizeof (KMF_X509_SPKI)); ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerified, - &data_to_verify, &signed_data); + &data_to_verify, &signed_data); if (ret != KMF_OK) goto cleanup; @@ -2576,7 +2916,7 @@ VerifyCertWithKey(KMF_HANDLE_T handle, if (ret != KMF_OK) return (ret); - algid = X509_AlgorithmOidToAlgId(CERT_SIG_OID(signed_cert)); + algid = x509_algoid_to_algid(CERT_SIG_OID(signed_cert)); if (algid == KMF_ALGID_NONE) return (KMF_ERR_BAD_ALGORITHM); @@ -2591,7 +2931,7 @@ VerifyCertWithKey(KMF_HANDLE_T handle, } ret = PKCS_VerifyData(handle, algid, &spki, - &data_to_verify, &signature); + &data_to_verify, &signature); cleanup: if (data_to_verify.Data != NULL) @@ -2601,50 +2941,27 @@ cleanup: free(signed_data.Data); if (signed_cert) { - KMF_FreeSignedCert(signed_cert); + kmf_free_signed_cert(signed_cert); free(signed_cert); } if (algid == KMF_ALGID_SHA1WithDSA) { free(signature.Data); } - KMF_FreeAlgOID(&spki.algorithm); - KMF_FreeData(&spki.subjectPublicKey); + kmf_free_algoid(&spki.algorithm); + kmf_free_data(&spki.subjectPublicKey); return (ret); } /* - * The key must be an ASN.1/DER encoded PKCS#1 key. + * Use a signer cert to verify another certificate's signature. + * This code forces the use of the OPENSSL mechanism + * for the verify operation to avoid a circular dependency + * with libelfsign when it attempts to verify the PKCS#11 libraries. */ -KMF_RETURN -VerifyDataWithKey(KMF_HANDLE_T handle, - KMF_DATA *derkey, - KMF_ALGORITHM_INDEX sigAlg, - KMF_DATA *indata, - KMF_DATA *insig) -{ - KMF_RETURN ret = KMF_OK; - KMF_X509_SPKI spki; - - if (!indata || !insig || !derkey || !derkey->Data) - return (KMF_ERR_BAD_PARAMETER); - - ret = DerDecodeSPKI(derkey, &spki); - if (ret != KMF_OK) - goto cleanup; - - ret = PKCS_VerifyData(handle, sigAlg, &spki, indata, insig); - -cleanup: - KMF_FreeAlgOID(&spki.algorithm); - KMF_FreeData(&spki.subjectPublicKey); - - return (ret); -} - static KMF_RETURN -VerifyCertWithCert(KMF_HANDLE_T handle, +verify_cert_with_cert(KMF_HANDLE_T handle, const KMF_DATA *CertToBeVerifiedData, const KMF_DATA *SignerCertData) { @@ -2666,9 +2983,14 @@ VerifyCertWithCert(KMF_HANDLE_T handle, !SignerCertData->Length) return (KMF_ERR_BAD_PARAMETER); + /* Make sure the signer has proper key usage bits */ + ret = check_key_usage(handle, SignerCertData, KMF_KU_SIGN_CERT); + if (ret != KMF_OK) + return (ret); + /* Decode the cert into parts for verification */ ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerifiedData, - &data_to_verify, &signed_data); + &data_to_verify, &signed_data); if (ret != KMF_OK) goto cleanup; @@ -2679,7 +3001,7 @@ VerifyCertWithCert(KMF_HANDLE_T handle, if (ret != KMF_OK) goto cleanup; - algid = X509_AlgorithmOidToAlgId(CERT_SIG_OID(ToBeVerifiedCert)); + algid = x509_algoid_to_algid(CERT_SIG_OID(ToBeVerifiedCert)); if (algid == KMF_ALGID_SHA1WithDSA) { ret = DerDecodeDSASignature(&signed_data, &signature); @@ -2690,32 +3012,25 @@ VerifyCertWithCert(KMF_HANDLE_T handle, signature.Length = signed_data.Length; } - /* Make sure the signer has proper key usage bits */ - ret = check_key_usage(handle, SignerCertData, KMF_KU_SIGN_CERT); - if (ret != KMF_OK) - return (ret); - /* * To avoid recursion with kcfd consumer and libpkcs11, - * do the data verification using the OpenSSL + * do the certificate verification using the OpenSSL * plugin algorithms instead of the crypto framework. */ - ret = plugin_verify_data_with_cert(handle, - KMF_KEYSTORE_OPENSSL, - algid, &data_to_verify, &signature, - SignerCertData); + ret = plugin_verify_data_with_cert(handle, KMF_KEYSTORE_OPENSSL, + algid, &data_to_verify, &signature, SignerCertData); cleanup: - KMF_FreeData(&data_to_verify); - KMF_FreeData(&signed_data); + kmf_free_data(&data_to_verify); + kmf_free_data(&signed_data); if (SignerCert) { - KMF_FreeSignedCert(SignerCert); + kmf_free_signed_cert(SignerCert); free(SignerCert); } if (ToBeVerifiedCert) { - KMF_FreeSignedCert(ToBeVerifiedCert); + kmf_free_signed_cert(ToBeVerifiedCert); free(ToBeVerifiedCert); } @@ -2726,78 +3041,158 @@ cleanup: return (ret); } +/* + * Phase 1 APIs still needed to maintain compat with elfsign. + */ KMF_RETURN -SignCsr(KMF_HANDLE_T handle, - const KMF_DATA *SubjectCsr, - KMF_KEY_HANDLE *Signkey, - KMF_X509_ALGORITHM_IDENTIFIER *algo, - KMF_DATA *SignedCsr) +KMF_VerifyDataWithCert(KMF_HANDLE_T handle, + KMF_KEYSTORE_TYPE kstype, + KMF_ALGORITHM_INDEX algid, + KMF_DATA *indata, + KMF_DATA *insig, + const KMF_DATA *SignerCert) { + KMF_ATTRIBUTE attrlist[8]; + int numattr = 0; - KMF_CSR_DATA subj_csr; - KMF_TBS_CSR *tbs_csr = NULL; - KMF_DATA signed_data = {0, NULL}; - KMF_RETURN ret = KMF_OK; + kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, + &kstype, sizeof (kstype)); + numattr++; - if (!SignedCsr) - return (KMF_ERR_BAD_PARAMETER); + kmf_set_attr_at_index(attrlist, numattr, KMF_DATA_ATTR, + indata, sizeof (KMF_DATA)); + numattr++; - SignedCsr->Length = 0; - SignedCsr->Data = NULL; + kmf_set_attr_at_index(attrlist, numattr, KMF_IN_SIGN_ATTR, + insig, sizeof (KMF_DATA)); + numattr++; - if (!SubjectCsr) - return (KMF_ERR_BAD_PARAMETER); + kmf_set_attr_at_index(attrlist, numattr, KMF_SIGNER_CERT_DATA_ATTR, + (KMF_DATA *)SignerCert, sizeof (KMF_DATA)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR, + &algid, sizeof (algid)); + numattr++; + + return (kmf_verify_data(handle, numattr, attrlist)); +} - if (!SubjectCsr->Data || !SubjectCsr->Length) +KMF_RETURN +KMF_VerifyCertWithCert(KMF_HANDLE_T handle, + const KMF_DATA *CertToBeVerified, + const KMF_DATA *SignerCert) +{ + KMF_RETURN ret; + if (CertToBeVerified == NULL || SignerCert == NULL) return (KMF_ERR_BAD_PARAMETER); - (void) memset(&subj_csr, 0, sizeof (subj_csr)); - /* Estimate the signed data length generously */ - signed_data.Length = SubjectCsr->Length*2; - signed_data.Data = calloc(1, signed_data.Length); - if (!signed_data.Data) { - ret = KMF_ERR_MEMORY; - goto cleanup; - } + /* check the keyUsage of signer's certificate */ + ret = check_key_usage(handle, SignerCert, KMF_KU_SIGN_CERT); + if (ret != KMF_OK) + return (ret); - /* Sign the data */ - ret = KMF_SignDataWithKey(handle, Signkey, &algo->algorithm, - (KMF_DATA *)SubjectCsr, &signed_data); + return (verify_cert_with_cert(handle, CertToBeVerified, + SignerCert)); +} - if (KMF_OK != ret) - goto cleanup; +KMF_RETURN +KMF_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *target, + KMF_X509_DER_CERT *kmf_cert, + uint32_t *num_certs) +{ + KMF_ATTRIBUTE attrlist[32]; + int i = 0; - /* - * If we got here OK, decode into a structure and then re-encode - * the complete CSR. - */ - ret = DerDecodeTbsCsr(SubjectCsr, &tbs_csr); - if (ret) - goto cleanup; + if (target == NULL || num_certs == NULL) + return (KMF_ERR_BAD_PARAMETER); /* ILLEGAL ARGS ERROR */ - (void) memcpy(&subj_csr.csr, tbs_csr, sizeof (KMF_TBS_CSR)); + if ((target->find_cert_validity < KMF_ALL_CERTS) || + (target->find_cert_validity > KMF_EXPIRED_CERTS)) + return (KMF_ERR_BAD_PARAMETER); - ret = copy_algoid(&subj_csr.signature.algorithmIdentifier, algo); - if (ret) - goto cleanup; + kmf_set_attr_at_index(attrlist, i, + KMF_KEYSTORE_TYPE_ATTR, &target->kstype, sizeof (target->kstype)); + i++; - subj_csr.signature.encrypted = signed_data; + if (kmf_cert != NULL) { + kmf_set_attr_at_index(attrlist, i, + KMF_X509_DER_CERT_ATTR, kmf_cert, + sizeof (KMF_X509_DER_CERT)); + i++; + } - /* Now, re-encode the CSR with the new signature */ - ret = DerEncodeSignedCsr(&subj_csr, SignedCsr); - if (ret != KMF_OK) { - KMF_FreeData(SignedCsr); - goto cleanup; + kmf_set_attr_at_index(attrlist, i, + KMF_COUNT_ATTR, num_certs, sizeof (uint32_t)); + i++; + + /* Set the optional searching attributes for all 3 plugins. */ + if (target->issuer != NULL) { + kmf_set_attr_at_index(attrlist, i, KMF_ISSUER_NAME_ATTR, + target->issuer, strlen(target->issuer)); + i++; + } + if (target->subject != NULL) { + kmf_set_attr_at_index(attrlist, i, KMF_SUBJECT_NAME_ATTR, + target->subject, strlen(target->subject)); + i++; + } + if (target->serial != NULL) { + kmf_set_attr_at_index(attrlist, i, KMF_BIGINT_ATTR, + target->serial, sizeof (KMF_BIGINT)); + i++; } - /* Cleanup & return */ -cleanup: - free(tbs_csr); + kmf_set_attr_at_index(attrlist, i, KMF_CERT_VALIDITY_ATTR, + &target->find_cert_validity, sizeof (KMF_CERT_VALIDITY)); + i++; + + if (target->kstype == KMF_KEYSTORE_NSS) { + if (target->certLabel != NULL) { + kmf_set_attr_at_index(attrlist, i, + KMF_CERT_LABEL_ATTR, + target->certLabel, strlen(target->certLabel)); + i++; + } - KMF_FreeTBSCSR(&subj_csr.csr); + if (target->nssparms.slotlabel != NULL) { + kmf_set_attr_at_index(attrlist, i, + KMF_TOKEN_LABEL_ATTR, + target->nssparms.slotlabel, + strlen(target->nssparms.slotlabel)); + i++; + } - KMF_FreeAlgOID(&subj_csr.signature.algorithmIdentifier); - KMF_FreeData(&signed_data); + } else if (target->kstype == KMF_KEYSTORE_OPENSSL) { + if (target->sslparms.certfile != NULL) { + kmf_set_attr_at_index(attrlist, i, + KMF_CERT_FILENAME_ATTR, + target->sslparms.certfile, + strlen(target->sslparms.certfile)); + i++; + } - return (ret); + if (target->sslparms.dirpath != NULL) { + kmf_set_attr_at_index(attrlist, i, + KMF_DIRPATH_ATTR, + target->sslparms.dirpath, + strlen(target->sslparms.dirpath)); + i++; + } + + } else if (target->kstype == KMF_KEYSTORE_PK11TOKEN) { + if (target->certLabel != NULL) { + kmf_set_attr_at_index(attrlist, i, + KMF_CERT_LABEL_ATTR, + target->certLabel, strlen(target->certLabel)); + i++; + } + + kmf_set_attr_at_index(attrlist, i, KMF_PRIVATE_BOOL_ATTR, + &target->pkcs11parms.private, + sizeof (target->pkcs11parms.private)); + i++; + } + + return (kmf_find_cert(handle, i, attrlist)); } diff --git a/usr/src/lib/libkmf/libkmf/common/client.c b/usr/src/lib/libkmf/libkmf/common/client.c index 15c158312e..d82381722c 100644 --- a/usr/src/lib/libkmf/libkmf/common/client.c +++ b/usr/src/lib/libkmf/libkmf/common/client.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * File: CLIENT.C @@ -72,7 +72,7 @@ static int init_socket(char *host, short port) sin.sin_port = htons(port); if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) { if ((hp = gethostbyname_r(host, &hrec, hostbuf, - sizeof (hostbuf), &herrno)) == NULL) { + sizeof (hostbuf), &herrno)) == NULL) { return (-1); } (void) memcpy((char *)&sin.sin_addr, hp->h_addr, @@ -478,7 +478,8 @@ out: } KMF_RETURN -KMF_GetEncodedOCSPResponse(KMF_HANDLE_T handle, char *reqfile, char *hostname, +kmf_get_encoded_ocsp_response(KMF_HANDLE_T handle, + char *reqfile, char *hostname, int port, char *proxy, int proxy_port, char *respfile, unsigned int maxsecs) { @@ -532,7 +533,7 @@ KMF_GetEncodedOCSPResponse(KMF_HANDLE_T handle, char *reqfile, char *hostname, ret = KMF_ERR_OPEN_FILE; } else { ret = get_encoded_response(sock, KMF_RESPONSE_OCSP, - respfd, maxsecs); + respfd, maxsecs); (void) close(respfd); } @@ -622,7 +623,7 @@ download_file(char *uri, char *proxy, int proxy_port, /* Connect to server */ if (proxy != NULL) { final_proxy_port = (proxy_port == 0 || proxy_port == -1) ? - 80 : proxy_port; + 80 : proxy_port; is_proxy = B_TRUE; sock = connect_to_server(proxy, final_proxy_port); } else { @@ -659,7 +660,7 @@ out: KMF_RETURN -KMF_DownloadCRL(KMF_HANDLE_T handle, char *uri, char *proxy, int proxy_port, +kmf_download_crl(KMF_HANDLE_T handle, char *uri, char *proxy, int proxy_port, unsigned int maxsecs, char *crlfile, KMF_ENCODE_FORMAT *pformat) { KMF_RETURN ret = KMF_OK; @@ -707,7 +708,7 @@ KMF_DownloadCRL(KMF_HANDLE_T handle, char *uri, char *proxy, int proxy_port, } /* Check if it is a CRL file and get its format */ - if (KMF_IsCRLFile(handle, tempfn, pformat) != KMF_OK) { + if (kmf_is_crl_file(handle, tempfn, pformat) != KMF_OK) { ret = KMF_ERR_BAD_CRLFILE; goto out; } @@ -733,7 +734,7 @@ out: KMF_RETURN -KMF_DownloadCert(KMF_HANDLE_T handle, char *uri, char *proxy, int proxy_port, +kmf_download_cert(KMF_HANDLE_T handle, char *uri, char *proxy, int proxy_port, unsigned int maxsecs, char *certfile, KMF_ENCODE_FORMAT *pformat) { KMF_RETURN ret = KMF_OK; @@ -782,7 +783,7 @@ KMF_DownloadCert(KMF_HANDLE_T handle, char *uri, char *proxy, int proxy_port, } /* Check if it is a Cert file and get its format */ - if (KMF_IsCertFile(handle, tempfn, pformat) != KMF_OK) { + if (kmf_is_cert_file(handle, tempfn, pformat) != KMF_OK) { ret = KMF_ERR_BAD_CERTFILE; goto out; } @@ -807,14 +808,13 @@ out: } KMF_RETURN -KMF_GetOCSPForCert(KMF_HANDLE_T handle, +kmf_get_ocsp_for_cert(KMF_HANDLE_T handle, KMF_DATA *user_cert, KMF_DATA *ta_cert, KMF_DATA *response) { KMF_POLICY_RECORD *policy; KMF_RETURN ret = KMF_OK; - KMF_OCSPREQUEST_PARAMS req_params; char *hostname = NULL, *host_uri = NULL, *proxyname = NULL; char *proxy_port_s = NULL; int host_port = 0, proxy_port = 0; @@ -825,20 +825,28 @@ KMF_GetOCSPForCert(KMF_HANDLE_T handle, boolean_t found = B_FALSE; KMF_X509EXT_ACCESSDESC *access_info; xmlURIPtr uriptr = NULL; + KMF_ATTRIBUTE attrlist[10]; + int numattr = 0; CLEAR_ERROR(handle, ret); if (ret != KMF_OK) return (ret); - if (user_cert == NULL || - ta_cert == NULL || response == NULL) + if (user_cert == NULL || ta_cert == NULL || response == NULL) return (KMF_ERR_BAD_PARAMETER); policy = handle->policy; /* Create an OCSP request */ - req_params.issuer_cert = ta_cert; - req_params.user_cert = user_cert; + kmf_set_attr_at_index(attrlist, numattr, + KMF_ISSUER_CERT_DATA_ATTR, ta_cert, + sizeof (KMF_DATA)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_USER_CERT_DATA_ATTR, user_cert, + sizeof (KMF_DATA)); + numattr++; /* * Create temporary files to hold the OCSP request & response data. @@ -855,7 +863,12 @@ KMF_GetOCSPForCert(KMF_HANDLE_T handle, return (KMF_ERR_INTERNAL); } - ret = KMF_CreateOCSPRequest(handle, &req_params, ocsp_reqname); + kmf_set_attr_at_index(attrlist, numattr, + KMF_OCSP_REQUEST_FILENAME_ATTR, ocsp_respname, + strlen(ocsp_respname)); + numattr++; + + ret = kmf_create_ocsp_request(handle, numattr, attrlist); if (ret != KMF_OK) { goto out; } @@ -873,7 +886,7 @@ KMF_GetOCSPForCert(KMF_HANDLE_T handle, * Authority Information Access * thru OID_PKIX_AD_OCSP */ - ret = KMF_GetCertAuthInfoAccessExt(user_cert, &aia); + ret = kmf_get_cert_auth_info_access(user_cert, &aia); if (ret != KMF_OK) { goto out; } @@ -934,14 +947,14 @@ KMF_GetOCSPForCert(KMF_HANDLE_T handle, * Send the request to an OCSP responder and receive an * OCSP response. */ - ret = KMF_GetEncodedOCSPResponse(handle, ocsp_reqname, + ret = kmf_get_encoded_ocsp_response(handle, ocsp_reqname, hostname, host_port, proxyname, proxy_port, ocsp_respname, 30); if (ret != KMF_OK) { goto out; } - ret = KMF_ReadInputFile(handle, ocsp_respname, response); + ret = kmf_read_input_file(handle, ocsp_respname, response); out: (void) unlink(ocsp_reqname); diff --git a/usr/src/lib/libkmf/libkmf/common/csrcrlop.c b/usr/src/lib/libkmf/libkmf/common/csrcrlop.c index 1099f57c71..b0af23b27c 100644 --- a/usr/src/lib/libkmf/libkmf/common/csrcrlop.c +++ b/usr/src/lib/libkmf/libkmf/common/csrcrlop.c @@ -17,8 +17,7 @@ * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END - */ -/* + * * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -41,10 +40,12 @@ #include <libgen.h> #include <cryptoutil.h> +static KMF_RETURN +setup_crl_call(KMF_HANDLE_T, int, KMF_ATTRIBUTE *, KMF_PLUGIN **); /* * - * Name: KMF_SetCSRPubKey + * Name: kmf_set_csr_pubkey * * Description: * This function converts the specified plugin public key to SPKI form, @@ -64,11 +65,11 @@ * */ KMF_RETURN -KMF_SetCSRPubKey(KMF_HANDLE_T handle, +kmf_set_csr_pubkey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *KMFKey, KMF_CSR_DATA *Csr) { - KMF_RETURN ret = KMF_OK; + KMF_RETURN ret; KMF_X509_SPKI *spki_ptr; KMF_PLUGIN *plugin; KMF_DATA KeyData = {NULL, 0}; @@ -94,13 +95,13 @@ KMF_SetCSRPubKey(KMF_HANDLE_T handle, ret = DerDecodeSPKI(&KeyData, spki_ptr); - KMF_FreeData(&KeyData); + kmf_free_data(&KeyData); return (ret); } KMF_RETURN -KMF_SetCSRVersion(KMF_CSR_DATA *CsrData, uint32_t version) +kmf_set_csr_version(KMF_CSR_DATA *CsrData, uint32_t version) { if (CsrData == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -112,11 +113,11 @@ KMF_SetCSRVersion(KMF_CSR_DATA *CsrData, uint32_t version) if (version != 0 && version != 1 && version != 2) return (KMF_ERR_BAD_PARAMETER); return (set_integer(&CsrData->csr.version, (void *)&version, - sizeof (uint32_t))); + sizeof (uint32_t))); } KMF_RETURN -KMF_SetCSRSubjectName(KMF_CSR_DATA *CsrData, +kmf_set_csr_subject(KMF_CSR_DATA *CsrData, KMF_X509_NAME *subject_name_ptr) { KMF_RETURN rv = KMF_OK; @@ -132,9 +133,8 @@ KMF_SetCSRSubjectName(KMF_CSR_DATA *CsrData, } return (rv); } - KMF_RETURN -KMF_CreateCSRFile(KMF_DATA *csrdata, KMF_ENCODE_FORMAT format, +kmf_create_csr_file(KMF_DATA *csrdata, KMF_ENCODE_FORMAT format, char *csrfile) { KMF_RETURN rv = KMF_OK; @@ -149,9 +149,9 @@ KMF_CreateCSRFile(KMF_DATA *csrdata, KMF_ENCODE_FORMAT format, if (format == KMF_FORMAT_PEM) { int len; - rv = KMF_Der2Pem(KMF_CSR, - csrdata->Data, csrdata->Length, - &pemdata.Data, &len); + rv = kmf_der_to_pem(KMF_CSR, + csrdata->Data, csrdata->Length, + &pemdata.Data, &len); if (rv != KMF_OK) goto cleanup; pemdata.Length = (size_t)len; @@ -164,12 +164,12 @@ KMF_CreateCSRFile(KMF_DATA *csrdata, KMF_ENCODE_FORMAT format, if (format == KMF_FORMAT_PEM) { if (write(fd, pemdata.Data, pemdata.Length) != - pemdata.Length) { + pemdata.Length) { rv = KMF_ERR_WRITE_FILE; } } else { if (write(fd, csrdata->Data, csrdata->Length) != - csrdata->Length) { + csrdata->Length) { rv = KMF_ERR_WRITE_FILE; } } @@ -178,14 +178,13 @@ cleanup: if (fd != -1) (void) close(fd); - KMF_FreeData(&pemdata); + kmf_free_data(&pemdata); return (rv); } KMF_RETURN -KMF_SetCSRExtension(KMF_CSR_DATA *Csr, - KMF_X509_EXTENSION *extn) +kmf_set_csr_extn(KMF_CSR_DATA *Csr, KMF_X509_EXTENSION *extn) { KMF_RETURN ret = KMF_OK; KMF_X509_EXTENSIONS *exts; @@ -201,7 +200,7 @@ KMF_SetCSRExtension(KMF_CSR_DATA *Csr, } KMF_RETURN -KMF_SetCSRSignatureAlgorithm(KMF_CSR_DATA *CsrData, +kmf_set_csr_sig_alg(KMF_CSR_DATA *CsrData, KMF_ALGORITHM_INDEX sigAlg) { KMF_OID *alg; @@ -209,12 +208,12 @@ KMF_SetCSRSignatureAlgorithm(KMF_CSR_DATA *CsrData, if (CsrData == NULL) return (KMF_ERR_BAD_PARAMETER); - alg = X509_AlgIdToAlgorithmOid(sigAlg); + alg = x509_algid_to_algoid(sigAlg); if (alg != NULL) { (void) copy_data((KMF_DATA *) - &CsrData->signature.algorithmIdentifier.algorithm, - (KMF_DATA *)alg); + &CsrData->signature.algorithmIdentifier.algorithm, + (KMF_DATA *)alg); (void) copy_data( &CsrData->signature.algorithmIdentifier.parameters, &CsrData->csr.subjectPublicKeyInfo.algorithm.parameters); @@ -225,7 +224,7 @@ KMF_SetCSRSignatureAlgorithm(KMF_CSR_DATA *CsrData, } KMF_RETURN -KMF_SetCSRSubjectAltName(KMF_CSR_DATA *Csr, +kmf_set_csr_subject_altname(KMF_CSR_DATA *Csr, char *altname, int critical, KMF_GENERALNAMECHOICES alttype) { @@ -234,15 +233,15 @@ KMF_SetCSRSubjectAltName(KMF_CSR_DATA *Csr, if (Csr == NULL || altname == NULL) return (KMF_ERR_BAD_PARAMETER); - ret = KMF_SetAltName(&Csr->csr.extensions, - (KMF_OID *)&KMFOID_SubjectAltName, critical, alttype, - altname); + ret = kmf_set_altname(&Csr->csr.extensions, + (KMF_OID *)&KMFOID_SubjectAltName, critical, alttype, + altname); return (ret); } KMF_RETURN -KMF_SetCSRKeyUsage(KMF_CSR_DATA *CSRData, +kmf_set_csr_ku(KMF_CSR_DATA *CSRData, int critical, uint16_t kubits) { KMF_RETURN ret = KMF_OK; @@ -251,15 +250,90 @@ KMF_SetCSRKeyUsage(KMF_CSR_DATA *CSRData, return (KMF_ERR_BAD_PARAMETER); ret = set_key_usage_extension( - &CSRData->csr.extensions, - critical, kubits); + &CSRData->csr.extensions, critical, kubits); + + return (ret); +} + +static KMF_RETURN +SignCsr(KMF_HANDLE_T handle, + const KMF_DATA *SubjectCsr, + KMF_KEY_HANDLE *Signkey, + KMF_X509_ALGORITHM_IDENTIFIER *algo, + KMF_DATA *SignedCsr) +{ + + KMF_CSR_DATA subj_csr; + KMF_TBS_CSR *tbs_csr = NULL; + KMF_DATA signed_data = {0, NULL}; + KMF_RETURN ret = KMF_OK; + + if (!SignedCsr) + return (KMF_ERR_BAD_PARAMETER); + + SignedCsr->Length = 0; + SignedCsr->Data = NULL; + + if (!SubjectCsr) + return (KMF_ERR_BAD_PARAMETER); + + if (!SubjectCsr->Data || !SubjectCsr->Length) + return (KMF_ERR_BAD_PARAMETER); + + (void) memset(&subj_csr, 0, sizeof (subj_csr)); + /* Estimate the signed data length generously */ + signed_data.Length = SubjectCsr->Length*2; + signed_data.Data = calloc(1, signed_data.Length); + if (!signed_data.Data) { + ret = KMF_ERR_MEMORY; + goto cleanup; + } + + /* Sign the data */ + ret = KMF_SignDataWithKey(handle, Signkey, &algo->algorithm, + (KMF_DATA *)SubjectCsr, &signed_data); + + if (KMF_OK != ret) + goto cleanup; + + /* + * If we got here OK, decode into a structure and then re-encode + * the complete CSR. + */ + ret = DerDecodeTbsCsr(SubjectCsr, &tbs_csr); + if (ret) + goto cleanup; + + (void) memcpy(&subj_csr.csr, tbs_csr, sizeof (KMF_TBS_CSR)); + + ret = copy_algoid(&subj_csr.signature.algorithmIdentifier, algo); + if (ret) + goto cleanup; + + subj_csr.signature.encrypted = signed_data; + + /* Now, re-encode the CSR with the new signature */ + ret = DerEncodeSignedCsr(&subj_csr, SignedCsr); + if (ret != KMF_OK) { + kmf_free_data(SignedCsr); + goto cleanup; + } + + /* Cleanup & return */ +cleanup: + free(tbs_csr); + + kmf_free_tbs_csr(&subj_csr.csr); + + kmf_free_algoid(&subj_csr.signature.algorithmIdentifier); + kmf_free_data(&signed_data); return (ret); } /* * - * Name: KMF_SignCSR + * Name: kmf_sign_csr * * Description: * This function signs a CSR and returns the result as a @@ -282,7 +356,7 @@ KMF_SetCSRKeyUsage(KMF_CSR_DATA *CSRData, * */ KMF_RETURN -KMF_SignCSR(KMF_HANDLE_T handle, +kmf_sign_csr(KMF_HANDLE_T handle, const KMF_CSR_DATA *tbsCsr, KMF_KEY_HANDLE *Signkey, KMF_DATA *SignedCsr) @@ -294,8 +368,7 @@ KMF_SignCSR(KMF_HANDLE_T handle, if (err != KMF_OK) return (err); - if (tbsCsr == NULL || - Signkey == NULL || SignedCsr == NULL) + if (tbsCsr == NULL || Signkey == NULL || SignedCsr == NULL) return (KMF_ERR_BAD_PARAMETER); SignedCsr->Data = NULL; @@ -304,187 +377,199 @@ KMF_SignCSR(KMF_HANDLE_T handle, err = DerEncodeTbsCsr((KMF_TBS_CSR *)&tbsCsr->csr, &csrdata); if (err == KMF_OK) { err = SignCsr(handle, &csrdata, Signkey, - (KMF_X509_ALGORITHM_IDENTIFIER *) - &tbsCsr->signature.algorithmIdentifier, - SignedCsr); + (KMF_X509_ALGORITHM_IDENTIFIER *) + &tbsCsr->signature.algorithmIdentifier, + SignedCsr); } if (err != KMF_OK) { - KMF_FreeData(SignedCsr); + kmf_free_data(SignedCsr); } - KMF_FreeData(&csrdata); + kmf_free_data(&csrdata); return (err); } -KMF_RETURN -KMF_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) +static KMF_RETURN +setup_crl_call(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist, KMF_PLUGIN **plugin) { - KMF_PLUGIN *plugin; KMF_RETURN ret; + KMF_KEYSTORE_TYPE kstype; + uint32_t len = sizeof (kstype); + + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)} + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL || plugin == NULL) + return (KMF_ERR_BAD_PARAMETER); CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); if (ret != KMF_OK) return (ret); - if (params == NULL) - return (KMF_ERR_BAD_PARAMETER); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, + &kstype, &len); + if (ret != KMF_OK) + return (ret); - switch (params->kstype) { + switch (kstype) { case KMF_KEYSTORE_NSS: - plugin = FindPlugin(handle, params->kstype); + *plugin = FindPlugin(handle, kstype); break; case KMF_KEYSTORE_OPENSSL: case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */ - plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); + *plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); break; default: return (KMF_ERR_PLUGIN_NOTFOUND); } - - if (plugin != NULL && plugin->funclist->ImportCRL != NULL) { - return (plugin->funclist->ImportCRL(handle, params)); - } - return (KMF_ERR_PLUGIN_NOTFOUND); + return (KMF_OK); } KMF_RETURN -KMF_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) +kmf_import_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { - KMF_PLUGIN *plugin; KMF_RETURN ret; + KMF_PLUGIN *plugin; - CLEAR_ERROR(handle, ret); + ret = setup_crl_call(handle, numattr, attrlist, &plugin); if (ret != KMF_OK) return (ret); - if (params == NULL) - return (KMF_ERR_BAD_PARAMETER); - - switch (params->kstype) { - case KMF_KEYSTORE_NSS: - plugin = FindPlugin(handle, params->kstype); - break; - - case KMF_KEYSTORE_OPENSSL: - case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */ - plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); - break; - default: + if (plugin == NULL) return (KMF_ERR_PLUGIN_NOTFOUND); - } + else if (plugin->funclist->ImportCRL != NULL) + return (plugin->funclist->ImportCRL(handle, numattr, attrlist)); - if (plugin != NULL && plugin->funclist->DeleteCRL != NULL) { - return (plugin->funclist->DeleteCRL(handle, params)); - } else { - return (KMF_ERR_PLUGIN_NOTFOUND); - } + return (KMF_ERR_FUNCTION_NOT_FOUND); } KMF_RETURN -KMF_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params, char **crldata) +kmf_delete_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { - KMF_PLUGIN *plugin; KMF_RETURN ret; + KMF_PLUGIN *plugin; - CLEAR_ERROR(handle, ret); + ret = setup_crl_call(handle, numattr, attrlist, &plugin); if (ret != KMF_OK) return (ret); - if (params == NULL || crldata == NULL) - return (KMF_ERR_BAD_PARAMETER); - - switch (params->kstype) { - case KMF_KEYSTORE_NSS: - plugin = FindPlugin(handle, params->kstype); - break; - - case KMF_KEYSTORE_OPENSSL: - case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */ - plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); - break; - default: + if (plugin == NULL) return (KMF_ERR_PLUGIN_NOTFOUND); - } + else if (plugin->funclist->DeleteCRL != NULL) + return (plugin->funclist->DeleteCRL(handle, numattr, attrlist)); - if (plugin != NULL && plugin->funclist->ListCRL != NULL) { - return (plugin->funclist->ListCRL(handle, params, crldata)); - } else { - return (KMF_ERR_PLUGIN_NOTFOUND); - } + return (KMF_ERR_FUNCTION_NOT_FOUND); } KMF_RETURN -KMF_FindCRL(KMF_HANDLE_T handle, KMF_FINDCRL_PARAMS *params, - char **CRLNameList, int *CRLCount) +kmf_list_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_PLUGIN *plugin; KMF_RETURN ret; - CLEAR_ERROR(handle, ret); + ret = setup_crl_call(handle, numattr, attrlist, &plugin); if (ret != KMF_OK) return (ret); - if (params == NULL || - CRLCount == NULL) - return (KMF_ERR_BAD_PARAMETER); - - plugin = FindPlugin(handle, params->kstype); - if (plugin != NULL && plugin->funclist->FindCRL != NULL) { - return (plugin->funclist->FindCRL(handle, params, - CRLNameList, CRLCount)); - } else { + if (plugin == NULL) return (KMF_ERR_PLUGIN_NOTFOUND); - } + else if (plugin->funclist->ListCRL != NULL) + return (plugin->funclist->ListCRL(handle, numattr, attrlist)); + return (KMF_ERR_FUNCTION_NOT_FOUND); } KMF_RETURN -KMF_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) +kmf_find_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_PLUGIN *plugin; KMF_RETURN ret; + KMF_KEYSTORE_TYPE kstype; + uint32_t len = sizeof (kstype); + + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, + sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_CRL_COUNT_ATTR, FALSE, + sizeof (char *), sizeof (char *)} + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); if (ret != KMF_OK) return (ret); - if (params == NULL) - return (KMF_ERR_BAD_PARAMETER); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, + &kstype, &len); + if (ret != KMF_OK) + return (ret); - switch (params->kstype) { + switch (kstype) { case KMF_KEYSTORE_NSS: - plugin = FindPlugin(handle, params->kstype); + plugin = FindPlugin(handle, kstype); break; - case KMF_KEYSTORE_OPENSSL: - case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */ - plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); - break; + case KMF_KEYSTORE_PK11TOKEN: + return (KMF_ERR_FUNCTION_NOT_FOUND); default: + /* + * FindCRL is only implemented for NSS. PKCS#11 + * and file-based keystores just store in a file + * and don't need a "Find" function. + */ return (KMF_ERR_PLUGIN_NOTFOUND); } - if (plugin != NULL && plugin->funclist->FindCertInCRL != NULL) { - return (plugin->funclist->FindCertInCRL(handle, params)); - } else { + if (plugin == NULL) return (KMF_ERR_PLUGIN_NOTFOUND); + else if (plugin->funclist->FindCRL != NULL) { + return (plugin->funclist->FindCRL(handle, numattr, + attrlist)); } + return (KMF_ERR_FUNCTION_NOT_FOUND); } KMF_RETURN -KMF_VerifyCRLFile(KMF_HANDLE_T handle, - KMF_VERIFYCRL_PARAMS *params) +kmf_find_cert_in_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { - KMF_PLUGIN *plugin; - KMF_RETURN (*verifyCRLFile)(KMF_HANDLE_T, - KMF_VERIFYCRL_PARAMS *); KMF_RETURN ret; + KMF_PLUGIN *plugin; - CLEAR_ERROR(handle, ret); + ret = setup_crl_call(handle, numattr, attrlist, &plugin); if (ret != KMF_OK) return (ret); - if (params == NULL) + if (plugin == NULL) + return (KMF_ERR_PLUGIN_NOTFOUND); + else if (plugin->funclist->FindCertInCRL != NULL) + return (plugin->funclist->FindCertInCRL(handle, numattr, + attrlist)); + + return (KMF_ERR_FUNCTION_NOT_FOUND); +} + +KMF_RETURN +kmf_verify_crl_file(KMF_HANDLE_T handle, char *crlfile, KMF_DATA *tacert) +{ + KMF_PLUGIN *plugin; + KMF_RETURN (*verifyCRLFile)(KMF_HANDLE_T, char *, KMF_DATA *); + + if (handle == NULL) return (KMF_ERR_BAD_PARAMETER); plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); @@ -499,24 +584,23 @@ KMF_VerifyCRLFile(KMF_HANDLE_T handle, return (KMF_ERR_FUNCTION_NOT_FOUND); } - return (verifyCRLFile(handle, params)); + return (verifyCRLFile(handle, crlfile, tacert)); } KMF_RETURN -KMF_CheckCRLDate(KMF_HANDLE_T handle, KMF_CHECKCRLDATE_PARAMS *params) +kmf_check_crl_date(KMF_HANDLE_T handle, char *crlname) { KMF_PLUGIN *plugin; - KMF_RETURN (*checkCRLDate)(void *, - KMF_CHECKCRLDATE_PARAMS *params); - KMF_RETURN ret; + KMF_RETURN (*checkCRLDate)(void *, char *); + KMF_RETURN ret = KMF_OK; + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); CLEAR_ERROR(handle, ret); if (ret != KMF_OK) return (ret); - if (params == NULL) - return (KMF_ERR_BAD_PARAMETER); - plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); if (plugin == NULL || plugin->dldesc == NULL) { return (KMF_ERR_PLUGIN_NOTFOUND); @@ -529,16 +613,15 @@ KMF_CheckCRLDate(KMF_HANDLE_T handle, KMF_CHECKCRLDATE_PARAMS *params) return (KMF_ERR_FUNCTION_NOT_FOUND); } - return (checkCRLDate(handle, params)); - + return (checkCRLDate(handle, crlname)); } KMF_RETURN -KMF_IsCRLFile(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat) +kmf_is_crl_file(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat) { KMF_PLUGIN *plugin; KMF_RETURN (*IsCRLFileFn)(void *, char *, KMF_ENCODE_FORMAT *); - KMF_RETURN ret; + KMF_RETURN ret = KMF_OK; CLEAR_ERROR(handle, ret); if (ret != KMF_OK) @@ -565,3 +648,50 @@ KMF_IsCRLFile(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat) return (IsCRLFileFn(handle, filename, pformat)); } + +/* + * Phase 1 APIs still needed to maintain compat with elfsign. + */ +KMF_RETURN +KMF_CreateCSRFile(KMF_DATA *csrdata, KMF_ENCODE_FORMAT format, + char *csrfile) +{ + return (kmf_create_csr_file(csrdata, format, csrfile)); +} + +KMF_RETURN +KMF_SetCSRPubKey(KMF_HANDLE_T handle, + KMF_KEY_HANDLE *KMFKey, + KMF_CSR_DATA *Csr) +{ + return (kmf_set_csr_pubkey(handle, KMFKey, Csr)); +} + +KMF_RETURN +KMF_SetCSRVersion(KMF_CSR_DATA *CsrData, uint32_t version) +{ + return (kmf_set_csr_version(CsrData, version)); +} + +KMF_RETURN +KMF_SetCSRSignatureAlgorithm(KMF_CSR_DATA *CsrData, + KMF_ALGORITHM_INDEX sigAlg) +{ + return (kmf_set_csr_sig_alg(CsrData, sigAlg)); +} + +KMF_RETURN +KMF_SignCSR(KMF_HANDLE_T handle, + const KMF_CSR_DATA *tbsCsr, + KMF_KEY_HANDLE *Signkey, + KMF_DATA *SignedCsr) +{ + return (kmf_sign_csr(handle, tbsCsr, Signkey, SignedCsr)); +} + +KMF_RETURN +KMF_SetCSRSubjectName(KMF_CSR_DATA *CsrData, + KMF_X509_NAME *subject_name_ptr) +{ + return (kmf_set_csr_subject(CsrData, subject_name_ptr)); +} diff --git a/usr/src/lib/libkmf/libkmf/common/generalop.c b/usr/src/lib/libkmf/libkmf/common/generalop.c index 73b6d75611..38a72a3df4 100644 --- a/usr/src/lib/libkmf/libkmf/common/generalop.c +++ b/usr/src/lib/libkmf/libkmf/common/generalop.c @@ -152,6 +152,8 @@ KMF_PLUGIN_ITEM plugin_list[] = { {KMF_KEYSTORE_NSS, KMF_PLUGIN_PATH "kmf_nss.so.1", FALSE} }; + + static void free_extensions(KMF_X509_EXTENSIONS *extns); KMF_RETURN @@ -222,7 +224,7 @@ InitializePlugin(KMF_KEYSTORE_TYPE kstype, char *path, KMF_PLUGIN **plugin) } sym = (KMF_PLUGIN_FUNCLIST *(*)())dlsym(p->dldesc, - KMF_PLUGIN_INIT_SYMBOL); + KMF_PLUGIN_INIT_SYMBOL); if (sym == NULL) { (void) dlclose(p->dldesc); free(p->path); @@ -254,7 +256,7 @@ AddPlugin(KMF_HANDLE_T handle, KMF_PLUGIN *plugin) /* If the head is NULL, create it */ if (handle->plugins == NULL) { handle->plugins = (KMF_PLUGIN_LIST *)malloc( - sizeof (KMF_PLUGIN_LIST)); + sizeof (KMF_PLUGIN_LIST)); if (handle->plugins == NULL) return (KMF_ERR_MEMORY); handle->plugins->plugin = plugin; @@ -298,7 +300,7 @@ Cleanup_KMF_Handle(KMF_HANDLE_T handle) handle->plugins = next; } - KMF_FreePolicyRecord(handle->policy); + kmf_free_policy_record(handle->policy); free(handle->policy); } free(handle); @@ -317,7 +319,7 @@ Cleanup_PK11_Session(KMF_HANDLE_T handle) } KMF_RETURN -KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) +kmf_initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) { KMF_RETURN ret = KMF_OK; KMF_HANDLE *handle = NULL; @@ -336,7 +338,7 @@ KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) handle->plugins = NULL; /* Initialize the handle with the policy */ - ret = KMF_SetPolicy((void *)handle, + ret = kmf_set_policy((void *)handle, policyfile == NULL ? KMF_DEFAULT_POLICY_FILE : policyfile, policyname == NULL ? KMF_DEFAULT_POLICY_NAME : policyname); if (ret != KMF_OK) @@ -345,7 +347,7 @@ KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) numitems = sizeof (plugin_list)/sizeof (KMF_PLUGIN_ITEM); for (i = 0; i < numitems; i++) { ret = InitializePlugin(plugin_list[i].kstype, - plugin_list[i].path, &pluginrec); + plugin_list[i].path, &pluginrec); if (ret != KMF_OK) { cryptoerror( plugin_list[i].critical ? LOG_WARNING : LOG_DEBUG, @@ -376,31 +378,51 @@ errout: } KMF_RETURN -KMF_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) +kmf_configure_keystore(KMF_HANDLE_T handle, + int num_args, + KMF_ATTRIBUTE *attrlist) { + KMF_RETURN ret = KMF_OK; KMF_PLUGIN *plugin; - KMF_RETURN ret; + KMF_KEYSTORE_TYPE kstype; + uint32_t len; + + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, num_args, attrlist); + if (ret != KMF_OK) return (ret); - if (params == NULL) - return (KMF_ERR_BAD_PARAMETER); - - plugin = FindPlugin(handle, params->kstype); - if (plugin == NULL) - return (KMF_ERR_PLUGIN_NOTFOUND); + len = sizeof (kstype); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args, + &kstype, &len); + if (ret != KMF_OK) + return (ret); - if (plugin->funclist->ConfigureKeystore != NULL) - return (plugin->funclist->ConfigureKeystore(handle, params)); - else + plugin = FindPlugin(handle, kstype); + if (plugin != NULL && plugin->funclist->ConfigureKeystore != NULL) { + return (plugin->funclist->ConfigureKeystore(handle, num_args, + attrlist)); + } else { /* return KMF_OK, if the plugin does not have an entry */ return (KMF_OK); + } } KMF_RETURN -KMF_Finalize(KMF_HANDLE_T handle) +kmf_finalize(KMF_HANDLE_T handle) { KMF_RETURN ret = KMF_OK; @@ -417,7 +439,7 @@ KMF_Finalize(KMF_HANDLE_T handle) } KMF_RETURN -KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) +kmf_get_kmf_error_str(KMF_RETURN errcode, char **errmsg) { KMF_RETURN ret = KMF_OK; int i, maxerr; @@ -428,7 +450,9 @@ KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) *errmsg = NULL; maxerr = sizeof (kmf_errcodes) / sizeof (kmf_error_map); - for (i = 0; i < maxerr && errcode != kmf_errcodes[i].code; i++); + for (i = 0; i < maxerr && errcode != kmf_errcodes[i].code; i++) + /* empty body */ + ; if (i == maxerr) return (KMF_ERR_MISSING_ERRCODE); @@ -441,7 +465,7 @@ KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) } KMF_RETURN -KMF_GetPluginErrorString(KMF_HANDLE_T handle, char **msgstr) +kmf_get_plugin_error_str(KMF_HANDLE_T handle, char **msgstr) { KMF_RETURN ret = KMF_OK; KMF_PLUGIN *plugin; @@ -478,29 +502,6 @@ KMF_GetPluginErrorString(KMF_HANDLE_T handle, char **msgstr) return (ret); } -KMF_RETURN -KMF_DNParser(char *string, KMF_X509_NAME *name) -{ - KMF_RETURN err; - - if (string == NULL || name == NULL) - return (KMF_ERR_BAD_PARAMETER); - - err = ParseDistinguishedName(string, (int)strlen(string), name); - return (err); -} - -KMF_RETURN -KMF_DN2Der(KMF_X509_NAME *dn, KMF_DATA *der) -{ - KMF_RETURN rv; - - if (dn == NULL || der == NULL) - return (KMF_ERR_BAD_PARAMETER); - - rv = DerEncodeName(dn, der); - return (rv); -} #define SET_SYS_ERROR(h, c) if (h) {\ h->lasterr.kstype = -1;\ @@ -508,7 +509,7 @@ KMF_DN2Der(KMF_X509_NAME *dn, KMF_DATA *der) } KMF_RETURN -KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) +kmf_read_input_file(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) { struct stat s; long nread, total = 0; @@ -561,7 +562,7 @@ KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) /* * - * Name: KMF_Der2Pem + * Name: kmf_der_to_pem * * Description: * Function for converting DER encoded format to PEM encoded format @@ -581,7 +582,7 @@ KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) * */ KMF_RETURN -KMF_Der2Pem(KMF_OBJECT_TYPE type, unsigned char *data, +kmf_der_to_pem(KMF_OBJECT_TYPE type, unsigned char *data, int len, unsigned char **out, int *outlen) { @@ -596,7 +597,7 @@ KMF_Der2Pem(KMF_OBJECT_TYPE type, unsigned char *data, /* * - * Name: KMF_Pem2Der + * Name: kmf_pem_to_der * * Description: * Function for converting PEM encoded format to DER encoded format @@ -615,7 +616,7 @@ KMF_Der2Pem(KMF_OBJECT_TYPE type, unsigned char *data, * */ KMF_RETURN -KMF_Pem2Der(unsigned char *in, int inlen, +kmf_pem_to_der(unsigned char *in, int inlen, unsigned char **out, int *outlen) { KMF_RETURN err; @@ -627,7 +628,7 @@ KMF_Pem2Der(unsigned char *in, int inlen, } char * -KMF_OID2String(KMF_OID *oid) +kmf_oid_to_string(KMF_OID *oid) { char numstr[128]; uint32_t number; @@ -811,7 +812,7 @@ check_for_pkcs12(uchar_t *buf, int buf_len) } KMF_RETURN -KMF_GetFileFormat(char *filename, KMF_ENCODE_FORMAT *fmt) +kmf_get_file_format(char *filename, KMF_ENCODE_FORMAT *fmt) { KMF_RETURN ret = KMF_OK; KMF_DATA filebuf = {NULL, 0}; @@ -821,7 +822,7 @@ KMF_GetFileFormat(char *filename, KMF_ENCODE_FORMAT *fmt) return (KMF_ERR_BAD_PARAMETER); *fmt = 0; - ret = KMF_ReadInputFile(NULL, filename, &filebuf); + ret = kmf_read_input_file(NULL, filename, &filebuf); if (ret != KMF_OK) return (ret); @@ -845,12 +846,12 @@ KMF_GetFileFormat(char *filename, KMF_ENCODE_FORMAT *fmt) } end: - KMF_FreeData(&filebuf); + kmf_free_data(&filebuf); return (ret); } KMF_RETURN -KMF_HexString2Bytes(unsigned char *hexstr, unsigned char **bytes, +kmf_hexstr_to_bytes(unsigned char *hexstr, unsigned char **bytes, size_t *outlen) { KMF_RETURN ret = KMF_OK; @@ -863,11 +864,12 @@ KMF_HexString2Bytes(unsigned char *hexstr, unsigned char **bytes, return (KMF_ERR_BAD_PARAMETER); } - if (hexstr[0] == '0' && - ((hexstr[1] == 'x') || (hexstr[1] == 'X'))) + if (hexstr[0] == '0' && ((hexstr[1] == 'x') || (hexstr[1] == 'X'))) hexstr += 2; - for (i = 0; i < strlen((char *)hexstr) && isxdigit(hexstr[i]); i++); + for (i = 0; i < strlen((char *)hexstr) && isxdigit(hexstr[i]); i++) + /* empty body */ + ; /* * If all the characters are not legitimate hex chars, * return an error. @@ -914,7 +916,7 @@ out: } void -KMF_FreeDN(KMF_X509_NAME *name) +kmf_free_dn(KMF_X509_NAME *name) { KMF_X509_RDN *newrdn = NULL; KMF_X509_TYPE_VALUE_PAIR *av = NULL; @@ -925,8 +927,8 @@ KMF_FreeDN(KMF_X509_NAME *name) newrdn = &name->RelativeDistinguishedName[i]; for (j = 0; j < newrdn->numberOfPairs; j++) { av = &newrdn->AttributeTypeAndValue[j]; - KMF_FreeData(&av->type); - KMF_FreeData(&av->value); + kmf_free_data(&av->type); + kmf_free_data(&av->value); } free(newrdn->AttributeTypeAndValue); newrdn->numberOfPairs = 0; @@ -939,7 +941,7 @@ KMF_FreeDN(KMF_X509_NAME *name) } void -KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) +kmf_free_kmf_cert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) { KMF_PLUGIN *plugin; KMF_RETURN ret; @@ -959,7 +961,7 @@ KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) } void -KMF_FreeData(KMF_DATA *datablock) +kmf_free_data(KMF_DATA *datablock) { if (datablock != NULL && datablock->Data != NULL) { free(datablock->Data); @@ -969,52 +971,52 @@ KMF_FreeData(KMF_DATA *datablock) } void -KMF_FreeAlgOID(KMF_X509_ALGORITHM_IDENTIFIER *algoid) +kmf_free_algoid(KMF_X509_ALGORITHM_IDENTIFIER *algoid) { if (algoid == NULL) return; - KMF_FreeData(&algoid->algorithm); - KMF_FreeData(&algoid->parameters); + kmf_free_data(&algoid->algorithm); + kmf_free_data(&algoid->parameters); } void -KMF_FreeExtension(KMF_X509_EXTENSION *exptr) +kmf_free_extn(KMF_X509_EXTENSION *exptr) { if (exptr == NULL) return; - KMF_FreeData((KMF_DATA *)&exptr->extnId); - KMF_FreeData(&exptr->BERvalue); + kmf_free_data((KMF_DATA *)&exptr->extnId); + kmf_free_data(&exptr->BERvalue); if (exptr->value.tagAndValue) { - KMF_FreeData(&exptr->value.tagAndValue->value); + kmf_free_data(&exptr->value.tagAndValue->value); free(exptr->value.tagAndValue); } } void -KMF_FreeTBSCSR(KMF_TBS_CSR *tbscsr) +kmf_free_tbs_csr(KMF_TBS_CSR *tbscsr) { if (tbscsr) { - KMF_FreeData(&tbscsr->version); + kmf_free_data(&tbscsr->version); - KMF_FreeDN(&tbscsr->subject); + kmf_free_dn(&tbscsr->subject); - KMF_FreeAlgOID(&tbscsr->subjectPublicKeyInfo.algorithm); - KMF_FreeData(&tbscsr->subjectPublicKeyInfo.subjectPublicKey); + kmf_free_algoid(&tbscsr->subjectPublicKeyInfo.algorithm); + kmf_free_data(&tbscsr->subjectPublicKeyInfo.subjectPublicKey); free_extensions(&tbscsr->extensions); } } void -KMF_FreeSignedCSR(KMF_CSR_DATA *csr) +kmf_free_signed_csr(KMF_CSR_DATA *csr) { if (csr) { - KMF_FreeTBSCSR(&csr->csr); + kmf_free_tbs_csr(&csr->csr); - KMF_FreeAlgOID(&csr->signature.algorithmIdentifier); - KMF_FreeData(&csr->signature.encrypted); + kmf_free_algoid(&csr->signature.algorithmIdentifier); + kmf_free_data(&csr->signature.encrypted); } } @@ -1023,8 +1025,8 @@ free_validity(KMF_X509_VALIDITY *validity) { if (validity == NULL) return; - KMF_FreeData(&validity->notBefore.time); - KMF_FreeData(&validity->notAfter.time); + kmf_free_data(&validity->notBefore.time); + kmf_free_data(&validity->notAfter.time); } static void @@ -1036,7 +1038,7 @@ free_extensions(KMF_X509_EXTENSIONS *extns) if (extns && extns->numberOfExtensions > 0) { for (i = 0; i < extns->numberOfExtensions; i++) { exptr = &extns->extensions[i]; - KMF_FreeExtension(exptr); + kmf_free_extn(exptr); } free(extns->extensions); extns->numberOfExtensions = 0; @@ -1045,45 +1047,45 @@ free_extensions(KMF_X509_EXTENSIONS *extns) } void -KMF_FreeTBSCert(KMF_X509_TBS_CERT *tbscert) +kmf_free_tbs_cert(KMF_X509_TBS_CERT *tbscert) { if (tbscert) { - KMF_FreeData(&tbscert->version); - KMF_FreeBigint(&tbscert->serialNumber); - KMF_FreeAlgOID(&tbscert->signature); + kmf_free_data(&tbscert->version); + kmf_free_bigint(&tbscert->serialNumber); + kmf_free_algoid(&tbscert->signature); - KMF_FreeDN(&tbscert->issuer); - KMF_FreeDN(&tbscert->subject); + kmf_free_dn(&tbscert->issuer); + kmf_free_dn(&tbscert->subject); free_validity(&tbscert->validity); - KMF_FreeData(&tbscert->issuerUniqueIdentifier); - KMF_FreeData(&tbscert->subjectUniqueIdentifier); + kmf_free_data(&tbscert->issuerUniqueIdentifier); + kmf_free_data(&tbscert->subjectUniqueIdentifier); - KMF_FreeAlgOID(&tbscert->subjectPublicKeyInfo.algorithm); - KMF_FreeData(&tbscert->subjectPublicKeyInfo.subjectPublicKey); + kmf_free_algoid(&tbscert->subjectPublicKeyInfo.algorithm); + kmf_free_data(&tbscert->subjectPublicKeyInfo.subjectPublicKey); free_extensions(&tbscert->extensions); - KMF_FreeData(&tbscert->issuerUniqueIdentifier); - KMF_FreeData(&tbscert->subjectUniqueIdentifier); + kmf_free_data(&tbscert->issuerUniqueIdentifier); + kmf_free_data(&tbscert->subjectUniqueIdentifier); } } void -KMF_FreeSignedCert(KMF_X509_CERTIFICATE *certptr) +kmf_free_signed_cert(KMF_X509_CERTIFICATE *certptr) { if (!certptr) return; - KMF_FreeTBSCert(&certptr->certificate); + kmf_free_tbs_cert(&certptr->certificate); - KMF_FreeAlgOID(&certptr->signature.algorithmIdentifier); - KMF_FreeData(&certptr->signature.encrypted); + kmf_free_algoid(&certptr->signature.algorithmIdentifier); + kmf_free_data(&certptr->signature.encrypted); } void -KMF_FreeString(char *pstr) +kmf_free_str(char *pstr) { if (pstr != NULL) free(pstr); @@ -1094,54 +1096,61 @@ free_keyidlist(KMF_OID *oidlist, int len) { int i; for (i = 0; i < len; i++) { - KMF_FreeData((KMF_DATA *)&oidlist[i]); + kmf_free_data((KMF_DATA *)&oidlist[i]); } free(oidlist); } void -KMF_FreeEKU(KMF_X509EXT_EKU *eptr) +kmf_free_eku(KMF_X509EXT_EKU *eptr) { - if (eptr && eptr->nEKUs > 0 && - eptr->keyPurposeIdList != NULL) + if (eptr && eptr->nEKUs > 0 && eptr->keyPurposeIdList != NULL) free_keyidlist(eptr->keyPurposeIdList, eptr->nEKUs); } void -KMF_FreeSPKI(KMF_X509_SPKI *spki) +kmf_free_spki(KMF_X509_SPKI *spki) { if (spki != NULL) { - KMF_FreeAlgOID(&spki->algorithm); - KMF_FreeData(&spki->subjectPublicKey); + kmf_free_algoid(&spki->algorithm); + kmf_free_data(&spki->subjectPublicKey); } } void -KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) +kmf_free_kmf_key(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) { KMF_PLUGIN *plugin; KMF_RETURN ret; + KMF_ATTRIBUTE attlist[2]; /* only 2 attributes for DeleteKey op */ + int i = 0; + boolean_t token_destroy = B_FALSE; + + if (key == NULL) + return; CLEAR_ERROR(handle, ret); if (ret != KMF_OK) return; - if (key == NULL) - return; + kmf_set_attr_at_index(attlist, i, + KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); + i++; + + kmf_set_attr_at_index(attlist, i, + KMF_DESTROY_BOOL_ATTR, &token_destroy, sizeof (boolean_t)); + i++; plugin = FindPlugin(handle, key->kstype); if (plugin != NULL && plugin->funclist->DeleteKey != NULL) { - (void) plugin->funclist->DeleteKey(handle, NULL, key, FALSE); + (void) plugin->funclist->DeleteKey(handle, i, attlist); } - if (key == NULL) - return; - if (key->keylabel) free(key->keylabel); if (key->israw) { - KMF_FreeRawKey(key->keyp); + kmf_free_raw_key(key->keyp); free(key->keyp); } @@ -1149,7 +1158,7 @@ KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) } void -KMF_FreeBigint(KMF_BIGINT *big) +kmf_free_bigint(KMF_BIGINT *big) { if (big != NULL && big->val != NULL) { /* Clear it out before returning it to the pool */ @@ -1165,14 +1174,14 @@ free_raw_rsa(KMF_RAW_RSA_KEY *key) { if (key == NULL) return; - KMF_FreeBigint(&key->mod); - KMF_FreeBigint(&key->pubexp); - KMF_FreeBigint(&key->priexp); - KMF_FreeBigint(&key->prime1); - KMF_FreeBigint(&key->prime2); - KMF_FreeBigint(&key->exp1); - KMF_FreeBigint(&key->exp2); - KMF_FreeBigint(&key->coef); + kmf_free_bigint(&key->mod); + kmf_free_bigint(&key->pubexp); + kmf_free_bigint(&key->priexp); + kmf_free_bigint(&key->prime1); + kmf_free_bigint(&key->prime2); + kmf_free_bigint(&key->exp1); + kmf_free_bigint(&key->exp2); + kmf_free_bigint(&key->coef); } static void @@ -1180,10 +1189,10 @@ free_raw_dsa(KMF_RAW_DSA_KEY *key) { if (key == NULL) return; - KMF_FreeBigint(&key->prime); - KMF_FreeBigint(&key->subprime); - KMF_FreeBigint(&key->base); - KMF_FreeBigint(&key->value); + kmf_free_bigint(&key->prime); + kmf_free_bigint(&key->subprime); + kmf_free_bigint(&key->base); + kmf_free_bigint(&key->value); } static void @@ -1191,11 +1200,11 @@ free_raw_sym(KMF_RAW_SYM_KEY *key) { if (key == NULL) return; - KMF_FreeBigint(&key->keydata); + kmf_free_bigint(&key->keydata); } void -KMF_FreeRawKey(KMF_RAW_KEY_DATA *key) +kmf_free_raw_key(KMF_RAW_KEY_DATA *key) { if (key == NULL) return; @@ -1217,11 +1226,11 @@ KMF_FreeRawKey(KMF_RAW_KEY_DATA *key) } void -KMF_FreeRawSymKey(KMF_RAW_SYM_KEY *key) +kmf_free_raw_sym_key(KMF_RAW_SYM_KEY *key) { if (key == NULL) return; - KMF_FreeBigint(&key->keydata); + kmf_free_bigint(&key->keydata); free(key); } @@ -1246,7 +1255,7 @@ free_dp_name(KMF_CRL_DIST_POINT *dp) for (i = 0; i < fullname->number; i++) { urldata = &(fullname->namelist[fullname->number - 1].name); - KMF_FreeData(urldata); + kmf_free_data(urldata); } free(fullname->namelist); @@ -1262,7 +1271,7 @@ free_dp(KMF_CRL_DIST_POINT *dp) return; free_dp_name(dp); - KMF_FreeData(&(dp->reasons)); + kmf_free_data(&(dp->reasons)); /* Need not to free crl_issuer space at phase 1 */ } @@ -1270,7 +1279,7 @@ free_dp(KMF_CRL_DIST_POINT *dp) * This function frees space for a KMF_X509EXT_CRLDISTPOINTS internally. */ void -KMF_FreeCRLDistributionPoints(KMF_X509EXT_CRLDISTPOINTS *crl_dps) +kmf_free_crl_dist_pts(KMF_X509EXT_CRLDISTPOINTS *crl_dps) { int i; @@ -1284,23 +1293,37 @@ KMF_FreeCRLDistributionPoints(KMF_X509EXT_CRLDISTPOINTS *crl_dps) } KMF_RETURN -KMF_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, - char *reqfile) +kmf_create_ocsp_request(KMF_HANDLE_T handle, + int num_args, + KMF_ATTRIBUTE *attrlist) { + KMF_RETURN ret = KMF_OK; KMF_PLUGIN *plugin; - KMF_RETURN (*createReqFn)(void *, KMF_OCSPREQUEST_PARAMS *params, - char *reqfile); - KMF_RETURN ret; + KMF_RETURN (*createReqFn)(void *, int num_args, + KMF_ATTRIBUTE *attrlist); - CLEAR_ERROR(handle, ret); - if (ret != KMF_OK) - return (ret); + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_OCSP_REQUEST_FILENAME_ATTR, FALSE, 1, 0}, + {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)}, + {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)}, + }; + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); - if (params == NULL || - reqfile == NULL) + if (handle == NULL) return (KMF_ERR_BAD_PARAMETER); + CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, num_args, attrlist); + + if (ret != KMF_OK) + return (ret); + /* * This framework function is actually implemented in the openssl * plugin library, so we find the function address and call it. @@ -1316,28 +1339,48 @@ KMF_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, return (KMF_ERR_FUNCTION_NOT_FOUND); } - return (createReqFn(handle, params, reqfile)); + return (createReqFn(handle, num_args, attrlist)); + } KMF_RETURN -KMF_GetOCSPStatusForCert(KMF_HANDLE_T handle, - KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, - KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out) +kmf_get_ocsp_status_for_cert(KMF_HANDLE_T handle, + int num_args, + KMF_ATTRIBUTE *attrlist) { + KMF_RETURN ret = KMF_OK; KMF_PLUGIN *plugin; - KMF_RETURN (*getCertStatusFn)(void *, - KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, - KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out); - KMF_RETURN ret; + KMF_RETURN (*getCertStatusFn)(void *, int num_args, + KMF_ATTRIBUTE *attrlist); + + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)}, + {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)}, + {KMF_OCSP_RESPONSE_DATA_ATTR, FALSE, sizeof (KMF_DATA), + sizeof (KMF_DATA)}, + {KMF_OCSP_RESPONSE_STATUS_ATTR, FALSE, sizeof (int), + sizeof (uint32_t)}, + {KMF_OCSP_RESPONSE_REASON_ATTR, FALSE, sizeof (int), + sizeof (uint32_t)}, + {KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, FALSE, sizeof (int), + sizeof (uint32_t)}, + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); CLEAR_ERROR(handle, ret); - if (ret != KMF_OK) - return (ret); + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, num_args, attrlist); - if (params_in == NULL || - params_out == NULL) - return (KMF_ERR_BAD_PARAMETER); + if (ret != KMF_OK) + return (ret); /* * This framework function is actually implemented in the openssl @@ -1354,11 +1397,12 @@ KMF_GetOCSPStatusForCert(KMF_HANDLE_T handle, return (KMF_ERR_INTERNAL); } - return (getCertStatusFn(handle, params_in, params_out)); + return (getCertStatusFn(handle, num_args, attrlist)); + } KMF_RETURN -KMF_String2OID(char *oidstring, KMF_OID *oid) +kmf_string_to_oid(char *oidstring, KMF_OID *oid) { KMF_RETURN rv = KMF_OK; char *cp, *bp, *startp; @@ -1469,7 +1513,7 @@ encode_rid(char *name, KMF_DATA *derdata) if (name == NULL || derdata == NULL) return (KMF_ERR_BAD_PARAMETER); - rv = KMF_String2OID(name, (KMF_OID *)derdata); + rv = kmf_string_to_oid(name, (KMF_OID *)derdata); return (rv); } @@ -1589,11 +1633,11 @@ encode_altname(char *namedata, tagval = (0x80 | nametype); break; case GENNAME_DIRECTORYNAME: - ret = KMF_DNParser(namedata, &dnname); + ret = kmf_dn_parser(namedata, &dnname); if (ret == KMF_OK) { - ret = KMF_DN2Der(&dnname, encodedname); + ret = DerEncodeName(&dnname, encodedname); } - (void) KMF_FreeDN(&dnname); + (void) kmf_free_dn(&dnname); tagval = (0xA0 | nametype); break; default: @@ -1602,19 +1646,18 @@ encode_altname(char *namedata, } if (ret != KMF_OK) { - KMF_FreeData(encodedname); + kmf_free_data(encodedname); return (ret); } if ((asn1 = kmfder_alloc()) == NULL) return (KMF_ERR_MEMORY); - if (kmfber_printf(asn1, "Tl", - tagval, encodedname->Length) == -1) + if (kmfber_printf(asn1, "Tl", tagval, encodedname->Length) == -1) goto cleanup; if (kmfber_write(asn1, (char *)encodedname->Data, - encodedname->Length, 0) == -1) { + encodedname->Length, 0) == -1) { ret = KMF_ERR_ENCODING; goto cleanup; } @@ -1623,7 +1666,7 @@ encode_altname(char *namedata, goto cleanup; } - KMF_FreeData(encodedname); + kmf_free_data(encodedname); encodedname->Data = (uchar_t *)extdata->bv_val; encodedname->Length = extdata->bv_len; @@ -1634,7 +1677,7 @@ cleanup: kmfber_free(asn1, 1); if (ret != KMF_OK) - KMF_FreeData(encodedname); + kmf_free_data(encodedname); return (ret); } @@ -1690,7 +1733,7 @@ GetSequenceContents(char *data, size_t len, * then consume them ("{"). */ if (kmfber_scanf(exasn1, "tl{", &tag, &oldsize) == KMFBER_DEFAULT || - oldsize == 0) { + oldsize == 0) { ret = KMF_ERR_ENCODING; goto out; } @@ -1735,7 +1778,7 @@ add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) return (KMF_ERR_BAD_PARAMETER); extlist = malloc(sizeof (KMF_X509_EXTENSION) * - (exts->numberOfExtensions + 1)); + (exts->numberOfExtensions + 1)); if (extlist == NULL) return (KMF_ERR_MEMORY); @@ -1743,7 +1786,7 @@ add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) exts->numberOfExtensions * sizeof (KMF_X509_EXTENSION)); (void) memcpy(&extlist[exts->numberOfExtensions], newextn, - sizeof (KMF_X509_EXTENSION)); + sizeof (KMF_X509_EXTENSION)); free(exts->extensions); exts->numberOfExtensions++; @@ -1753,7 +1796,7 @@ add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) } KMF_RETURN -KMF_SetAltName(KMF_X509_EXTENSIONS *extensions, +kmf_set_altname(KMF_X509_EXTENSIONS *extensions, KMF_OID *oid, int critical, KMF_GENERALNAMECHOICES nametype, @@ -1788,9 +1831,9 @@ KMF_SetAltName(KMF_X509_EXTENSIONS *extensions, if (foundextn != NULL) { ret = GetSequenceContents( - (char *)foundextn->BERvalue.Data, - foundextn->BERvalue.Length, - &olddata, &oldsize); + (char *)foundextn->BERvalue.Data, + foundextn->BERvalue.Length, + &olddata, &oldsize); if (ret != KMF_OK) goto out; } @@ -1854,10 +1897,380 @@ out: if (olddata != NULL) free(olddata); - KMF_FreeData(&dername); + kmf_free_data(&dername); if (ret != KMF_OK) - KMF_FreeData(&subjAltName.extnId); + kmf_free_data(&subjAltName.extnId); if (asn1 != NULL) kmfber_free(asn1, 1); return (ret); } + +/* + * Search a list of attributes for one that matches the given type. + * Return a pointer into the attribute list. This does not + * return a copy of the value, it returns a reference into the + * given list. + */ +int +kmf_find_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, int numattrs) +{ + int i; + for (i = 0; i < numattrs; i++) { + if (attlist[i].type == type) + return (i); + } + return (-1); +} + +/* + * Verify that a given attribute is consistent with the + * "test" attribute. + */ +static KMF_RETURN +verify_attribute(KMF_ATTRIBUTE *givenattr, + KMF_ATTRIBUTE_TESTER *testattr) +{ + /* A NULL pValue was found where one is required */ + if (testattr->null_value_ok == FALSE && + givenattr->pValue == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* If the given valueLen is too small, return error */ + if (givenattr->pValue != NULL && + testattr->minlen > 0 && + (givenattr->valueLen < testattr->minlen)) + return (KMF_ERR_BAD_PARAMETER); + + /* If the given valueLen is too big, return error */ + if (givenattr->pValue != NULL && + testattr->maxlen > 0 && + (givenattr->valueLen > testattr->maxlen)) + return (KMF_ERR_BAD_PARAMETER); + + return (KMF_OK); +} + +/* + * Given a set of required attribute tests and optional + * attributes, make sure that the actual attributes + * being tested (attrlist below) are allowed and are + * properly specified. + */ +KMF_RETURN +test_attributes(int reqnum, KMF_ATTRIBUTE_TESTER *reqattrs, + int optnum, KMF_ATTRIBUTE_TESTER *optattrs, + int numattrs, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + int i, idx; + + /* + * If the caller didn't supply enough attributes, + * return an error. + */ + if (numattrs < reqnum || attrlist == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* + * Make sure all required attrs are present and + * correct. + */ + for (i = 0; i < reqnum && ret == KMF_OK; i++) { + idx = kmf_find_attr(reqattrs[i].type, attrlist, numattrs); + /* If a required attr is not found, return error */ + if (idx == -1) { + return (KMF_ERR_BAD_PARAMETER); + } + + ret = verify_attribute(&attrlist[idx], &reqattrs[i]); + } + /* + * Now test the optional parameters. + */ + for (i = 0; i < optnum && ret == KMF_OK; i++) { + idx = kmf_find_attr(optattrs[i].type, attrlist, numattrs); + /* If a optional attr is not found, continue. */ + if (idx == -1) { + continue; + } + + ret = verify_attribute(&attrlist[idx], &optattrs[i]); + } + + return (ret); +} + +/* + * Given an already allocated attribute list, insert + * the given attribute information at a specific index + * in the list. + */ +void +kmf_set_attr_at_index(KMF_ATTRIBUTE *attlist, int index, + KMF_ATTR_TYPE type, void *pValue, uint32_t len) +{ + if (attlist == NULL) + return; + + attlist[index].type = type; + attlist[index].pValue = pValue; + attlist[index].valueLen = len; +} + +/* + * Find an attribute matching a particular type and set + * the pValue and length fields to the given values. + */ +KMF_RETURN +kmf_set_attr(KMF_ATTRIBUTE *attlist, int numattr, + KMF_ATTR_TYPE type, void *pValue, uint32_t len) +{ + int idx; + if (attlist == NULL) + return (KMF_ERR_BAD_PARAMETER); + + idx = kmf_find_attr(type, attlist, numattr); + if (idx == -1) + return (KMF_ERR_ATTR_NOT_FOUND); + + attlist[idx].type = type; + /* Assumes the attribute pValue can hold the result */ + if (attlist[idx].pValue != NULL) { + if (attlist[idx].valueLen >= len) + (void) memcpy(attlist[idx].pValue, pValue, len); + else + return (KMF_ERR_BUFFER_SIZE); + } + attlist[idx].valueLen = len; + return (KMF_OK); +} + +/* + * Find a particular attribute in a list and return + * a pointer to its value. + */ +void * +kmf_get_attr_ptr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, + int numattrs) +{ + int i; + + i = kmf_find_attr(type, attlist, numattrs); + if (i == -1) + return (NULL); + + return (attlist[i].pValue); +} + +/* + * Find a particular attribute in a list and return + * the value and length values. Value and length + * may be NULL if the caller doesn't want their values + * to be filled in. + */ +KMF_RETURN +kmf_get_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, + int numattrs, void *outValue, uint32_t *outlen) +{ + int i; + uint32_t len = 0; + uint32_t *lenptr = outlen; + + if (lenptr == NULL) + lenptr = &len; + + i = kmf_find_attr(type, attlist, numattrs); + if (i == -1) + return (KMF_ERR_ATTR_NOT_FOUND); + + /* This assumes that the ptr passed in is pre-allocated space */ + if (attlist[i].pValue != NULL && outValue != NULL) { + /* + * If the caller did not specify a length, + * assume "outValue" is big enough. + */ + if (outlen != NULL) { + if (*outlen >= attlist[i].valueLen) + (void) memcpy(outValue, attlist[i].pValue, + attlist[i].valueLen); + else + return (KMF_ERR_BUFFER_SIZE); + } else { + (void) memcpy(outValue, attlist[i].pValue, + attlist[i].valueLen); + } + } + + if (outlen != NULL) + *outlen = attlist[i].valueLen; + return (KMF_OK); +} + +/* + * Utility routine to find a string type attribute, allocate it + * and return the value to the caller. This simplifies the + * operation by doing both "kmf_get_attr" calls and avoids + * duplicating this block of code in lots of places. + */ +KMF_RETURN +kmf_get_string_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attrlist, + int numattrs, char **outstr) +{ + KMF_RETURN rv; + uint32_t len; + + if (outstr == NULL) + return (KMF_ERR_BAD_PARAMETER); + + if ((rv = kmf_get_attr(type, attrlist, numattrs, NULL, &len)) == + KMF_OK) { + *outstr = malloc(len + 1); + if ((*outstr) == NULL) + return (KMF_ERR_MEMORY); + (void) memset((*outstr), 0, len + 1); + rv = kmf_get_attr(type, attrlist, numattrs, (*outstr), &len); + if (rv != KMF_OK) { + free(*outstr); + *outstr = NULL; + } + } + + return (rv); +} + +/* + * This API is used by elfsign. We must keep it in old API form. + */ +KMF_RETURN +KMF_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) +{ + + KMF_ATTRIBUTE attlist[32]; + int i = 0; + + if (params == NULL) + return (KMF_ERR_BAD_PARAMETER); + + kmf_set_attr_at_index(attlist, i, + KMF_KEYSTORE_TYPE_ATTR, ¶ms->kstype, sizeof (params->kstype)); + i++; + + if (params->kstype == KMF_KEYSTORE_NSS) { + if (params->nssconfig.configdir != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_DIRPATH_ATTR, + params->nssconfig.configdir, + strlen(params->nssconfig.configdir)); + i++; + } + if (params->nssconfig.certPrefix != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_CERTPREFIX_ATTR, + params->nssconfig.certPrefix, + strlen(params->nssconfig.certPrefix)); + i++; + } + if (params->nssconfig.keyPrefix != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_KEYPREFIX_ATTR, + params->nssconfig.keyPrefix, + strlen(params->nssconfig.keyPrefix)); + i++; + } + if (params->nssconfig.secModName != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_SECMODNAME_ATTR, + params->nssconfig.secModName, + strlen(params->nssconfig.secModName)); + i++; + } + } else if (params->kstype == KMF_KEYSTORE_PK11TOKEN) { + if (params->pkcs11config.label != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_TOKEN_LABEL_ATTR, + params->pkcs11config.label, + strlen(params->pkcs11config.label)); + i++; + } + kmf_set_attr_at_index(attlist, i, + KMF_READONLY_ATTR, + ¶ms->pkcs11config.readonly, + sizeof (params->pkcs11config.readonly)); + i++; + } + + return (kmf_configure_keystore(handle, i, attlist)); +} + +/* + * This API is used by elfsign. We must keep it in old API form. + */ +KMF_RETURN +KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) +{ + return (kmf_initialize(outhandle, policyfile, policyname)); +} + +/* + * This API is used by elfsign. We must keep it in old API form. + */ +KMF_RETURN +KMF_Finalize(KMF_HANDLE_T handle) +{ + return (kmf_finalize(handle)); +} + +/* + * This API is used by elfsign. We must keep it in old API form. + */ +KMF_RETURN +KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) +{ + return (kmf_get_kmf_error_str(errcode, errmsg)); +} + +/* + * This API is used by elfsign. We must keep it in old API form. + */ +KMF_RETURN +KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) +{ + return (kmf_read_input_file(handle, filename, pdata)); +} + + +/* + * This API is used by elfsign. We must keep it in old API form. + */ +void +KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) +{ + kmf_free_kmf_cert(handle, kmf_cert); +} + +/* + * This API is used by elfsign. We must keep it in old API form. + */ +void +KMF_FreeData(KMF_DATA *datablock) +{ + kmf_free_data(datablock); +} + +/* + * This API is used by elfsign. We must keep it in old API form. + */ +void +KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) +{ + kmf_free_kmf_key(handle, key); +} + +/* + * This API is used by elfsign. We must keep it in old API form. + */ +void +KMF_FreeSignedCSR(KMF_CSR_DATA *csr) +{ + kmf_free_signed_csr(csr); +} diff --git a/usr/src/lib/libkmf/libkmf/common/keyop.c b/usr/src/lib/libkmf/libkmf/common/keyop.c index 42781ecf52..a6eca064f2 100644 --- a/usr/src/lib/libkmf/libkmf/common/keyop.c +++ b/usr/src/lib/libkmf/libkmf/common/keyop.c @@ -37,211 +37,112 @@ #include <libgen.h> #include <cryptoutil.h> -/* - * - * Name: KMF_SignDataWithKey - * - * Description: - * This function signs a block of data using the private key - * and returns the signature in output - * - * Parameters: - * handle(input) - opaque handle for KMF session - * key(input) - contains private key handle needed for signing - * AlgOID(input) - contains algorithm to be used for signing - * tobesigned(input) - pointer to a KMF_DATA structure containing - * the data to be signed - * output(output) - pointer to the KMF_DATA structure containing the - * signed data - * - * Returns: - * A KMF_RETURN value indicating success or specifying a particular - * error condition. - * The value KMF_OK indicates success. All other values represent - * an error condition. - * - */ KMF_RETURN -KMF_SignDataWithKey(KMF_HANDLE_T handle, - KMF_KEY_HANDLE *key, - KMF_OID *AlgOID, - KMF_DATA *tobesigned, - KMF_DATA *output) +kmf_create_keypair(KMF_HANDLE_T handle, + int num_args, + KMF_ATTRIBUTE *attrlist) { - KMF_RETURN ret; + KMF_RETURN ret = KMF_OK; KMF_PLUGIN *plugin; - KMF_ALGORITHM_INDEX AlgId; - KMF_DATA signature = {0, NULL}; + KMF_KEYSTORE_TYPE kstype; + uint32_t len; - CLEAR_ERROR(handle, ret); - if (ret != KMF_OK) - return (ret); - - if (key == NULL || AlgOID == NULL || - tobesigned == NULL || output == NULL) - return (KMF_ERR_BAD_PARAMETER); - - /* - * The plugin must be based on the key since private keys - * cannot be extracted. - */ - plugin = FindPlugin(handle, key->kstype); - if (plugin != NULL && plugin->funclist->SignData != NULL) { - ret = plugin->funclist->SignData(handle, key, - AlgOID, tobesigned, output); - if (ret != KMF_OK) - goto cleanup; - - AlgId = X509_AlgorithmOidToAlgId(AlgOID); - - /* - * For DSA, NSS returns an encoded signature. Decode the - * signature as DSA signature should be 40-byte long. - */ - if ((AlgId == KMF_ALGID_SHA1WithDSA) && - (plugin->type == KMF_KEYSTORE_NSS)) { - ret = DerDecodeDSASignature(output, &signature); - if (ret != KMF_OK) { - goto cleanup; - } else { - output->Length = signature.Length; - (void) memcpy(output->Data, signature.Data, - signature.Length); - } - } else if (AlgId == KMF_ALGID_NONE) { - ret = KMF_ERR_BAD_ALGORITHM; - } - } else { - return (KMF_ERR_PLUGIN_NOTFOUND); - } + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_PRIVKEY_HANDLE_ATTR, FALSE, sizeof (KMF_KEY_HANDLE), + sizeof (KMF_KEY_HANDLE)}, + {KMF_PUBKEY_HANDLE_ATTR, FALSE, sizeof (KMF_KEY_HANDLE), + sizeof (KMF_KEY_HANDLE)}, + }; -cleanup: - if (signature.Data) - free(signature.Data); - return (ret); -} + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); -/* - * - * Name: KMF_VerifyDataWithKey - * - * Description: - * This function verifies the signature of a block of data - * using the input public key - * - * Parameters: - * handle(input) - opaque handle for KMF session - * KMFKey(input) - holds public key information for verification - * sigAlg(input) - algorithm to verify - * indata(input) - pointer to the block of data whose signature - * is to be verified - * insig(input) - pointer to the signature to be verified - * - * Returns: - * A KMF_RETURN value indicating success or specifying a particular - * error condition. - * The value KMF_OK indicates success. All other values represent - * an error condition. - * - */ -KMF_RETURN -KMF_VerifyDataWithKey(KMF_HANDLE_T handle, - KMF_KEY_HANDLE *KMFKey, - KMF_ALGORITHM_INDEX sigAlg, - KMF_DATA *indata, - KMF_DATA *insig) -{ - KMF_RETURN err; - KMF_DATA derkey = {0, NULL}; - KMF_PLUGIN *plugin; - - CLEAR_ERROR(handle, err); - if (err != KMF_OK) - return (err); - - if (KMFKey == NULL || - indata == NULL || insig == NULL) + if (handle == NULL) return (KMF_ERR_BAD_PARAMETER); - plugin = FindPlugin(handle, KMFKey->kstype); - - /* Retrieve public key data from keystore */ - if (plugin != NULL && plugin->funclist->EncodePubkeyData != NULL) { - err = plugin->funclist->EncodePubkeyData(handle, - KMFKey, &derkey); - } else { - return (KMF_ERR_PLUGIN_NOTFOUND); - } - - err = VerifyDataWithKey(handle, &derkey, sigAlg, indata, insig); - - if (derkey.Data != NULL) - free(derkey.Data); - - return (err); -} + CLEAR_ERROR(handle, ret); -KMF_RETURN -KMF_CreateKeypair(KMF_HANDLE_T handle, - KMF_CREATEKEYPAIR_PARAMS *params, - KMF_KEY_HANDLE *privKey, - KMF_KEY_HANDLE *pubKey) -{ - KMF_PLUGIN *plugin; - KMF_RETURN ret; + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, num_args, attrlist); - CLEAR_ERROR(handle, ret); if (ret != KMF_OK) return (ret); - if (params == NULL || - privKey == NULL || pubKey == NULL) - return (KMF_ERR_BAD_PARAMETER); - - (void) memset(privKey, 0, sizeof (KMF_KEY_HANDLE)); - (void) memset(pubKey, 0, sizeof (KMF_KEY_HANDLE)); - plugin = FindPlugin(handle, params->kstype); + len = sizeof (kstype); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args, + &kstype, &len); + if (ret != KMF_OK) + return (ret); + plugin = FindPlugin(handle, kstype); if (plugin != NULL && plugin->funclist->CreateKeypair != NULL) { - return (plugin->funclist->CreateKeypair(handle, params, - privKey, pubKey)); + return (plugin->funclist->CreateKeypair(handle, num_args, + attrlist)); } else { return (KMF_ERR_PLUGIN_NOTFOUND); } } KMF_RETURN -KMF_DeleteKeyFromKeystore(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, - KMF_KEY_HANDLE *key) +kmf_delete_key_from_keystore(KMF_HANDLE_T handle, + int num_args, + KMF_ATTRIBUTE *attrlist) { - KMF_RETURN rv = KMF_OK; + KMF_RETURN ret = KMF_OK; KMF_PLUGIN *plugin; + KMF_KEYSTORE_TYPE kstype; + uint32_t len; + KMF_KEY_HANDLE *key; + - CLEAR_ERROR(handle, rv); - if (rv != KMF_OK) - return (rv); + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_KEY_HANDLE_ATTR, FALSE, sizeof (KMF_KEY_HANDLE), + sizeof (KMF_KEY_HANDLE)}, + }; - if (key == NULL || params == NULL) + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) return (KMF_ERR_BAD_PARAMETER); - plugin = FindPlugin(handle, params->kstype); + CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, num_args, attrlist); + + if (ret != KMF_OK) + return (ret); + + len = sizeof (kstype); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args, + &kstype, &len); + if (ret != KMF_OK) + return (ret); + + plugin = FindPlugin(handle, kstype); if (plugin != NULL && plugin->funclist->DeleteKey != NULL) { - rv = plugin->funclist->DeleteKey(handle, params, key, TRUE); + ret = plugin->funclist->DeleteKey(handle, num_args, attrlist); } else { - rv = KMF_ERR_PLUGIN_NOTFOUND; + ret = KMF_ERR_PLUGIN_NOTFOUND; } - if (rv == KMF_OK) { + if (ret == KMF_OK) { + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, num_args); + if (key == NULL) + return (KMF_ERR_BAD_PARAMETER); if (key->keylabel != NULL) free(key->keylabel); if (key->israw && key->keyp != NULL) { if (key->keyclass == KMF_ASYM_PUB || key->keyclass == KMF_ASYM_PRI) { - KMF_FreeRawKey(key->keyp); + kmf_free_raw_key(key->keyp); free(key->keyp); } else if (key->keyclass == KMF_SYMMETRIC) { - KMF_FreeRawSymKey(key->keyp); + kmf_free_raw_sym_key(key->keyp); } /* Else we don't know how to free the memory. */ } @@ -249,107 +150,101 @@ KMF_DeleteKeyFromKeystore(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, (void) memset(key, 0, sizeof (KMF_KEY_HANDLE)); } - return (rv); + return (ret); } KMF_RETURN -KMF_SignCertRecord(KMF_HANDLE_T handle, KMF_KEY_HANDLE *kmfprikey, - KMF_X509_CERTIFICATE *CertData, KMF_DATA *signedCert) +kmf_find_key(KMF_HANDLE_T handle, + int num_args, + KMF_ATTRIBUTE *attrlist) { - KMF_RETURN ret; - KMF_DATA unsignedCert; + KMF_RETURN ret = KMF_OK; + KMF_PLUGIN *plugin; + KMF_KEYSTORE_TYPE kstype; + uint32_t len; - CLEAR_ERROR(handle, ret); - if (ret != KMF_OK) - return (ret); + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_COUNT_ATTR, FALSE, sizeof (uint32_t), + sizeof (uint32_t)} + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); - if (kmfprikey == NULL || - CertData == NULL || signedCert == NULL) + if (handle == NULL) return (KMF_ERR_BAD_PARAMETER); - ret = KMF_EncodeCertRecord(CertData, &unsignedCert); - if (ret == KMF_OK) - ret = KMF_SignCertWithKey(handle, &unsignedCert, kmfprikey, - signedCert); + CLEAR_ERROR(handle, ret); - KMF_FreeData(&unsignedCert); - return (ret); -} + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, num_args, attrlist); -KMF_RETURN -KMF_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, - KMF_KEY_HANDLE *keys, uint32_t *numkeys) -{ - KMF_PLUGIN *plugin; - KMF_RETURN ret; - - CLEAR_ERROR(handle, ret); if (ret != KMF_OK) return (ret); - if (parms == NULL || numkeys == NULL) - return (KMF_ERR_BAD_PARAMETER); - - plugin = FindPlugin(handle, parms->kstype); + len = sizeof (kstype); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args, + &kstype, &len); + if (ret != KMF_OK) + return (ret); + plugin = FindPlugin(handle, kstype); if (plugin != NULL && plugin->funclist->FindKey != NULL) { - return (plugin->funclist->FindKey(handle, parms, - keys, numkeys)); + return (plugin->funclist->FindKey(handle, num_args, attrlist)); } return (KMF_ERR_PLUGIN_NOTFOUND); } KMF_RETURN -KMF_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, - KMF_RAW_KEY_DATA *rawkey) +kmf_create_sym_key(KMF_HANDLE_T handle, + int num_args, + KMF_ATTRIBUTE *attrlist) { + KMF_RETURN ret = KMF_OK; KMF_PLUGIN *plugin; - KMF_RETURN ret; + KMF_KEYSTORE_TYPE kstype; + uint32_t len; - CLEAR_ERROR(handle, ret); - if (ret != KMF_OK) - return (ret); + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_KEY_HANDLE_ATTR, FALSE, sizeof (KMF_KEY_HANDLE), + sizeof (KMF_KEY_HANDLE)}, + {KMF_KEYALG_ATTR, FALSE, 1, sizeof (KMF_KEY_ALG)}, + }; - if (params == NULL || rawkey == NULL) - return (KMF_ERR_BAD_PARAMETER); + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); - /* Find the private key from the keystore */ - plugin = FindPlugin(handle, params->kstype); + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); - if (plugin != NULL && plugin->funclist->StorePrivateKey != NULL) { - return (plugin->funclist->StorePrivateKey(handle, - params, rawkey)); - } - return (KMF_ERR_PLUGIN_NOTFOUND); -} + CLEAR_ERROR(handle, ret); -KMF_RETURN -KMF_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, - KMF_KEY_HANDLE *symkey) -{ - KMF_PLUGIN *plugin; - KMF_RETURN ret; + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, num_args, attrlist); - CLEAR_ERROR(handle, ret); if (ret != KMF_OK) return (ret); - if (params == NULL || - symkey == NULL) - return (KMF_ERR_BAD_PARAMETER); + len = sizeof (kstype); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args, + &kstype, &len); + if (ret != KMF_OK) + return (ret); - plugin = FindPlugin(handle, params->kstype); + plugin = FindPlugin(handle, kstype); if (plugin != NULL && plugin->funclist->CreateSymKey != NULL) { - return (plugin->funclist->CreateSymKey(handle, params, - symkey)); + return (plugin->funclist->CreateSymKey(handle, num_args, + attrlist)); } else { return (KMF_ERR_PLUGIN_NOTFOUND); } } KMF_RETURN -KMF_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, +kmf_get_sym_key_value(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, KMF_RAW_SYM_KEY *rkey) { KMF_PLUGIN *plugin; @@ -371,3 +266,294 @@ KMF_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, return (KMF_ERR_PLUGIN_NOTFOUND); } } + +KMF_RETURN +kmf_store_key(KMF_HANDLE_T handle, + int numattr, + KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_PLUGIN *plugin; + KMF_KEYSTORE_TYPE kstype; + + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); + + CLEAR_ERROR(handle, ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); + + if (ret != KMF_OK) + return (ret); + + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, + &kstype, NULL); + if (ret != KMF_OK) + return (ret); + + plugin = FindPlugin(handle, kstype); + if (plugin != NULL) { + if (plugin->funclist->StoreKey != NULL) + return (plugin->funclist->StoreKey(handle, + numattr, attrlist)); + else + return (KMF_ERR_FUNCTION_NOT_FOUND); + } + return (KMF_ERR_PLUGIN_NOTFOUND); +} + +/* + * The following are Phase 1 APIs still needed to maintain compat with elfsign. + */ + +/* + * Name: KMF_SignDataWithKey + * + * Description: + * This function signs a block of data using the private key + * and returns the signature in output + * + * Parameters: + * handle(input) - opaque handle for KMF session + * key(input) - contains private key handle needed for signing + * AlgOID(input) - contains algorithm to be used for signing + * tobesigned(input) - pointer to a KMF_DATA structure containing + * the data to be signed + * output(output) - pointer to the KMF_DATA structure containing the + * signed data + * + * Returns: + * A KMF_RETURN value indicating success or specifying a particular + * error condition. + * The value KMF_OK indicates success. All other values represent + * an error condition. + * + */ +KMF_RETURN +KMF_SignDataWithKey(KMF_HANDLE_T handle, + KMF_KEY_HANDLE *key, + KMF_OID *AlgOID, + KMF_DATA *tobesigned, + KMF_DATA *output) +{ + KMF_ATTRIBUTE attlist[5]; /* only 5 attrs for SignData */ + int i = 0; + + if (key == NULL || AlgOID == NULL || + tobesigned == NULL || output == NULL) + return (KMF_ERR_BAD_PARAMETER); + + kmf_set_attr_at_index(attlist, i, + KMF_KEYSTORE_TYPE_ATTR, &key->kstype, sizeof (key->kstype)); + i++; + + kmf_set_attr_at_index(attlist, i, + KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); + i++; + + kmf_set_attr_at_index(attlist, i, + KMF_OID_ATTR, AlgOID, sizeof (KMF_OID)); + i++; + + kmf_set_attr_at_index(attlist, i, + KMF_DATA_ATTR, tobesigned, sizeof (KMF_DATA)); + i++; + + kmf_set_attr_at_index(attlist, i, + KMF_OUT_DATA_ATTR, output, sizeof (KMF_DATA)); + i++; + + return (kmf_sign_data(handle, i, attlist)); +} + + +KMF_RETURN +KMF_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, + KMF_KEY_HANDLE *keys, uint32_t *numkeys) +{ + KMF_ATTRIBUTE attlist[16]; /* Max 16 attributes used here */ + int i = 0; + + if (params == NULL || numkeys == NULL) + return (KMF_ERR_BAD_PARAMETER); + + kmf_set_attr_at_index(attlist, i, + KMF_KEYSTORE_TYPE_ATTR, ¶ms->kstype, sizeof (params->kstype)); + i++; + + if (keys) { + kmf_set_attr_at_index(attlist, i, + KMF_KEY_HANDLE_ATTR, keys, sizeof (KMF_KEY_HANDLE)); + i++; + } + + kmf_set_attr_at_index(attlist, i, + KMF_COUNT_ATTR, numkeys, sizeof (uint32_t)); + i++; + + kmf_set_attr_at_index(attlist, i, + KMF_KEYALG_ATTR, ¶ms->keytype, sizeof (params->keytype)); + i++; + + kmf_set_attr_at_index(attlist, i, + KMF_KEYCLASS_ATTR, ¶ms->keyclass, sizeof (params->keyclass)); + i++; + + kmf_set_attr_at_index(attlist, i, + KMF_ENCODE_FORMAT_ATTR, ¶ms->format, sizeof (params->format)); + i++; + + if (params->findLabel != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_KEYLABEL_ATTR, params->findLabel, + strlen(params->findLabel)); + i++; + } + + if (params->idstr != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_IDSTR_ATTR, params->idstr, + strlen(params->idstr)); + i++; + } + + if (params->cred.credlen > 0) { + kmf_set_attr_at_index(attlist, i, + KMF_CREDENTIAL_ATTR, ¶ms->cred, + sizeof (KMF_CREDENTIAL)); + i++; + } + + if (params->kstype == KMF_KEYSTORE_NSS) { + if (params->nssparms.slotlabel != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_TOKEN_LABEL_ATTR, + params->nssparms.slotlabel, + strlen(params->nssparms.slotlabel)); + i++; + } + } else if (params->kstype == KMF_KEYSTORE_OPENSSL) { + if (params->sslparms.dirpath != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_DIRPATH_ATTR, + params->sslparms.dirpath, + strlen(params->sslparms.dirpath)); + i++; + } + if (params->sslparms.keyfile != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_KEY_FILENAME_ATTR, + params->sslparms.keyfile, + strlen(params->sslparms.keyfile)); + i++; + } + kmf_set_attr_at_index(attlist, i, + KMF_ENCODE_FORMAT_ATTR, + ¶ms->sslparms.format, + sizeof (params->sslparms.format)); + i++; + } else if (params->kstype == KMF_KEYSTORE_PK11TOKEN) { + kmf_set_attr_at_index(attlist, i, + KMF_TOKEN_BOOL_ATTR, + ¶ms->pkcs11parms.token, + sizeof (params->pkcs11parms.token)); + i++; + kmf_set_attr_at_index(attlist, i, + KMF_PRIVATE_BOOL_ATTR, + ¶ms->pkcs11parms.private, + sizeof (params->pkcs11parms.private)); + i++; + } + return (kmf_find_key(handle, i, attlist)); +} + +KMF_RETURN +KMF_CreateKeypair(KMF_HANDLE_T handle, + KMF_CREATEKEYPAIR_PARAMS *params, + KMF_KEY_HANDLE *privKey, + KMF_KEY_HANDLE *pubKey) +{ + KMF_ATTRIBUTE attlist[12]; /* max 12 attrs used here */ + int i = 0; + + if (handle == NULL || params == NULL || + privKey == NULL || pubKey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + (void) memset(privKey, 0, sizeof (KMF_KEY_HANDLE)); + (void) memset(pubKey, 0, sizeof (KMF_KEY_HANDLE)); + + kmf_set_attr_at_index(attlist, i, + KMF_KEYSTORE_TYPE_ATTR, ¶ms->kstype, sizeof (params->kstype)); + i++; + kmf_set_attr_at_index(attlist, i, + KMF_KEYALG_ATTR, ¶ms->keytype, sizeof (params->keytype)); + i++; + kmf_set_attr_at_index(attlist, i, + KMF_KEYLENGTH_ATTR, ¶ms->keylength, sizeof (params->keylength)); + i++; + if (params->keylabel != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_KEYLABEL_ATTR, params->keylabel, + strlen(params->keylabel)); + i++; + } + if (params->cred.credlen > 0) { + kmf_set_attr_at_index(attlist, i, + KMF_CREDENTIAL_ATTR, ¶ms->cred, + sizeof (KMF_CREDENTIAL)); + i++; + } + + if (params->rsa_exponent.len > 0) { + kmf_set_attr_at_index(attlist, i, + KMF_RSAEXP_ATTR, ¶ms->cred, + sizeof (KMF_BIGINT)); + i++; + } + kmf_set_attr_at_index(attlist, i, KMF_PRIVKEY_HANDLE_ATTR, privKey, + sizeof (KMF_KEY_HANDLE)); + i++; + kmf_set_attr_at_index(attlist, i, KMF_PUBKEY_HANDLE_ATTR, pubKey, + sizeof (KMF_KEY_HANDLE)); + i++; + + if (params->kstype == KMF_KEYSTORE_NSS) { + if (params->nssparms.slotlabel != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_TOKEN_LABEL_ATTR, + params->nssparms.slotlabel, + strlen(params->nssparms.slotlabel)); + i++; + } + } else if (params->kstype == KMF_KEYSTORE_OPENSSL) { + if (params->sslparms.dirpath != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_DIRPATH_ATTR, + params->sslparms.dirpath, + strlen(params->sslparms.dirpath)); + i++; + } + if (params->sslparms.keyfile != NULL) { + kmf_set_attr_at_index(attlist, i, + KMF_KEY_FILENAME_ATTR, + params->sslparms.keyfile, + strlen(params->sslparms.keyfile)); + i++; + } + kmf_set_attr_at_index(attlist, i, + KMF_ENCODE_FORMAT_ATTR, + ¶ms->sslparms.format, + sizeof (params->sslparms.format)); + i++; + } + return (kmf_create_keypair(handle, i, attlist)); +} diff --git a/usr/src/lib/libkmf/libkmf/common/mapfile-vers b/usr/src/lib/libkmf/libkmf/common/mapfile-vers index 85424328bd..31ef381e6d 100644 --- a/usr/src/lib/libkmf/libkmf/common/mapfile-vers +++ b/usr/src/lib/libkmf/libkmf/common/mapfile-vers @@ -24,143 +24,8 @@ # ident "%Z%%M% %I% %E% SMI" # -SUNWprivate_1.1 { +SUNW_1.1 { global: - GetIDFromSPKI; - KMF_AddCertEKU; - KMF_AddPolicyToDB; - KMF_CheckCRLDate; - KMF_CheckCertDate; - KMF_CompareRDNs; - KMF_ConfigureKeystore; - KMF_CreateCSRFile; - KMF_CreateCertFile; - KMF_CreateKeypair; - KMF_CreateOCSPRequest; - KMF_CreateSymKey; - KMF_DN2Der; - KMF_DNParser; - KMF_DecodeCertData; - KMF_DecryptWithCert; - KMF_DeleteCRL; - KMF_DeleteCertFromKeystore; - KMF_DeleteKeyFromKeystore; - KMF_DeletePolicyFromDB; - KMF_Der2Pem; - KMF_DownloadCRL; - KMF_DownloadCert; - KMF_EncodeCertRecord; - KMF_EncryptWithCert; - KMF_ExportPK12; - KMF_Finalize; - KMF_FindCRL; - KMF_FindCert; - KMF_FindCertInCRL; - KMF_FindKey; - KMF_FreeAlgOID; - KMF_FreeBigint; - KMF_FreeCRLDistributionPoints; - KMF_FreeDN; - KMF_FreeData; - KMF_FreeEKU; - KMF_FreeEKUPolicy; - KMF_FreeExtension; - KMF_FreeKMFCert; - KMF_FreeKMFKey; - KMF_FreePolicyRecord; - KMF_FreeRawKey; - KMF_FreeRawSymKey; - KMF_FreeSPKI; - KMF_FreeSignedCSR; - KMF_FreeSignedCert; - KMF_FreeString; - KMF_FreeTBSCSR; - KMF_FreeTBSCert; - KMF_GetCertAuthInfoAccessExt; - KMF_GetCertBasicConstraintExt; - KMF_GetCertCriticalExtensions; - KMF_GetCertCRLDistributionPointsExt; - KMF_GetCertEKU; - KMF_GetCertEmailString; - KMF_GetCertEndDateString; - KMF_GetCertExtensionData; - KMF_GetCertExtensionString; - KMF_GetCertIDData; - KMF_GetCertIDString; - KMF_GetCertIssuerNameString; - KMF_GetCertKeyUsageExt; - KMF_GetCertNonCriticalExtensions; - KMF_GetCertPoliciesExt; - KMF_GetCertPubKeyAlgString; - KMF_GetCertPubKeyDataString; - KMF_GetCertSerialNumberString; - KMF_GetCertSignatureAlgString; - KMF_GetCertStartDateString; - KMF_GetCertSubjectNameString; - KMF_GetCertValidity; - KMF_GetCertVersionString; - KMF_GetEncodedOCSPResponse; - KMF_GetFileFormat; - KMF_GetKMFErrorString; - KMF_GetOCSPForCert; - KMF_GetOCSPStatusForCert; - KMF_GetPK11Handle; - KMF_GetPluginErrorString; - KMF_GetPolicy; - KMF_GetSymKeyValue; - KMF_HexString2Bytes; - KMF_ImportCRL; - KMF_ImportCert; - KMF_ImportKeypair; - KMF_ImportPK12; - KMF_Initialize; - KMF_IsCRLFile; - KMF_IsCertFile; - KMF_ListCRL; - KMF_OID2EKUString; - KMF_OID2String; - KMF_PK11TokenLookup; - KMF_Pem2Der; - KMF_ReadInputFile; - KMF_SelectToken; - KMF_SetCSRExtension; - KMF_SetCSRKeyUsage; - KMF_SetCSRPubKey; - KMF_SetCSRSignatureAlgorithm; - KMF_SetCSRSubjectAltName; - KMF_SetCSRSubjectName; - KMF_SetCSRVersion; - KMF_SetCertBasicConstraintExt; - KMF_SetCertExtension; - KMF_SetCertIssuerAltName; - KMF_SetCertIssuerName; - KMF_SetCertKeyUsage; - KMF_SetCertPubKey; - KMF_SetCertSerialNumber; - KMF_SetCertSignatureAlgorithm; - KMF_SetCertSubjectAltName; - KMF_SetCertSubjectName; - KMF_SetCertValidityTimes; - KMF_SetCertVersion; - KMF_SetPolicy; - KMF_SetTokenPin; - KMF_SignCSR; - KMF_SignCertRecord; - KMF_SignCertWithCert; - KMF_SignCertWithKey; - KMF_SignDataWithCert; - KMF_SignDataWithKey; - KMF_StoreCert; - KMF_StorePrivateKey; - KMF_String2OID; - KMF_StringToKeyUsage; - KMF_ValidateCert; - KMF_VerifyCRLFile; - KMF_VerifyCertWithCert; - KMF_VerifyCertWithKey; - KMF_VerifyDataWithCert; - KMF_VerifyDataWithKey; - KMF_VerifyPolicy; KMFOID_AliasedEntryName; KMFOID_AuthorityInfoAccess; KMFOID_AuthorityKeyID; @@ -194,6 +59,7 @@ SUNWprivate_1.1 { KMFOID_CrlReason; KMFOID_CrossCertificatePair; KMFOID_DNQualifier; + KMFOID_DSA; KMFOID_DeltaCrlIndicator; KMFOID_Description; KMFOID_DestinationIndicator; @@ -217,10 +83,13 @@ SUNWprivate_1.1 { KMFOID_KeyUsageRestriction; KMFOID_KnowledgeInformation; KMFOID_LocalityName; + KMFOID_MD2WithRSA; + KMFOID_MD5WithRSA; KMFOID_Member; KMFOID_MessageDigest; KMFOID_Name; KMFOID_NameConstraints; + KMFOID_OIW_DSAWithSHA1; KMFOID_ObjectClass; KMFOID_OrganizationName; KMFOID_OrganizationalUnitName; @@ -249,8 +118,12 @@ SUNWprivate_1.1 { KMFOID_PrivateKeyUsagePeriod; KMFOID_ProtocolInformation; KMFOID_RFC822mailbox; + KMFOID_RSA; KMFOID_RegisteredAddress; KMFOID_RoleOccupant; + KMFOID_SHA1; + KMFOID_SHA1WithDSA; + KMFOID_SHA1WithRSA; KMFOID_SearchGuide; KMFOID_SeeAlso; KMFOID_SerialNumber; @@ -273,28 +146,184 @@ SUNWprivate_1.1 { KMFOID_UserCertificate; KMFOID_UserPassword; KMFOID_VerisignCertificatePolicy; + KMFOID_X9CM_DSA; + KMFOID_X9CM_DSAWithSHA1; KMFOID_X_121Address; KMFOID_domainComponent; KMFOID_userid; - KMFOID_SHA1; - KMFOID_RSA; - KMFOID_DSA; - KMFOID_MD5WithRSA; - KMFOID_MD2WithRSA; - KMFOID_SHA1WithRSA; - KMFOID_SHA1WithDSA; - KMFOID_OIW_DSAWithSHA1; - KMFOID_X9CM_DSA; - KMFOID_X9CM_DSAWithSHA1; - PKCS_GetDefaultSignatureMode; - PKCS_GetAlgorithmMap; - PKCS_AcquirePublicKeyHandle; - X509_AlgIdToAlgorithmOid; - X509_AlgorithmOidToAlgId; - kmf_ekuname2oid; - kmf_string2oid; - ku2str; + kmf_add_cert_eku; + kmf_add_policy_to_db; + kmf_build_pk12; + kmf_check_cert_date; + kmf_check_crl_date; + kmf_compare_rdns; + kmf_configure_keystore; + kmf_create_cert_file; + kmf_create_csr_file; + kmf_create_keypair; + kmf_create_ocsp_request; + kmf_create_sym_key; + kmf_decrypt; + kmf_delete_cert_from_keystore; + kmf_delete_crl; + kmf_delete_key_from_keystore; + kmf_delete_policy_from_db; + kmf_der_to_pem; + kmf_dn_parser; + kmf_download_cert; + kmf_download_crl; + kmf_ekuname_to_oid; + kmf_encode_cert_record; + kmf_encrypt; + kmf_export_pk12; + kmf_finalize; + kmf_find_attr; + kmf_find_cert; + kmf_find_cert_in_crl; + kmf_find_crl; + kmf_find_key; + kmf_free_algoid; + kmf_free_bigint; + kmf_free_crl_dist_pts; + kmf_free_data; + kmf_free_dn; + kmf_free_eku; + kmf_free_eku_policy; + kmf_free_extn; + kmf_free_kmf_cert; + kmf_free_kmf_key; + kmf_free_policy_record; + kmf_free_raw_key; + kmf_free_raw_sym_key; + kmf_free_signed_cert; + kmf_free_signed_csr; + kmf_free_spki; + kmf_free_str; + kmf_free_tbs_cert; + kmf_free_tbs_csr; + kmf_get_attr; + kmf_get_attr_ptr; + kmf_get_cert_auth_info_access; + kmf_get_cert_basic_constraint; + kmf_get_cert_crl_dist_pts; + kmf_get_cert_eku; + kmf_get_cert_email_str; + kmf_get_cert_end_date_str; + kmf_get_cert_extn; + kmf_get_cert_extn_str; + kmf_get_cert_extns; + kmf_get_cert_id_data; + kmf_get_cert_id_str; + kmf_get_cert_issuer_str; + kmf_get_cert_ku; + kmf_get_cert_policies; + kmf_get_cert_pubkey_alg_str; + kmf_get_cert_pubkey_str; + kmf_get_cert_serial_str; + kmf_get_cert_sig_alg_str; + kmf_get_cert_start_date_str; + kmf_get_cert_subject_str; + kmf_get_cert_validity; + kmf_get_cert_version_str; + kmf_get_encoded_ocsp_response; + kmf_get_file_format; + kmf_get_kmf_error_str; + kmf_get_ocsp_for_cert; + kmf_get_ocsp_status_for_cert; + kmf_get_pk11_handle; + kmf_get_plugin_error_str; + kmf_get_policy; + kmf_get_string_attr; + kmf_get_sym_key_value; + kmf_hexstr_to_bytes; + kmf_import_crl; + kmf_import_cert; + kmf_import_objects; + kmf_initialize; + kmf_is_cert_file; + kmf_is_crl_file; + kmf_ku_to_string; + kmf_list_crl; + kmf_oid_to_eku_string; + kmf_oid_to_string; + kmf_pem_to_der; + kmf_pk11_token_lookup; + kmf_read_input_file; + kmf_select_token; + kmf_set_attr; + kmf_set_attr_at_index; + kmf_set_cert_basic_constraint; + kmf_set_cert_extn; + kmf_set_cert_issuer; + kmf_set_cert_issuer_altname; + kmf_set_cert_ku; + kmf_set_cert_pubkey; + kmf_set_cert_serial; + kmf_set_cert_sig_alg; + kmf_set_cert_subject; + kmf_set_cert_subject_altname; + kmf_set_cert_validity; + kmf_set_cert_version; + kmf_set_csr_extn; + kmf_set_csr_ku; + kmf_set_csr_pubkey; + kmf_set_csr_sig_alg; + kmf_set_csr_subject; + kmf_set_csr_subject_altname; + kmf_set_csr_version; + kmf_set_policy; + kmf_set_token_pin; + kmf_sign_cert; + kmf_sign_csr; + kmf_sign_data; + kmf_store_cert; + kmf_store_key; + kmf_string_to_ku; + kmf_string_to_oid; + kmf_validate_cert; + kmf_verify_cert; + kmf_verify_crl_file; + kmf_verify_data; + kmf_verify_policy; + local: + *; +}; + + +SUNWprivate_1.1 { + global: + GetIDFromSPKI; + KMF_ConfigureKeystore; + KMF_CreateCSRFile; + KMF_CreateKeypair; + KMF_DNParser; + KMF_Finalize; + KMF_FindCert; + KMF_FindKey; + KMF_FreeData; + KMF_FreeKMFCert; + KMF_FreeKMFKey; + KMF_FreeSignedCSR; + KMF_GetCertIDString; + KMF_GetCertIssuerNameString; + KMF_GetCertSubjectNameString; + KMF_GetKMFErrorString; + KMF_Initialize; + KMF_ReadInputFile; + KMF_SetCSRPubKey; + KMF_SetCSRSignatureAlgorithm; + KMF_SetCSRSubjectName; + KMF_SetCSRVersion; + KMF_SignCSR; + KMF_SignDataWithKey; + KMF_VerifyCertWithCert; + KMF_VerifyDataWithCert; parsePolicyElement; + PKCS_AcquirePublicKeyHandle; + PKCS_GetDefaultSignatureMode; + pkcs_get_alg_map; + x509_algid_to_algoid; + x509_algoid_to_algid; local: *; }; diff --git a/usr/src/lib/libkmf/libkmf/common/pk11keys.c b/usr/src/lib/libkmf/libkmf/common/pk11keys.c index 66d328968b..5a6e945009 100644 --- a/usr/src/lib/libkmf/libkmf/common/pk11keys.c +++ b/usr/src/lib/libkmf/libkmf/common/pk11keys.c @@ -61,7 +61,7 @@ create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech, } if (i < pulCount) { rv = C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION, - NULL, NULL, sessionp); + NULL, NULL, sessionp); if (rv != CKR_OK) { kmf_rv = KMF_ERR_UNINITIALIZED; @@ -148,8 +148,10 @@ PKCS_CreatePublicKey( /* Parse the keyblob */ (void) memset(KeyParts, 0, sizeof (KeyParts)); - AlgorithmId = X509_AlgorithmOidToAlgId((KMF_OID *) - &pKey->algorithm.algorithm); + AlgorithmId = x509_algoid_to_algid( + (KMF_OID *)&pKey->algorithm.algorithm); + if (AlgorithmId == KMF_ALGID_NONE) + return (KMF_ERR_BAD_ALGORITHM); mrReturn = ExtractSPKIData(pKey, AlgorithmId, KeyParts, &uNumKeyParts); @@ -157,74 +159,46 @@ PKCS_CreatePublicKey( return (mrReturn); /* Fill in the common object attributes */ - if (!PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_CLASS, - (CK_BYTE *)&ckObjClass, - sizeof (ckObjClass)) || - !PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_TOKEN, - (CK_BYTE *)&ckToken, - sizeof (ckToken)) || - !PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_PRIVATE, - (CK_BYTE *)&ckPrivate, - sizeof (ckPrivate))) { + if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_CLASS, (CK_BYTE *)&ckObjClass, + sizeof (ckObjClass)) || + !PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_TOKEN, (CK_BYTE *)&ckToken, + sizeof (ckToken)) || + !PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_PRIVATE, (CK_BYTE *)&ckPrivate, + sizeof (ckPrivate))) { mrReturn = KMF_ERR_INTERNAL; goto cleanup; } /* Fill in the common key attributes */ - if (!PKCS_ConvertAlgorithmId2PKCSKeyType(AlgorithmId, - &ckKeyType)) { + if (!pkcs_algid_to_keytype(AlgorithmId, &ckKeyType)) { goto cleanup; } - if (!PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_KEY_TYPE, - (CK_BYTE *)&ckKeyType, - sizeof (ckKeyType)) || - !PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_DERIVE, - (CK_BYTE *)&ckDerive, - sizeof (ckDerive))) { + if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_KEY_TYPE, (CK_BYTE *)&ckKeyType, + sizeof (ckKeyType)) || + !PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_DERIVE, (CK_BYTE *)&ckDerive, + sizeof (ckDerive))) { mrReturn = KMF_ERR_INTERNAL; goto cleanup; } /* Add common public key attributes */ - if (!PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_ENCRYPT, - (CK_BYTE *)&ckEncrypt, - sizeof (ckEncrypt)) || - !PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_VERIFY, - (CK_BYTE *)&ckVerify, - sizeof (ckVerify)) || - !PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_VERIFY_RECOVER, - (CK_BYTE *)&ckVerifyRecover, - sizeof (ckVerifyRecover)) || - !PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_WRAP, - (CK_BYTE *)&ckWrap, - sizeof (ckWrap))) { + if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_ENCRYPT, (CK_BYTE *)&ckEncrypt, + sizeof (ckEncrypt)) || + !PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_VERIFY, (CK_BYTE *)&ckVerify, + sizeof (ckVerify)) || + !PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_VERIFY_RECOVER, + (CK_BYTE *)&ckVerifyRecover, sizeof (ckVerifyRecover)) || + !PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_WRAP, (CK_BYTE *)&ckWrap, + sizeof (ckWrap))) { mrReturn = KMF_ERR_INTERNAL; goto cleanup; } @@ -232,47 +206,35 @@ PKCS_CreatePublicKey( /* Add algorithm specific attributes */ switch (ckKeyType) { case CKK_RSA: - if (!PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_MODULUS, - (CK_BYTE *)KeyParts[KMF_RSA_MODULUS].Data, - (CK_ULONG)KeyParts[KMF_RSA_MODULUS].Length) || - !PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_PUBLIC_EXPONENT, - (CK_BYTE *)KeyParts[KMF_RSA_PUBLIC_EXPONENT].Data, - (CK_ULONG)KeyParts[KMF_RSA_PUBLIC_EXPONENT].Length)) { - mrReturn = KMF_ERR_INTERNAL; - goto cleanup; + if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_MODULUS, + (CK_BYTE *)KeyParts[KMF_RSA_MODULUS].Data, + (CK_ULONG)KeyParts[KMF_RSA_MODULUS].Length) || + !PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_PUBLIC_EXPONENT, + (CK_BYTE *)KeyParts[KMF_RSA_PUBLIC_EXPONENT].Data, + (CK_ULONG)KeyParts[KMF_RSA_PUBLIC_EXPONENT].Length)) { + mrReturn = KMF_ERR_INTERNAL; + goto cleanup; } break; case CKK_DSA: - if (!PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_PRIME, - (CK_BYTE *)KeyParts[KMF_DSA_PRIME].Data, - (CK_ULONG)KeyParts[KMF_DSA_PRIME].Length) || - !PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_SUBPRIME, - (CK_BYTE *)KeyParts[KMF_DSA_SUB_PRIME].Data, - (CK_ULONG)KeyParts[KMF_DSA_SUB_PRIME].Length) || - !PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_BASE, - (CK_BYTE *)KeyParts[KMF_DSA_BASE].Data, - (CK_ULONG)KeyParts[KMF_DSA_BASE].Length) || - !PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - MAX_PUBLIC_KEY_TEMPLATES, - CKA_VALUE, - (CK_BYTE *)KeyParts[KMF_DSA_PUBLIC_VALUE].Data, - (CK_ULONG)KeyParts[KMF_DSA_PUBLIC_VALUE].Length)) { + if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_PRIME, + (CK_BYTE *)KeyParts[KMF_DSA_PRIME].Data, + (CK_ULONG)KeyParts[KMF_DSA_PRIME].Length) || + !PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_SUBPRIME, + (CK_BYTE *)KeyParts[KMF_DSA_SUB_PRIME].Data, + (CK_ULONG)KeyParts[KMF_DSA_SUB_PRIME].Length) || + !PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_BASE, + (CK_BYTE *)KeyParts[KMF_DSA_BASE].Data, + (CK_ULONG)KeyParts[KMF_DSA_BASE].Length) || + !PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + MAX_PUBLIC_KEY_TEMPLATES, CKA_VALUE, + (CK_BYTE *)KeyParts[KMF_DSA_PUBLIC_VALUE].Data, + (CK_ULONG)KeyParts[KMF_DSA_PUBLIC_VALUE].Length)) { mrReturn = KMF_ERR_INTERNAL; goto cleanup; } @@ -283,17 +245,15 @@ PKCS_CreatePublicKey( if (mrReturn == KMF_OK) { /* Instantiate the object */ - ckRv = C_CreateObject(ckSession, - ckTemplate, - ckNumTemplates, - pckPublicKey); + ckRv = C_CreateObject(ckSession, ckTemplate, + ckNumTemplates, pckPublicKey); if (ckRv != CKR_OK) mrReturn = KMF_ERR_INTERNAL; } cleanup: for (i = 0; i < uNumKeyParts; i++) { - KMF_FreeData(&KeyParts[i]); + kmf_free_data(&KeyParts[i]); } return (mrReturn); @@ -331,7 +291,7 @@ PKCS_AcquirePublicKeyHandle(CK_SESSION_HANDLE ckSession, CK_ATTRIBUTE ckTemplate[3]; CK_ULONG ckNumTemplates; static const CK_ULONG ckMaxTemplates = (sizeof (ckTemplate) / - sizeof (CK_ATTRIBUTE)); + sizeof (CK_ATTRIBUTE)); CK_RV ckRv; /* Extract the data from the SPKI into individual fields */ @@ -343,31 +303,23 @@ PKCS_AcquirePublicKeyHandle(CK_SESSION_HANDLE ckSession, /* Fetch the key class and algorithm from the object */ ckNumTemplates = 0; - if (!PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - ckMaxTemplates, - CKA_CLASS, - (CK_BYTE *)&ckObjClass, - sizeof (ckObjClass)) || - !PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - ckMaxTemplates, - CKA_KEY_TYPE, - (CK_BYTE *)&ckKeyType, - sizeof (ckKeyType))) { + if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + ckMaxTemplates, CKA_CLASS, (CK_BYTE *)&ckObjClass, + sizeof (ckObjClass)) || + !PKCS_AddTemplate(ckTemplate, &ckNumTemplates, + ckMaxTemplates, CKA_KEY_TYPE, (CK_BYTE *)&ckKeyType, + sizeof (ckKeyType))) { return (KMF_ERR_INTERNAL); } - ckRv = C_GetAttributeValue(ckSession, - ckKeyHandle, - ckTemplate, - ckNumTemplates); + ckRv = C_GetAttributeValue(ckSession, ckKeyHandle, + ckTemplate, ckNumTemplates); if (ckRv != CKR_OK) { return (ckRv); } /* Make sure the results match the expected values */ if ((ckKeyType != ckRequestedKeyType) || - (ckObjClass != CKO_PUBLIC_KEY)) { + (ckObjClass != CKO_PUBLIC_KEY)) { if (*pbTemporary == KMF_TRUE) { (void) C_DestroyObject(ckSession, ckKeyHandle); } @@ -419,21 +371,21 @@ PKCS_VerifyData(KMF_HANDLE_T kmfh, if (AlgorithmId == KMF_ALGID_NONE) return (KMF_ERR_BAD_ALGORITHM); - pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, - AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); + pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, + AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); if (!pAlgMap) return (KMF_ERR_BAD_ALGORITHM); rv = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism, - CKF_VERIFY); + CKF_VERIFY); if (rv != KMF_OK) return (rv); /* Fetch the verifying key */ rv = PKCS_AcquirePublicKeyHandle(ckSession, keyp, - pAlgMap->key_type, &ckKeyHandle, &bTempKey); + pAlgMap->key_type, &ckKeyHandle, &bTempKey); if (rv != KMF_OK) { (void) C_CloseSession(ckSession); @@ -454,11 +406,10 @@ PKCS_VerifyData(KMF_HANDLE_T kmfh, return (KMF_ERR_INTERNAL); } - ckRv = C_Verify(ckSession, - (CK_BYTE *)data->Data, - (CK_ULONG)data->Length, - (CK_BYTE *)signed_data->Data, - (CK_ULONG)signed_data->Length); + ckRv = C_Verify(ckSession, (CK_BYTE *)data->Data, + (CK_ULONG)data->Length, + (CK_BYTE *)signed_data->Data, + (CK_ULONG)signed_data->Length); if (ckRv != CKR_OK) { kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; @@ -493,16 +444,16 @@ PKCS_EncryptData(KMF_HANDLE_T kmfh, CK_ATTRIBUTE ckTemplate[2]; CK_ULONG ckNumTemplates; CK_ULONG ckMaxTemplates = (sizeof (ckTemplate) / - sizeof (CK_ATTRIBUTE)); + sizeof (CK_ATTRIBUTE)); - pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, + pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); if (!pAlgMap) return (KMF_ERR_BAD_ALGORITHM); rv = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism, - CKF_ENCRYPT); + CKF_ENCRYPT); if (rv != KMF_OK) return (rv); @@ -518,22 +469,16 @@ PKCS_EncryptData(KMF_HANDLE_T kmfh, /* Get the modulus length */ ckNumTemplates = 0; - if (!PKCS_AddTemplate(ckTemplate, - &ckNumTemplates, - ckMaxTemplates, - CKA_MODULUS, - (CK_BYTE *)NULL, - sizeof (CK_ULONG))) { + if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates, ckMaxTemplates, + CKA_MODULUS, (CK_BYTE *)NULL, sizeof (CK_ULONG))) { if (bTempKey) (void) C_DestroyObject(ckSession, ckKeyHandle); (void) C_CloseSession(ckSession); return (KMF_ERR_INTERNAL); } - ckRv = C_GetAttributeValue(ckSession, - ckKeyHandle, - ckTemplate, - ckNumTemplates); + ckRv = C_GetAttributeValue(ckSession, ckKeyHandle, + ckTemplate, ckNumTemplates); if (ckRv != CKR_OK) { if (bTempKey) @@ -661,7 +606,9 @@ GetIDFromSPKI(KMF_X509_SPKI *spki, KMF_DATA *ID) ID->Length = SHA1_HASH_LENGTH; - algId = X509_AlgorithmOidToAlgId(&spki->algorithm.algorithm); + algId = x509_algoid_to_algid(&spki->algorithm.algorithm); + if (algId == KMF_ALGID_NONE) + return (KMF_ERR_BAD_ALGORITHM); rv = ExtractSPKIData(spki, algId, KeyParts, &uNumKeyParts); if (rv != KMF_OK) @@ -677,7 +624,6 @@ GetIDFromSPKI(KMF_X509_SPKI *spki, KMF_DATA *ID) rv = KMF_ERR_BAD_ALGORITHM; } - for (i = 0; i < uNumKeyParts; i++) { if (KeyParts[i].Data != NULL) free(KeyParts[i].Data); diff --git a/usr/src/lib/libkmf/libkmf/common/pk11tokens.c b/usr/src/lib/libkmf/libkmf/common/pk11tokens.c index 80909114e2..2e37a31f78 100644 --- a/usr/src/lib/libkmf/libkmf/common/pk11tokens.c +++ b/usr/src/lib/libkmf/libkmf/common/pk11tokens.c @@ -105,6 +105,16 @@ kmf_get_token_slots(KMF_HANDLE *handle, CK_SLOT_ID_PTR *slot_list, CK_SLOT_ID_PTR tmp_list = NULL_PTR, tmp2_list = NULL_PTR; ck_rv = C_GetSlotList(1, NULL_PTR, &tmp_count); + if (ck_rv == CKR_CRYPTOKI_NOT_INITIALIZED) { + ck_rv = C_Initialize(NULL); + if ((ck_rv != CKR_OK) && + (ck_rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) + return (KMF_ERR_UNINITIALIZED); + if (ck_rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) + ck_rv = CKR_OK; + + ck_rv = C_GetSlotList(1, NULL_PTR, &tmp_count); + } if (ck_rv != CKR_OK) { if (handle != NULL) { handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; @@ -281,7 +291,7 @@ parse_token_spec(char *token_spec, char **token_name, char **manuf_id, * are delimited by the colon ':' character. */ KMF_RETURN -KMF_PK11TokenLookup(KMF_HANDLE_T handle, char *label, CK_SLOT_ID *slot_id) +kmf_pk11_token_lookup(KMF_HANDLE_T handle, char *label, CK_SLOT_ID *slot_id) { KMF_RETURN kmf_rv = KMF_OK; CK_RV rv; @@ -298,9 +308,9 @@ KMF_PK11TokenLookup(KMF_HANDLE_T handle, char *label, CK_SLOT_ID *slot_id) char *token_name = NULL; char *manuf_id = NULL; char *serial_no = NULL; - boolean_t tok_match = B_FALSE, - man_match = B_FALSE, - ser_match = B_FALSE; + boolean_t tok_match = B_FALSE; + boolean_t man_match = B_FALSE; + boolean_t ser_match = B_FALSE; if (slot_id == NULL || label == NULL || !strlen(label)) return (KMF_ERR_BAD_PARAMETER); @@ -322,7 +332,7 @@ KMF_PK11TokenLookup(KMF_HANDLE_T handle, char *label, CK_SLOT_ID *slot_id) return (KMF_ERR_MEMORY); if (parse_token_spec(tmplabel, &token_name, &manuf_id, - &serial_no) < 0) { + &serial_no) < 0) { free(tmplabel); return (KMF_ERR_BAD_PARAMETER); } @@ -350,7 +360,7 @@ KMF_PK11TokenLookup(KMF_HANDLE_T handle, char *label, CK_SLOT_ID *slot_id) len = strlen(token_name); max_sz = sizeof (token_info.label); if (memcmp_pad_max(&(token_info.label), max_sz, token_name, - len, max_sz) == 0) + len, max_sz) == 0) tok_match = B_TRUE; /* * If manufacturer id was given, see if it actually matches. @@ -424,43 +434,56 @@ KMF_PK11TokenLookup(KMF_HANDLE_T handle, char *label, CK_SLOT_ID *slot_id) } KMF_RETURN -KMF_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, - KMF_CREDENTIAL *newpin) +kmf_set_token_pin(KMF_HANDLE_T handle, + int num_attr, + KMF_ATTRIBUTE *attrlist) { - KMF_RETURN rv = KMF_OK; + KMF_RETURN ret = KMF_OK; KMF_PLUGIN *plugin; - - CLEAR_ERROR(handle, rv); - if (rv != KMF_OK) - return (rv); - - if (params == NULL || newpin == NULL) + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, + {KMF_CREDENTIAL_ATTR, FALSE, sizeof (KMF_CREDENTIAL), + sizeof (KMF_CREDENTIAL)}, + {KMF_NEWPIN_ATTR, FALSE, sizeof (KMF_CREDENTIAL), + sizeof (KMF_CREDENTIAL)}, + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + uint32_t len; + KMF_KEYSTORE_TYPE kstype; + + if (handle == NULL) return (KMF_ERR_BAD_PARAMETER); - /* - * If setting PKCS#11 token look for the slot. - */ - if (params->kstype == KMF_KEYSTORE_PK11TOKEN) { - rv = KMF_PK11TokenLookup(NULL, params->tokenname, - ¶ms->pkcs11parms.slot); - if (rv != KMF_OK) - return (rv); + CLEAR_ERROR(handle, ret); + if (ret != KMF_OK) + return (ret); + + ret = test_attributes(num_req_attrs, required_attrs, + 0, NULL, num_attr, attrlist); + if (ret != KMF_OK) + return (ret); + + len = sizeof (kstype); + ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_attr, + &kstype, &len); + if (ret != KMF_OK) + return (ret); + + plugin = FindPlugin(handle, kstype); + if (plugin != NULL) { + if (plugin->funclist->SetTokenPin != NULL) + return (plugin->funclist->SetTokenPin(handle, num_attr, + attrlist)); + else + return (KMF_ERR_FUNCTION_NOT_FOUND); } - - plugin = FindPlugin(handle, params->kstype); - if (plugin == NULL) - return (KMF_ERR_PLUGIN_NOTFOUND); - if (plugin->funclist->SetTokenPin == NULL) - return (KMF_ERR_FUNCTION_NOT_FOUND); - - rv = plugin->funclist->SetTokenPin(handle, params, newpin); - - return (rv); + return (KMF_ERR_PLUGIN_NOTFOUND); } /* - * - * Name: KMF_SelectToken + * Name: kmf_select_token * * Description: * This function enables the user of PKCS#11 plugin to select a @@ -477,11 +500,9 @@ KMF_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, * error condition. * The value KMF_OK indicates success. All other values represent * an error condition. - * */ KMF_RETURN -KMF_SelectToken(KMF_HANDLE_T handle, char *label, - int readonly) +kmf_select_token(KMF_HANDLE_T handle, char *label, int readonly) { KMF_RETURN kmf_rv = KMF_OK; CK_RV ck_rv = CKR_OK; @@ -508,7 +529,7 @@ KMF_SelectToken(KMF_HANDLE_T handle, char *label, } /* Find the token with matching label */ - kmf_rv = KMF_PK11TokenLookup(handle, label, &slot_id); + kmf_rv = kmf_pk11_token_lookup(handle, label, &slot_id); if (kmf_rv != KMF_OK) { return (kmf_rv); } @@ -531,7 +552,7 @@ KMF_SelectToken(KMF_HANDLE_T handle, char *label, } CK_SESSION_HANDLE -KMF_GetPK11Handle(KMF_HANDLE_T kmfh) +kmf_get_pk11_handle(KMF_HANDLE_T kmfh) { return (kmfh->pk11handle); } diff --git a/usr/src/lib/libkmf/libkmf/common/policy.c b/usr/src/lib/libkmf/libkmf/common/policy.c index 5e41f9f42a..d9c3b1b754 100644 --- a/usr/src/lib/libkmf/libkmf/common/policy.c +++ b/usr/src/lib/libkmf/libkmf/common/policy.c @@ -18,7 +18,7 @@ * * CDDL HEADER END * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -77,7 +77,7 @@ parseOCSPValidation(xmlNodePtr node, KMF_VALIDATION_POLICY *vinfo) n = node->children; while (n != NULL) { if (!xmlStrcmp((const xmlChar *)n->name, - (const xmlChar *)KMF_OCSP_BASIC_ELEMENT)) { + (const xmlChar *)KMF_OCSP_BASIC_ELEMENT)) { vinfo->ocsp_info.basic.responderURI = (char *)xmlGetProp(n, @@ -111,8 +111,8 @@ parseOCSPValidation(xmlNodePtr node, KMF_VALIDATION_POLICY *vinfo) (char *)xmlGetProp(n, (const xmlChar *)KMF_CERT_NAME_ATTR); vinfo->ocsp_info.resp_cert.serial = - (char *)xmlGetProp(n, - (const xmlChar *)KMF_CERT_SERIAL_ATTR); + (char *)xmlGetProp(n, + (const xmlChar *)KMF_CERT_SERIAL_ATTR); vinfo->ocsp_info.has_resp_cert = 1; } @@ -133,23 +133,23 @@ parseValidation(xmlNodePtr node, KMF_VALIDATION_POLICY *vinfo, n = node->children; while (n != NULL) { if (!xmlStrcmp((const xmlChar *)n->name, - (const xmlChar *)KMF_OCSP_ELEMENT)) { + (const xmlChar *)KMF_OCSP_ELEMENT)) { parseOCSPValidation(n, &policy->validation_info); policy->revocation |= KMF_REVOCATION_METHOD_OCSP; } else if (!xmlStrcmp((const xmlChar *)n->name, - (const xmlChar *)KMF_CRL_ELEMENT)) { + (const xmlChar *)KMF_CRL_ELEMENT)) { vinfo->crl_info.basefilename = (char *)xmlGetProp(n, - (const xmlChar *)KMF_CRL_BASENAME_ATTR); + (const xmlChar *)KMF_CRL_BASENAME_ATTR); vinfo->crl_info.directory = (char *)xmlGetProp(n, - (const xmlChar *)KMF_CRL_DIRECTORY_ATTR); + (const xmlChar *)KMF_CRL_DIRECTORY_ATTR); c = (char *)xmlGetProp(n, - (const xmlChar *)KMF_CRL_GET_URI_ATTR); + (const xmlChar *)KMF_CRL_GET_URI_ATTR); if (c != NULL && !strcasecmp(c, "true")) { vinfo->crl_info.get_crl_uri = 1; } else { @@ -161,7 +161,7 @@ parseValidation(xmlNodePtr node, KMF_VALIDATION_POLICY *vinfo, (const xmlChar *)KMF_CRL_PROXY_ATTR); c = (char *)xmlGetProp(n, - (const xmlChar *)KMF_CRL_IGNORE_SIGN_ATTR); + (const xmlChar *)KMF_CRL_IGNORE_SIGN_ATTR); if (c != NULL && !strcasecmp(c, "true")) { vinfo->crl_info.ignore_crl_sign = 1; } else { @@ -170,7 +170,7 @@ parseValidation(xmlNodePtr node, KMF_VALIDATION_POLICY *vinfo, xmlFree(c); c = (char *)xmlGetProp(n, - (const xmlChar *)KMF_CRL_IGNORE_DATE_ATTR); + (const xmlChar *)KMF_CRL_IGNORE_DATE_ATTR); if (c != NULL && !strcasecmp(c, "true")) { vinfo->crl_info.ignore_crl_date = 1; } else { @@ -186,7 +186,7 @@ parseValidation(xmlNodePtr node, KMF_VALIDATION_POLICY *vinfo, } char * -ku2str(uint32_t bitfield) +kmf_ku_to_string(uint32_t bitfield) { if (bitfield & KMF_digitalSignature) return ("digitalSignature"); @@ -218,8 +218,8 @@ ku2str(uint32_t bitfield) return (NULL); } -uint16_t -KMF_StringToKeyUsage(char *kustring) +uint32_t +kmf_string_to_ku(char *kustring) { if (kustring == NULL || !strlen(kustring)) return (0); @@ -254,11 +254,11 @@ parseKeyUsageSet(xmlNodePtr node, uint32_t *kubits) n = node->children; while (n != NULL) { if (!xmlStrcmp((const xmlChar *)n->name, - (const xmlChar *)KMF_KEY_USAGE_ELEMENT)) { + (const xmlChar *)KMF_KEY_USAGE_ELEMENT)) { c = (char *)xmlGetProp(n, - (const xmlChar *)KMF_KEY_USAGE_USE_ATTR); + (const xmlChar *)KMF_KEY_USAGE_USE_ATTR); if (c) { - *kubits |= KMF_StringToKeyUsage(c); + *kubits |= kmf_string_to_ku(c); xmlFree(c); } } @@ -288,7 +288,7 @@ dup_oid(KMF_OID *oldoid) } KMF_OID * -kmf_ekuname2oid(char *ekuname) +kmf_ekuname_to_oid(char *ekuname) { KMF_OID *oid; int i; @@ -307,131 +307,18 @@ kmf_ekuname2oid(char *ekuname) } char * -KMF_OID2EKUString(KMF_OID *oid) +kmf_oid_to_eku_string(KMF_OID *oid) { int i; for (i = 0; i < num_ekus; i++) { if (oid->Length == EKUList[i].oid->Length && - !memcmp(oid->Data, EKUList[i].oid->Data, oid->Length)) { + !memcmp(oid->Data, EKUList[i].oid->Data, oid->Length)) { return (EKUList[i].ekuname); } } return (NULL); } -/* - * Convert a human-readable OID string of the form "1.2.3.4" or - * "1 2 3 4" into a KMF_OID value. - */ -KMF_OID * -kmf_string2oid(char *oidstring) -{ - KMF_OID *oid = NULL; - char *cp, *bp, *startp; - int numbuf; - int onumbuf; - int nbytes, index; - int len; - unsigned char *op; - - if (oidstring == NULL) - return (NULL); - - len = strlen(oidstring); - - bp = oidstring; - cp = bp; - /* Skip over leading space */ - while ((bp < &cp[len]) && isspace(*bp)) - bp++; - - startp = bp; - nbytes = 0; - - /* - * The first two numbers are chewed up by the first octet. - */ - if (sscanf(bp, "%d", &numbuf) != 1) - return (NULL); - while ((bp < &cp[len]) && isdigit(*bp)) - bp++; - while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) - bp++; - if (sscanf(bp, "%d", &numbuf) != 1) - return (NULL); - while ((bp < &cp[len]) && isdigit(*bp)) - bp++; - while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) - bp++; - nbytes++; - - while (isdigit(*bp)) { - if (sscanf(bp, "%d", &numbuf) != 1) - return (NULL); - while (numbuf) { - nbytes++; - numbuf >>= 7; - } - while ((bp < &cp[len]) && isdigit(*bp)) - bp++; - while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) - bp++; - } - - oid = malloc(sizeof (KMF_OID)); - if (oid == NULL) - return (NULL); - - oid->Length = nbytes; - oid->Data = malloc(oid->Length); - if (oid->Data == NULL) { - free(oid); - return (NULL); - } - (void) memset(oid->Data, 0, oid->Length); - - op = oid->Data; - - bp = startp; - (void) sscanf(bp, "%d", &numbuf); - - while (isdigit(*bp)) bp++; - while (isspace(*bp) || *bp == '.') bp++; - - onumbuf = 40 * numbuf; - (void) sscanf(bp, "%d", &numbuf); - onumbuf += numbuf; - *op = (unsigned char) onumbuf; - op++; - - while (isdigit(*bp)) bp++; - while (isspace(*bp) || *bp == '.') bp++; - while (isdigit(*bp)) { - (void) sscanf(bp, "%d", &numbuf); - nbytes = 0; - /* Have to fill in the bytes msb-first */ - onumbuf = numbuf; - while (numbuf) { - nbytes++; - numbuf >>= 7; - } - numbuf = onumbuf; - op += nbytes; - index = -1; - while (numbuf) { - op[index] = (unsigned char)numbuf & 0x7f; - if (index != -1) - op[index] |= 0x80; - index--; - numbuf >>= 7; - } - while (isdigit(*bp)) bp++; - while (isspace(*bp) || *bp == '.') bp++; - } - - return (oid); -} - static KMF_RETURN parseExtKeyUsage(xmlNodePtr node, KMF_EKU_POLICY *ekus) { @@ -442,23 +329,29 @@ parseExtKeyUsage(xmlNodePtr node, KMF_EKU_POLICY *ekus) n = node->children; while (n != NULL && ret == KMF_OK) { - KMF_OID *newoid = NULL; + KMF_OID newoid, *oidptr; + + oidptr = NULL; + newoid.Data = NULL; + newoid.Length = 0; if (!xmlStrcmp((const xmlChar *)n->name, - (const xmlChar *)KMF_EKU_NAME_ELEMENT)) { + (const xmlChar *)KMF_EKU_NAME_ELEMENT)) { c = (char *)xmlGetProp(n, - (const xmlChar *)KMF_EKU_NAME_ATTR); + (const xmlChar *)KMF_EKU_NAME_ATTR); if (c != NULL) { - newoid = kmf_ekuname2oid(c); + oidptr = kmf_ekuname_to_oid(c); xmlFree(c); found = TRUE; + if (oidptr != NULL) + newoid = *oidptr; } } else if (!xmlStrcmp((const xmlChar *)n->name, - (const xmlChar *)KMF_EKU_OID_ELEMENT)) { + (const xmlChar *)KMF_EKU_OID_ELEMENT)) { c = (char *)xmlGetProp(n, - (const xmlChar *)KMF_EKU_OID_ATTR); + (const xmlChar *)KMF_EKU_OID_ATTR); if (c != NULL) { - newoid = kmf_string2oid(c); + (void) kmf_string_to_oid(c, &newoid); xmlFree(c); found = TRUE; } @@ -469,29 +362,18 @@ parseExtKeyUsage(xmlNodePtr node, KMF_EKU_POLICY *ekus) continue; } - if (newoid != NULL) { + if (newoid.Data != NULL) { ekus->eku_count++; ekus->ekulist = realloc(ekus->ekulist, - ekus->eku_count * sizeof (KMF_OID)); + ekus->eku_count * sizeof (KMF_OID)); if (ekus->ekulist != NULL) { ekus->ekulist[ekus->eku_count-1].Length = - newoid->Length; + newoid.Length; ekus->ekulist[ekus->eku_count-1].Data = - malloc(newoid->Length); - if (ekus->ekulist[ekus->eku_count-1].Data == - NULL) { - ret = KMF_ERR_MEMORY; - } else { - (void) memcpy( - ekus->ekulist[ekus->eku_count-1]. - Data, - newoid->Data, newoid->Length); - } + newoid.Data; } else { ret = KMF_ERR_MEMORY; } - KMF_FreeData(newoid); - free(newoid); } else { ret = KMF_ERR_POLICY_DB_FORMAT; } @@ -512,10 +394,10 @@ parsePolicyElement(xmlNodePtr node, KMF_POLICY_RECORD *policy) if (node->type == XML_ELEMENT_NODE) { if (node->properties != NULL) { policy->name = (char *)xmlGetProp(node, - (const xmlChar *)KMF_POLICY_NAME_ATTR); + (const xmlChar *)KMF_POLICY_NAME_ATTR); c = (char *)xmlGetProp(node, - (const xmlChar *)KMF_OPTIONS_IGNORE_DATE_ATTR); + (const xmlChar *)KMF_OPTIONS_IGNORE_DATE_ATTR); if (c && !strcasecmp(c, "true")) { policy->ignore_date = 1; xmlFree((xmlChar *)c); @@ -544,20 +426,20 @@ parsePolicyElement(xmlNodePtr node, KMF_POLICY_RECORD *policy) } policy->ta_name = (char *)xmlGetProp(node, - (const xmlChar *)KMF_POLICY_TA_NAME_ATTR); + (const xmlChar *)KMF_POLICY_TA_NAME_ATTR); policy->ta_serial = (char *)xmlGetProp(node, - (const xmlChar *)KMF_POLICY_TA_SERIAL_ATTR); + (const xmlChar *)KMF_POLICY_TA_SERIAL_ATTR); } n = node->children; while (n != NULL) { if (!xmlStrcmp((const xmlChar *)n->name, - (const xmlChar *)KMF_VALIDATION_METHODS_ELEMENT)) + (const xmlChar *)KMF_VALIDATION_METHODS_ELEMENT)) parseValidation(n, &policy->validation_info, policy); else if (!xmlStrcmp((const xmlChar *)n->name, - (const xmlChar *)KMF_KEY_USAGE_SET_ELEMENT)) + (const xmlChar *)KMF_KEY_USAGE_SET_ELEMENT)) parseKeyUsageSet(n, &policy->ku_bits); else if (!xmlStrcmp((const xmlChar *)n->name, (const xmlChar *)KMF_EKU_ELEMENT)) { @@ -580,7 +462,7 @@ newprop(xmlNodePtr node, char *attrname, char *src) if (src != NULL && strlen(src)) { newattr = xmlNewProp(node, (const xmlChar *)attrname, - (xmlChar *)src); + (xmlChar *)src); if (newattr == NULL) { xmlUnlinkNode(node); xmlFreeNode(node); @@ -660,7 +542,7 @@ AddOCSPNodes(xmlNodePtr parent, KMF_OCSP_POLICY *ocsp) /* basic node */ n_ocsp = xmlNewChild(parent, NULL, - (const xmlChar *)KMF_OCSP_ELEMENT, NULL); + (const xmlChar *)KMF_OCSP_ELEMENT, NULL); if (n_ocsp == NULL) return (-1); addFormatting(n_ocsp, "\n\t\t\t"); @@ -680,7 +562,7 @@ AddOCSPNodes(xmlNodePtr parent, KMF_OCSP_POLICY *ocsp) return (-1); if (basic->response_lifetime && newprop(n_basic, KMF_OCSP_RESPONSE_LIFETIME_ATTR, - basic->response_lifetime)) + basic->response_lifetime)) return (-1); if (basic->ignore_response_sign && newprop(n_basic, KMF_OCSP_IGNORE_SIGN_ATTR, "TRUE")) @@ -721,7 +603,7 @@ AddValidationNodes(xmlNodePtr parent, KMF_POLICY_RECORD *policy) addFormatting(parent, "\t"); mnode = xmlNewChild(parent, NULL, - (const xmlChar *)KMF_VALIDATION_METHODS_ELEMENT, NULL); + (const xmlChar *)KMF_VALIDATION_METHODS_ELEMENT, NULL); if (mnode == NULL) return (-1); @@ -768,17 +650,17 @@ AddKeyUsageNodes(xmlNodePtr parent, uint32_t kubits) addFormatting(parent, "\n\t"); kuset = xmlNewChild(parent, NULL, - (const xmlChar *)KMF_KEY_USAGE_SET_ELEMENT, NULL); + (const xmlChar *)KMF_KEY_USAGE_SET_ELEMENT, NULL); if (kuset == NULL) return (KMF_ERR_POLICY_ENGINE); for (i = KULOWBIT; i <= KUHIGHBIT && ret == KMF_OK; i++) { - char *s = ku2str((kubits & (1<<i))); + char *s = kmf_ku_to_string((kubits & (1<<i))); if (s != NULL) { addFormatting(kuset, "\n\t\t"); kunode = xmlNewChild(kuset, NULL, - (const xmlChar *)KMF_KEY_USAGE_ELEMENT, NULL); + (const xmlChar *)KMF_KEY_USAGE_ELEMENT, NULL); if (kunode == NULL) ret = KMF_ERR_POLICY_ENGINE; @@ -811,17 +693,17 @@ AddExtKeyUsageNodes(xmlNodePtr parent, KMF_EKU_POLICY *ekus) if (ekus != NULL && ekus->eku_count > 0) { addFormatting(parent, "\n\t"); n = xmlNewChild(parent, NULL, - (const xmlChar *)KMF_EKU_ELEMENT, NULL); + (const xmlChar *)KMF_EKU_ELEMENT, NULL); if (n == NULL) return (KMF_ERR_POLICY_ENGINE); for (i = 0; i < ekus->eku_count; i++) { - char *s = KMF_OID2String(&ekus->ekulist[i]); + char *s = kmf_oid_to_string(&ekus->ekulist[i]); if (s != NULL) { addFormatting(n, "\n\t\t"); kunode = xmlNewChild(n, NULL, - (const xmlChar *)KMF_EKU_OID_ELEMENT, - NULL); + (const xmlChar *)KMF_EKU_OID_ELEMENT, + NULL); if (kunode == NULL) ret = KMF_ERR_POLICY_ENGINE; @@ -844,12 +726,12 @@ AddExtKeyUsageNodes(xmlNodePtr parent, KMF_EKU_POLICY *ekus) } void -KMF_FreeEKUPolicy(KMF_EKU_POLICY *ekus) +kmf_free_eku_policy(KMF_EKU_POLICY *ekus) { if (ekus->eku_count > 0) { int i; for (i = 0; i < ekus->eku_count; i++) { - KMF_FreeData(&ekus->ekulist[i]); + kmf_free_data(&ekus->ekulist[i]); } free(ekus->ekulist); } @@ -858,7 +740,7 @@ KMF_FreeEKUPolicy(KMF_EKU_POLICY *ekus) #define FREE_POLICY_STR(s) if (s != NULL) free(s); void -KMF_FreePolicyRecord(KMF_POLICY_RECORD *policy) +kmf_free_policy_record(KMF_POLICY_RECORD *policy) { if (policy == NULL) return; @@ -876,18 +758,18 @@ KMF_FreePolicyRecord(KMF_POLICY_RECORD *policy) FREE_POLICY_STR(policy->ta_name) FREE_POLICY_STR(policy->ta_serial) - KMF_FreeEKUPolicy(&policy->eku_set); + kmf_free_eku_policy(&policy->eku_set); (void) memset(policy, 0, sizeof (KMF_POLICY_RECORD)); } /* - * KMF_GetPolicy + * kmf_get_policy * * Find a policy record in the database. */ KMF_RETURN -KMF_GetPolicy(char *filename, char *policy_name, KMF_POLICY_RECORD *plc) +kmf_get_policy(char *filename, char *policy_name, KMF_POLICY_RECORD *plc) { KMF_RETURN ret = KMF_OK; xmlParserCtxtPtr ctxt; @@ -926,10 +808,10 @@ KMF_GetPolicy(char *filename, char *policy_name, KMF_POLICY_RECORD *plc) * Search for the policy that matches the given name. */ if (!xmlStrcmp((const xmlChar *)node->name, - (const xmlChar *)KMF_POLICY_ELEMENT)) { + (const xmlChar *)KMF_POLICY_ELEMENT)) { /* Check the name attribute */ c = (char *)xmlGetProp(node, - (const xmlChar *)KMF_POLICY_NAME_ATTR); + (const xmlChar *)KMF_POLICY_NAME_ATTR); /* If a match, parse the rest of the data */ if (c != NULL) { @@ -959,7 +841,7 @@ out: } /* - * KMF_SetPolicy + * kmf_set_policy * * Set the policy record in the handle. This searches * the policy DB for the named policy. If it is not found @@ -967,7 +849,7 @@ out: * is kept and an error code is returned. */ KMF_RETURN -KMF_SetPolicy(KMF_HANDLE_T handle, char *policyfile, char *policyname) +kmf_set_policy(KMF_HANDLE_T handle, char *policyfile, char *policyname) { KMF_RETURN ret = KMF_OK; KMF_POLICY_RECORD *newpolicy = NULL; @@ -981,20 +863,20 @@ KMF_SetPolicy(KMF_HANDLE_T handle, char *policyfile, char *policyname) return (KMF_ERR_MEMORY); (void) memset(newpolicy, 0, sizeof (KMF_POLICY_RECORD)); - ret = KMF_GetPolicy( + ret = kmf_get_policy( policyfile == NULL ? KMF_DEFAULT_POLICY_FILE : policyfile, policyname == NULL ? KMF_DEFAULT_POLICY_NAME : policyname, newpolicy); if (ret != KMF_OK) goto out; - ret = KMF_VerifyPolicy(newpolicy); + ret = kmf_verify_policy(newpolicy); if (ret != KMF_OK) goto out; /* release the existing policy data (if any). */ if (handle->policy != NULL) { - KMF_FreePolicyRecord(handle->policy); + kmf_free_policy_record(handle->policy); free(handle->policy); } @@ -1003,7 +885,7 @@ KMF_SetPolicy(KMF_HANDLE_T handle, char *policyfile, char *policyname) out: /* Cleanup any data allocated before the error occurred */ if (ret != KMF_OK) { - KMF_FreePolicyRecord(newpolicy); + kmf_free_policy_record(newpolicy); free(newpolicy); } @@ -1024,10 +906,10 @@ deletePolicyNode(xmlNodePtr node, char *policy_name) * Search for the policy that matches the given name. */ if (!xmlStrcmp((const xmlChar *)node->name, - (const xmlChar *)KMF_POLICY_ELEMENT)) { + (const xmlChar *)KMF_POLICY_ELEMENT)) { /* Check the name attribute */ c = (char *)xmlGetProp(node, - (const xmlChar *)KMF_POLICY_NAME_ATTR); + (const xmlChar *)KMF_POLICY_NAME_ATTR); /* If a match, parse the rest of the data */ if (c != NULL) { @@ -1139,8 +1021,7 @@ update_policyfile(xmlDocPtr doc, char *filename) (void) fclose(pfile); - if (fchmod(tmpfd, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { + if (fchmod(tmpfd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { (void) close(tmpfd); (void) unlink(tmpfilename); return (KMF_ERR_POLICY_DB_FILE); @@ -1164,13 +1045,13 @@ update_policyfile(xmlDocPtr doc, char *filename) } /* - * DeletePolicyFromDB + * kmf_delete_policy_from_db * * Find a policy by name and remove it from the policy DB file. * If the policy is not found, return an error. */ KMF_RETURN -KMF_DeletePolicyFromDB(char *policy_name, char *dbfilename) +kmf_delete_policy_from_db(char *policy_name, char *dbfilename) { KMF_RETURN ret; xmlParserCtxtPtr ctxt = NULL; @@ -1241,7 +1122,7 @@ addPolicyNode(xmlNodePtr pnode, KMF_POLICY_RECORD *policy) } if (policy->ignore_date) { if (newprop(pnode, KMF_OPTIONS_IGNORE_DATE_ATTR, - "TRUE")) { + "TRUE")) { ret = KMF_ERR_POLICY_ENGINE; goto out; } @@ -1249,7 +1130,7 @@ addPolicyNode(xmlNodePtr pnode, KMF_POLICY_RECORD *policy) if (policy->ignore_unknown_ekus) { if (newprop(pnode, KMF_OPTIONS_IGNORE_UNKNOWN_EKUS, - "TRUE")) { + "TRUE")) { ret = KMF_ERR_POLICY_ENGINE; goto out; } @@ -1257,7 +1138,7 @@ addPolicyNode(xmlNodePtr pnode, KMF_POLICY_RECORD *policy) if (policy->ignore_trust_anchor) { if (newprop(pnode, KMF_OPTIONS_IGNORE_TRUST_ANCHOR, - "TRUE")) { + "TRUE")) { ret = KMF_ERR_POLICY_ENGINE; goto out; } @@ -1265,7 +1146,7 @@ addPolicyNode(xmlNodePtr pnode, KMF_POLICY_RECORD *policy) if (policy->validity_adjusttime) { if (newprop(pnode, KMF_OPTIONS_VALIDITY_ADJUSTTIME, - policy->validity_adjusttime)) { + policy->validity_adjusttime)) { ret = KMF_ERR_POLICY_ENGINE; goto out; } @@ -1311,7 +1192,7 @@ out: KMF_RETURN -KMF_VerifyPolicy(KMF_POLICY_RECORD *policy) +kmf_verify_policy(KMF_POLICY_RECORD *policy) { KMF_RETURN ret = KMF_OK; boolean_t has_ta; @@ -1366,7 +1247,7 @@ KMF_VerifyPolicy(KMF_POLICY_RECORD *policy) * is true, then we check the policy sanity also. */ KMF_RETURN -KMF_AddPolicyToDB(KMF_POLICY_RECORD *policy, char *dbfilename, +kmf_add_policy_to_db(KMF_POLICY_RECORD *policy, char *dbfilename, boolean_t check_policy) { KMF_RETURN ret = KMF_OK; @@ -1378,8 +1259,8 @@ KMF_AddPolicyToDB(KMF_POLICY_RECORD *policy, char *dbfilename, return (KMF_ERR_BAD_PARAMETER); if (check_policy == B_TRUE) { - if (ret = KMF_VerifyPolicy(policy)) - return (ret); + if (ret = kmf_verify_policy(policy)) + return (ret); } /* If the policyDB exists, load it into memory */ @@ -1423,11 +1304,11 @@ KMF_AddPolicyToDB(KMF_POLICY_RECORD *policy, char *dbfilename, * DTD link is embedded */ doc->intSubset = xmlCreateIntSubset(doc, - (const xmlChar *)KMF_POLICY_ROOT, - NULL, (const xmlChar *)KMF_POLICY_DTD); + (const xmlChar *)KMF_POLICY_ROOT, + NULL, (const xmlChar *)KMF_POLICY_DTD); root = xmlNewDocNode(doc, NULL, - (const xmlChar *)KMF_POLICY_ROOT, NULL); + (const xmlChar *)KMF_POLICY_ROOT, NULL); if (root != NULL) { xmlDocSetRootElement(doc, root); } @@ -1438,7 +1319,7 @@ KMF_AddPolicyToDB(KMF_POLICY_RECORD *policy, char *dbfilename, xmlNodePtr pnode; pnode = xmlNewChild(root, NULL, - (const xmlChar *)KMF_POLICY_ELEMENT, NULL); + (const xmlChar *)KMF_POLICY_ELEMENT, NULL); ret = addPolicyNode(pnode, policy); /* If that worked, update the DB file. */ diff --git a/usr/src/lib/libkmf/libkmf/common/rdn_parser.c b/usr/src/lib/libkmf/libkmf/common/rdn_parser.c index 575ab85a31..8c8c1c644c 100644 --- a/usr/src/lib/libkmf/libkmf/common/rdn_parser.c +++ b/usr/src/lib/libkmf/libkmf/common/rdn_parser.c @@ -366,7 +366,7 @@ ParseRdnAttribute(char **pbp, char *endptr, boolean_t singleAVA, return (KMF_ERR_RDN_ATTR); } } else if ((n2k->kind == OID_PKCS9_EMAIL_ADDRESS) || - (n2k->kind == OID_RFC1274_MAIL)) { + (n2k->kind == OID_RFC1274_MAIL)) { vt = BER_IA5STRING; } else { /* @@ -381,8 +381,7 @@ ParseRdnAttribute(char **pbp, char *endptr, boolean_t singleAVA, vt = BER_T61STRING; } } - rv = CreateAVA(n2k->OID, - vt, (char *)valBuf, a); + rv = CreateAVA(n2k->OID, vt, (char *)valBuf, a); return (rv); } } @@ -412,8 +411,8 @@ rdnavcompare(const void *a, const void *b) * the result. */ for (n2k = name2kinds, i = 0; - n2k->name && (p1 == MAXINT || p2 == MAXINT); - n2k++, i++) { + n2k->name && (p1 == MAXINT || p2 == MAXINT); + n2k++, i++) { oidrec = n2k->OID; if (oidrec != NULL) { if (IsEqualOid(&av1->type, oidrec)) @@ -431,7 +430,7 @@ rdnavcompare(const void *a, const void *b) return (1); } -KMF_RETURN +static KMF_RETURN ParseDistinguishedName(char *buf, int len, KMF_X509_NAME *name) { KMF_RETURN rv = KMF_OK; @@ -458,15 +457,13 @@ ParseDistinguishedName(char *buf, int len, KMF_X509_NAME *name) * order (most significant component last)." */ qsort((void *)name->RelativeDistinguishedName, - name->numberOfRDNs, - sizeof (KMF_X509_RDN), - rdnavcompare); + name->numberOfRDNs, sizeof (KMF_X509_RDN), rdnavcompare); /* return result */ return (rv); loser: - KMF_FreeDN(name); + kmf_free_dn(name); return (rv); } @@ -486,7 +483,7 @@ IsEqualData(KMF_DATA *d1, KMF_DATA *d2) * Return 0 if equal, 1 if not. */ int -KMF_CompareRDNs(KMF_X509_NAME *name1, KMF_X509_NAME *name2) +kmf_compare_rdns(KMF_X509_NAME *name1, KMF_X509_NAME *name2) { int i, j; boolean_t avfound; @@ -506,12 +503,12 @@ KMF_CompareRDNs(KMF_X509_NAME *name1, KMF_X509_NAME *name2) avfound = FALSE; for (j = 0; j < name2->numberOfRDNs && !avfound; j++) { r2 = (KMF_X509_RDN *) - &name2->RelativeDistinguishedName[j]; + &name2->RelativeDistinguishedName[j]; av2 = (KMF_X509_TYPE_VALUE_PAIR *) - r2->AttributeTypeAndValue; + r2->AttributeTypeAndValue; avfound = (IsEqualOid(&av1->type, &av2->type) && - IsEqualData(&av1->value, &av2->value)); + IsEqualData(&av1->value, &av2->value)); } /* * If the current AV from name1 was not found in name2, @@ -524,3 +521,27 @@ KMF_CompareRDNs(KMF_X509_NAME *name1, KMF_X509_NAME *name2) /* If we got this far, it must be a match */ return (0); } + +/* + * kmf_dn_parser + * + * Public interface for parsing a Distinguished name in + * human-readable format into a binary KMF_X509_NAME. + */ +KMF_RETURN +kmf_dn_parser(char *string, KMF_X509_NAME *name) +{ + KMF_RETURN err; + + if (string == NULL || name == NULL) + return (KMF_ERR_BAD_PARAMETER); + + err = ParseDistinguishedName(string, (int)strlen(string), name); + return (err); +} + +KMF_RETURN +KMF_DNParser(char *string, KMF_X509_NAME *name) +{ + return (kmf_dn_parser(string, name)); +} diff --git a/usr/src/lib/libkmf/libkmf/sparc/Makefile b/usr/src/lib/libkmf/libkmf/sparc/Makefile index 6dd6b42169..24e67f949d 100644 --- a/usr/src/lib/libkmf/libkmf/sparc/Makefile +++ b/usr/src/lib/libkmf/libkmf/sparc/Makefile @@ -18,7 +18,7 @@ # # CDDL HEADER END # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -26,4 +26,11 @@ include ../Makefile.com +# +# Because elfsign depends on libkmf, make sure that the +# library being built & signed here uses the system's own +# KMF library (/usr/lib/libkmf.so.1) +# +$(DYNLIB):= LD_LIBRARY_PATH=/usr/lib + install: all $(ROOTLIBS) $(ROOTLINKS) diff --git a/usr/src/lib/libkmf/plugins/kmf_nss/common/mapfile-vers b/usr/src/lib/libkmf/plugins/kmf_nss/common/mapfile-vers index ed84774842..86cd5655a4 100644 --- a/usr/src/lib/libkmf/plugins/kmf_nss/common/mapfile-vers +++ b/usr/src/lib/libkmf/plugins/kmf_nss/common/mapfile-vers @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -28,29 +28,28 @@ SUNWprivate_1.1 { global: KMF_Plugin_Initialize; - NSS_FindCert; - NSS_FreeKMFCert; - NSS_StoreCert; - NSS_ImportCert; - NSS_ImportCRL; - NSS_DeleteCert; - NSS_DeleteCRL; - NSS_CreateKeypair; - NSS_FindKey; - NSS_EncodePubKeyData; - NSS_SignData; - NSS_DeleteKey; - NSS_FindCRL; - NSS_FindCertInCRL; - NSS_GetErrorString; - NSS_GetPrikeyByCert; - NSS_DecryptData; - NSS_ExportP12; - NSS_StorePrivateKey; - NSS_CreateSymKey; - NSS_GetSymKeyValue; - NSS_SetTokenPin; - + NSS_CreateKeypair; + NSS_CreateSymKey; + NSS_DecryptData; + NSS_DeleteCRL; + NSS_DeleteCert; + NSS_DeleteKey; + NSS_EncodePubKeyData; + NSS_ExportPK12; + NSS_FindCRL; + NSS_FindCert; + NSS_FindCertInCRL; + NSS_FindKey; + NSS_FindPrikeyByCert; + NSS_FreeKMFCert; + NSS_GetErrorString; + NSS_GetSymKeyValue; + NSS_ImportCRL; + NSS_ImportCert; + NSS_SetTokenPin; + NSS_SignData; + NSS_StoreCert; + NSS_StoreKey; local: *; }; diff --git a/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c b/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c index 2ef9aa0fee..010bc547b9 100644 --- a/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c +++ b/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c @@ -58,30 +58,28 @@ mutex_t init_lock = DEFAULTMUTEX; static int nss_initialized = 0; KMF_RETURN -NSS_ConfigureKeystore(KMF_HANDLE_T, KMF_CONFIG_PARAMS *); +NSS_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_FindCert(KMF_HANDLE_T, - KMF_FINDCERT_PARAMS *params, - KMF_X509_DER_CERT *kmf_cert, - uint32_t *num_certs); +NSS_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); void NSS_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); KMF_RETURN -NSS_StoreCert(KMF_HANDLE_T, KMF_STORECERT_PARAMS *params, - KMF_DATA * pcert); +NSS_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_ImportCert(KMF_HANDLE_T, KMF_IMPORTCERT_PARAMS *params); +NSS_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_DeleteCert(KMF_HANDLE_T, KMF_DELETECERT_PARAMS *params); +NSS_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, - KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); +NSS_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); + +KMF_RETURN +NSS_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN NSS_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); @@ -91,55 +89,44 @@ NSS_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, KMF_DATA *, KMF_DATA *); KMF_RETURN -NSS_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *params); +NSS_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *params); +NSS_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_FindCRL(KMF_HANDLE_T, KMF_FINDCRL_PARAMS *params, - char **CRLNameList, int *CRLCount); +NSS_FindCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, - KMF_KEY_HANDLE *, uint32_t *); +NSS_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *params); +NSS_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN NSS_GetErrorString(KMF_HANDLE_T, char **); KMF_RETURN -NSS_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, - KMF_KEY_HANDLE *, boolean_t); +NSS_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, - KMF_KEY_HANDLE *, KMF_KEY_ALG); +NSS_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN NSS_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, KMF_DATA *, KMF_DATA *); KMF_RETURN -NSS_ExportP12(KMF_HANDLE_T, - KMF_EXPORTP12_PARAMS *, - int, KMF_X509_DER_CERT *, - int, KMF_KEY_HANDLE *, - char *); - -KMF_RETURN -NSS_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, KMF_RAW_KEY_DATA *); +NSS_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, KMF_KEY_HANDLE *); +NSS_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN NSS_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); KMF_RETURN -NSS_SetTokenPin(KMF_HANDLE_T, KMF_SETPIN_PARAMS *, KMF_CREDENTIAL *); +NSS_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); static KMF_PLUGIN_FUNCLIST nss_plugin_table = @@ -162,14 +149,14 @@ KMF_PLUGIN_FUNCLIST nss_plugin_table = NSS_FindCRL, NSS_FindCertInCRL, NSS_GetErrorString, - NSS_GetPrikeyByCert, + NSS_FindPrikeyByCert, NSS_DecryptData, - NSS_ExportP12, - NSS_StorePrivateKey, + NSS_ExportPK12, NSS_CreateSymKey, NSS_GetSymKeyValue, NSS_SetTokenPin, NULL, /* VerifyData */ + NSS_StoreKey, NULL /* Finalize */ }; @@ -220,7 +207,7 @@ nss_authenticate(KMF_HANDLE_T handle, /* If a password was given, try to login to the slot */ if (cred == NULL || cred->cred == NULL || cred->credlen == 0 || - nss_slot == NULL) { + nss_slot == NULL) { return (KMF_ERR_BAD_PARAMETER); } @@ -229,8 +216,7 @@ nss_authenticate(KMF_HANDLE_T handle, } PK11_SetPasswordFunc(nss_getpassword); - nssrv = PK11_Authenticate(nss_slot, PR_TRUE, - (void *)cred->cred); + nssrv = PK11_Authenticate(nss_slot, PR_TRUE, (void *)cred->cred); if (nssrv != SECSuccess) { SET_ERROR(kmfh, nssrv); @@ -258,9 +244,8 @@ Init_NSS_DBs(const char *configdir, } rv = NSS_Initialize((configdir && strlen(configdir)) ? - configdir : "./", certPrefix, - keyPrefix, secmodName ? secmodName : "secmod.db", - NSS_INIT_COOPERATE); + configdir : "./", certPrefix, keyPrefix, + secmodName ? secmodName : "secmod.db", NSS_INIT_COOPERATE); if (rv != SECSuccess) { goto end; } @@ -277,23 +262,28 @@ end: * if it is called again. */ KMF_RETURN -NSS_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) +NSS_ConfigureKeystore(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + char *configdir; + char *certPrefix; + char *keyPrefix; + char *secModName; - if (params == NULL) - return (KMF_ERR_BAD_PARAMETER); + configdir = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + certPrefix = kmf_get_attr_ptr(KMF_CERTPREFIX_ATTR, attrlist, numattr); + keyPrefix = kmf_get_attr_ptr(KMF_KEYPREFIX_ATTR, attrlist, numattr); + secModName = kmf_get_attr_ptr(KMF_SECMODNAME_ATTR, attrlist, numattr); (void) mutex_lock(&init_lock); if (nss_initialized == 0) { SECStatus err; (void) mutex_unlock(&init_lock); - err = Init_NSS_DBs(params->nssconfig.configdir, - params->nssconfig.certPrefix, - params->nssconfig.keyPrefix, - params->nssconfig.secModName); + err = Init_NSS_DBs(configdir, certPrefix, + keyPrefix, secModName); if (err != SECSuccess) { SET_ERROR(kmfh, err); return (KMF_ERR_INTERNAL); @@ -306,7 +296,6 @@ NSS_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) return (rv); } - /* * This function sets up the slot to be used for other operations. * This function is basically called by every NSS SPI function. @@ -314,44 +303,49 @@ NSS_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) * boolean "internal_slot_only" argument needs to be TRUE. * A slot pointer will be returned when this function is executed successfully. */ -static KMF_RETURN -Do_NSS_Init( - void *handle, - KMF_NSS_PARAMS nss_opts, +KMF_RETURN +do_nss_init(void *handle, int numattr, + KMF_ATTRIBUTE *attrlist, boolean_t internal_slot_only, PK11SlotInfo **nss_slot) { + KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + char *slotlabel = NULL; if (!nss_initialized) return (KMF_ERR_PLUGIN_INIT); + slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr); /* * NSS Is already initialized, but we need to find * the right slot. */ - if (nss_opts.slotlabel == NULL || - strcmp(nss_opts.slotlabel, "internal") == 0) { + if (slotlabel == NULL || + strcmp(slotlabel, "internal") == 0) { *nss_slot = PK11_GetInternalKeySlot(); } else if (internal_slot_only == TRUE) { - return (KMF_ERR_SLOTNAME); + rv = KMF_ERR_SLOTNAME; + goto end; } else { - *nss_slot = PK11_FindSlotByName(nss_opts.slotlabel); + *nss_slot = PK11_FindSlotByName(slotlabel); } if (*nss_slot == NULL) { SET_ERROR(kmfh, PORT_GetError()); - return (KMF_ERR_SLOTNAME); + rv = KMF_ERR_SLOTNAME; + goto end; } /* * If the token was not yet initialized, return an error. */ if (PK11_NeedUserInit(*nss_slot)) { - return (KMF_ERR_UNINITIALIZED_TOKEN); + rv = KMF_ERR_UNINITIALIZED_TOKEN; } - return (KMF_OK); +end: + return (rv); } static KMF_RETURN @@ -363,15 +357,15 @@ nss2kmf_cert(CERTCertificate *nss_cert, KMF_X509_DER_CERT *kmf_cert) kmf_cert->certificate.Length = nss_cert->derCert.len; if ((kmf_cert->certificate.Data = malloc(nss_cert->derCert.len)) == - NULL) { + NULL) { kmf_cert->certificate.Length = 0; return (KMF_ERR_MEMORY); } (void) memcpy(kmf_cert->certificate.Data, nss_cert->derCert.data, - nss_cert->derCert.len); + nss_cert->derCert.len); if (nss_cert->nickname != NULL) kmf_cert->kmf_private.label = - (char *)strdup(nss_cert->nickname); + (char *)strdup(nss_cert->nickname); return (KMF_OK); } @@ -399,7 +393,7 @@ nss_getcert_by_label(KMF_HANDLE *kmfh, break; case KMF_NONEXPIRED_CERTS: validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(), - PR_FALSE); + PR_FALSE); if (validity != secCertTimeValid) { /* this is an invalid cert, reject it */ *num_certs = 0; @@ -409,7 +403,7 @@ nss_getcert_by_label(KMF_HANDLE *kmfh, break; case KMF_EXPIRED_CERTS: validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(), - PR_FALSE); + PR_FALSE); if (validity == secCertTimeValid) { /* this is a valid cert, reject it in this case. */ *num_certs = 0; @@ -448,13 +442,13 @@ nss_find_matching_certs(PK11SlotInfo *slot, boolean_t findSerial = FALSE; if (issuer != NULL && strlen(issuer)) { - rv = KMF_DNParser(issuer, &issuerDN); + rv = kmf_dn_parser(issuer, &issuerDN); if (rv != KMF_OK) return (rv); findIssuer = TRUE; } if (subject != NULL && strlen(subject)) { - rv = KMF_DNParser(subject, &subjectDN); + rv = kmf_dn_parser(subject, &subjectDN); if (rv != KMF_OK) return (rv); findSubject = TRUE; @@ -477,8 +471,8 @@ nss_find_matching_certs(PK11SlotInfo *slot, rv = DerDecodeName(&der, &cmpDN); if (rv == KMF_OK) { match = !KMF_CompareRDNs(&issuerDN, - &cmpDN); - KMF_FreeDN(&cmpDN); + &cmpDN); + kmf_free_dn(&cmpDN); if (!match) goto delete_and_cont; } else { @@ -491,8 +485,8 @@ nss_find_matching_certs(PK11SlotInfo *slot, rv = DerDecodeName(&der, &cmpDN); if (rv == KMF_OK) { match = !KMF_CompareRDNs(&subjectDN, - &cmpDN); - KMF_FreeDN(&cmpDN); + &cmpDN); + kmf_free_dn(&cmpDN); if (!match) goto delete_and_cont; } else { @@ -508,7 +502,7 @@ nss_find_matching_certs(PK11SlotInfo *slot, goto delete_and_cont; if (memcmp(sernum->data, serial->val, - serial->len)) + serial->len)) goto delete_and_cont; } @@ -559,12 +553,19 @@ convertCertList(void *kmfhandle, CERTCertListNode *node; uint32_t maxcerts = *numcerts; + maxcerts = *numcerts; + if (maxcerts == 0) + maxcerts = 0xFFFFFFFF; + *numcerts = 0; + /* + * Don't copy more certs than the caller wanted. + */ for (node = CERT_LIST_HEAD(nsscerts); - !CERT_LIST_END(node, nsscerts) && rv == KMF_OK && - (*numcerts) < maxcerts; - node = CERT_LIST_NEXT(node), (*numcerts)++) { + !CERT_LIST_END(node, nsscerts) && rv == KMF_OK && + (*numcerts) < maxcerts; + node = CERT_LIST_NEXT(node), (*numcerts)++) { if (kmfcerts != NULL) rv = nss2kmf_cert(node->cert, &kmfcerts[*numcerts]); } @@ -575,47 +576,71 @@ convertCertList(void *kmfhandle, if (rv != KMF_OK) { int i; for (i = 0; i < *numcerts; i++) - KMF_FreeKMFCert(kmfhandle, &kmfcerts[i]); + kmf_free_kmf_cert(kmfhandle, &kmfcerts[i]); + *numcerts = 0; } return (rv); } KMF_RETURN -NSS_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, - KMF_X509_DER_CERT *kmfcerts, - uint32_t *num_certs) +NSS_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; PK11SlotInfo *nss_slot = NULL; CERTCertList *certlist = NULL; uint32_t maxcerts; - - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, FALSE, &nss_slot); - if (rv != KMF_OK) { - return (rv); + uint32_t *num_certs; + KMF_X509_DER_CERT *kmfcerts = NULL; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; + + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); } + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) + return (rv); - if (*num_certs == 0) - maxcerts = 0xFFFFFFFF; - else - maxcerts = *num_certs; + num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (num_certs == NULL) + return (KMF_ERR_BAD_PARAMETER); + maxcerts = *num_certs; + if (maxcerts == 0) + maxcerts = 0xFFFFFFFF; *num_certs = 0; - if (params->certLabel) { + + /* Get the optional returned certificate list */ + kmfcerts = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, numattr); + + /* Get optional search criteria attributes */ + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); + if (rv != KMF_OK) { + validity = KMF_ALL_CERTS; + rv = KMF_OK; + } + + if (certlabel != NULL) { /* This will only find 1 certificate */ - rv = nss_getcert_by_label(kmfh, - params->certLabel, - kmfcerts, num_certs, params->find_cert_validity); + rv = nss_getcert_by_label(kmfh, certlabel, kmfcerts, num_certs, + validity); } else { /* * Build a list of matching certs. */ - rv = nss_find_matching_certs(nss_slot, - params->issuer, params->subject, params->serial, - &certlist, params->find_cert_validity); + rv = nss_find_matching_certs(nss_slot, issuer, subject, serial, + &certlist, validity); /* * If the caller supplied a pointer to storage for @@ -623,8 +648,8 @@ NSS_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, * matching certs. */ if (rv == KMF_OK && certlist != NULL) { - rv = convertCertList(handle, - certlist, kmfcerts, &maxcerts); + rv = convertCertList(handle, certlist, kmfcerts, + &maxcerts); CERT_DestroyCertList(certlist); if (rv == KMF_OK) *num_certs = maxcerts; @@ -659,177 +684,49 @@ NSS_FreeKMFCert(KMF_HANDLE_T handle, } } -KMF_RETURN -NSS_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, - KMF_DATA *pcert) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - SECStatus nss_rv; - CERTCertificate *nss_cert = NULL; - CERTCertTrust *nss_trust = NULL; - PK11SlotInfo *nss_slot = NULL; - CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); - - if (pcert == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - /* NSS only support DER format */ - if (params == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - ret = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, FALSE, &nss_slot); - if (ret != KMF_OK) { - return (ret); - } - - nss_cert = CERT_DecodeCertFromPackage((char *)pcert->Data, - pcert->Length); - if (nss_cert == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - ret = KMF_ERR_BAD_CERT_FORMAT; - goto out; - } - - nss_rv = PK11_ImportCert(nss_slot, nss_cert, CK_INVALID_HANDLE, - params->certLabel, 0); - if (nss_rv) { - SET_ERROR(kmfh, nss_rv); - ret = KMF_ERR_BAD_CERT_FORMAT; - goto out; - } - - if (params->ks_opt_u.nss_opts.trustflag != NULL && - strlen(params->ks_opt_u.nss_opts.trustflag)) { - nss_trust = (CERTCertTrust *) malloc(sizeof (CERTCertTrust)); - if (nss_trust == NULL) { - ret = KMF_ERR_MEMORY; - goto out; - } - nss_rv = CERT_DecodeTrustString(nss_trust, - params->ks_opt_u.nss_opts.trustflag); - if (nss_rv) { - SET_ERROR(kmfh, nss_rv); - ret = KMF_ERR_BAD_PARAMETER; - goto out; - } - - nss_rv = CERT_ChangeCertTrust(certHandle, nss_cert, nss_trust); - if (nss_rv) { - SET_ERROR(kmfh, nss_rv); - ret = KMF_ERR_BAD_PARAMETER; - } - } - -out: - if (nss_trust != NULL) { - free(nss_trust); - } - - if (nss_cert != NULL) { - CERT_DestroyCertificate(nss_cert); - } - - if (nss_slot != NULL) { - PK11_FreeSlot(nss_slot); - } - - return (ret); -} - KMF_RETURN -NSS_ImportCert(KMF_HANDLE_T handle, KMF_IMPORTCERT_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_STORECERT_PARAMS scparams; - KMF_DATA cert = {NULL, 0}; - KMF_DATA cert_der = {NULL, 0}; - KMF_DATA *cptr = NULL; - KMF_ENCODE_FORMAT format; - - if (params == NULL || params->certfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - /* - * Check if the input cert file is a valid certificate and - * auto-detect the file format of it. - */ - ret = KMF_IsCertFile(handle, params->certfile, &format); - if (ret != KMF_OK) - return (ret); - - ret = KMF_ReadInputFile(handle, params->certfile, &cert); - if (ret != KMF_OK) { - return (ret); - } - - /* - * If the imported cert is in PEM format, convert it to - * DER format in order to store it in NSS token. - */ - if (format == KMF_FORMAT_PEM) { - int derlen; - ret = KMF_Pem2Der(cert.Data, cert.Length, - &cert_der.Data, &derlen); - if (ret != KMF_OK) { - goto cleanup; - } - cert_der.Length = (size_t)derlen; - cptr = &cert_der; - } else { - cptr = &cert; - } - - (void) memset(&scparams, 0, sizeof (scparams)); - scparams.kstype = params->kstype; - scparams.certLabel = params->certLabel; - scparams.nssparms = params->nssparms; - - ret = NSS_StoreCert(handle, &scparams, cptr); - - if (format == KMF_FORMAT_PEM) { - KMF_FreeData(&cert_der); - } - -cleanup: - KMF_FreeData(&cert); - - return (ret); -} - -KMF_RETURN -NSS_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) +NSS_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; int nssrv; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; CERTCertificate *cert = NULL; PK11SlotInfo *nss_slot = NULL; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; - /* check params */ - if (params == NULL) { + if (handle == NULL || attrlist == NULL || numattr == 0) { return (KMF_ERR_BAD_PARAMETER); } + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) + return (rv); + + /* Get the search criteria attributes. They are all optional. */ + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, - FALSE, &nss_slot); + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); if (rv != KMF_OK) { - return (rv); + validity = KMF_ALL_CERTS; + rv = KMF_OK; } - if (params->certLabel) { - cert = PK11_FindCertFromNickname(params->certLabel, NULL); + /* Start finding the matched certificates and delete them. */ + if (certlabel != NULL) { + cert = PK11_FindCertFromNickname(certlabel, NULL); if (cert == NULL) { return (KMF_ERR_CERT_NOT_FOUND); } - switch (params->find_cert_validity) { + switch (validity) { case KMF_ALL_CERTS: break; case KMF_NONEXPIRED_CERTS: @@ -857,13 +754,12 @@ NSS_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) CERTCertListNode *node; CERTCertList *certlist = NULL; - rv = nss_find_matching_certs(nss_slot, - params->issuer, params->subject, params->serial, - &certlist, params->find_cert_validity); + rv = nss_find_matching_certs(nss_slot, issuer, subject, serial, + &certlist, validity); for (node = CERT_LIST_HEAD(certlist); - !CERT_LIST_END(node, certlist) && rv == KMF_OK; - node = CERT_LIST_NEXT(node)) { + !CERT_LIST_END(node, certlist) && rv == KMF_OK; + node = CERT_LIST_NEXT(node)) { nssrv = SEC_DeletePermCertificate(node->cert); if (nssrv) { @@ -911,63 +807,114 @@ InitRandom(char *filename) KMF_RETURN NSS_CreateKeypair(KMF_HANDLE_T handle, - KMF_CREATEKEYPAIR_PARAMS *params, - KMF_KEY_HANDLE *privkey, - KMF_KEY_HANDLE *pubkey) + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - PK11RSAGenParams rsaparams; - void *nssparams; + PK11RSAGenParams rsaparams; + void *nssparams; CK_MECHANISM_TYPE mechanism; ulong_t publicExponent = 0x010001; PK11SlotInfo *nss_slot = NULL; SECKEYPrivateKey *NSSprivkey = NULL; SECKEYPublicKey *NSSpubkey = NULL; PQGParams *pqgParams = NULL; - - - if (params == NULL) { + KMF_CREDENTIAL cred; + boolean_t storekey = TRUE; + uint32_t keylen = 1024, len; + uint32_t keylen_size = sizeof (uint32_t); + KMF_KEY_ALG keytype = KMF_RSA; + KMF_KEY_HANDLE *pubkey = NULL; + KMF_KEY_HANDLE *privkey = NULL; + char *keylabel = NULL; + + if (handle == NULL || attrlist == NULL || numattr == 0) { return (KMF_ERR_BAD_PARAMETER); } - - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, FALSE, &nss_slot); + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); if (rv != KMF_OK) { return (rv); } - rv = nss_authenticate(handle, nss_slot, ¶ms->cred); + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (rv); + + rv = nss_authenticate(handle, nss_slot, &cred); if (rv != KMF_OK) { return (rv); } + /* "storekey" is optional. Default is TRUE */ + (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr, + &storekey, NULL); + + /* keytype is optional. KMF_RSA is default */ + (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); + + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, + &keylen, &keylen_size); + if (rv == KMF_ERR_ATTR_NOT_FOUND) + /* Default keylen = 1024 */ + rv = KMF_OK; + else if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); + privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); + if (pubkey == NULL || privkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); + (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); + + rv = kmf_get_attr(KMF_KEYLABEL_ATTR, attrlist, numattr, NULL, &len); + if (rv == KMF_OK && len > 0) { + keylabel = malloc(len + 1); + if (keylabel == NULL) + return (KMF_ERR_MEMORY); + /* Now fill in the label value */ + (void) memset(keylabel, 0, len + 1); + rv = kmf_get_attr(KMF_KEYLABEL_ATTR, attrlist, numattr, + keylabel, NULL); + if (rv != KMF_OK) { + free(keylabel); + goto cleanup; + } + } + /* Get some random bits */ InitRandom("/dev/urandom"); - if (params->keytype == KMF_RSA) { - rsaparams.keySizeInBits = params->keylength; + if (keytype == KMF_RSA) { + KMF_BIGINT rsaexp; + + rsaparams.keySizeInBits = keylen; /* * NSS only allows for a 4 byte exponent. * Ignore the exponent parameter if it is too big. */ - if (params->rsa_exponent.len > 0 && - params->rsa_exponent.len <= sizeof (publicExponent) && - params->rsa_exponent.val != NULL) { - (void) memcpy(&publicExponent, - params->rsa_exponent.val, - params->rsa_exponent.len); + if ((rv = kmf_get_attr(KMF_RSAEXP_ATTR, attrlist, numattr, + &rsaexp, NULL)) == KMF_OK) { + if (rsaexp.len > 0 && + rsaexp.len <= sizeof (publicExponent) && + rsaexp.val != NULL) { + (void) memcpy(&publicExponent, rsaexp.val, + rsaexp.len); + } } rsaparams.pe = publicExponent; mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; nssparams = &rsaparams; - } else if (params->keytype == KMF_DSA) { + } else if (keytype == KMF_DSA) { PQGVerify *pqgVerify = NULL; int ks; SECStatus nssrv, passed; mechanism = CKM_DSA_KEY_PAIR_GEN; - ks = PQG_PBITS_TO_INDEX(params->keylength); + ks = PQG_PBITS_TO_INDEX(keylen); nssrv = PK11_PQG_ParamGen(ks, &pqgParams, &pqgVerify); if (nssrv != SECSuccess) { SET_ERROR(kmfh, rv); @@ -995,40 +942,34 @@ NSS_CreateKeypair(KMF_HANDLE_T handle, goto cleanup; } - NSSprivkey = PK11_GenerateKeyPair(nss_slot, - mechanism, nssparams, &NSSpubkey, - PR_TRUE, /* isPermanent */ - PR_TRUE, /* isSensitive */ - (void *)params->cred.cred); + NSSprivkey = PK11_GenerateKeyPair(nss_slot, mechanism, nssparams, + &NSSpubkey, + storekey, /* isPermanent */ + PR_TRUE, /* isSensitive */ + (void *)cred.cred); if (NSSprivkey == NULL || NSSpubkey == NULL) { SET_ERROR(kmfh, PORT_GetError()); rv = KMF_ERR_KEYGEN_FAILED; } else { - if (params->keylabel != NULL && - strlen(params->keylabel)) { + if (keylabel != NULL && strlen(keylabel)) { (void) PK11_SetPrivateKeyNickname(NSSprivkey, - params->keylabel); - (void) PK11_SetPublicKeyNickname(NSSpubkey, - params->keylabel); + keylabel); + (void) PK11_SetPublicKeyNickname(NSSpubkey, keylabel); } /* Now, convert it to a KMF_KEY object for the framework */ - if (privkey != NULL) { - privkey->kstype = KMF_KEYSTORE_NSS; - privkey->keyalg = params->keytype; - privkey->keyclass = KMF_ASYM_PRI; - privkey->keylabel = - PK11_GetPrivateKeyNickname(NSSprivkey); - privkey->keyp = (void *)NSSprivkey; - } - if (pubkey != NULL) { - pubkey->kstype = KMF_KEYSTORE_NSS; - pubkey->keyalg = params->keytype; - pubkey->keyp = (void *)NSSpubkey; - pubkey->keyclass = KMF_ASYM_PUB; - pubkey->keylabel = - PK11_GetPublicKeyNickname(NSSpubkey); - } + privkey->kstype = KMF_KEYSTORE_NSS; + privkey->keyalg = keytype; + privkey->keyclass = KMF_ASYM_PRI; + privkey->keylabel = PK11_GetPrivateKeyNickname(NSSprivkey); + privkey->keyp = (void *)NSSprivkey; + + pubkey->kstype = KMF_KEYSTORE_NSS; + pubkey->keyalg = keytype; + pubkey->keyp = (void *)NSSpubkey; + pubkey->keyclass = KMF_ASYM_PUB; + pubkey->keylabel = PK11_GetPublicKeyNickname(NSSpubkey); + rv = KMF_OK; } cleanup: @@ -1042,10 +983,12 @@ cleanup: pubkey->keyp = NULL; } + if (keylabel) + free(keylabel); + if (pqgParams != NULL) PK11_PQG_DestroyParams(pqgParams); - if (nss_slot != NULL) PK11_FreeSlot(nss_slot); @@ -1054,11 +997,11 @@ cleanup: KMF_RETURN NSS_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, - KMF_OID *AlgOID, KMF_DATA *tobesigned, - KMF_DATA *output) + KMF_OID *AlgOID, KMF_DATA *tobesigned, + KMF_DATA *output) { KMF_RETURN ret = KMF_OK; - KMF_ALGORITHM_INDEX AlgId; + KMF_ALGORITHM_INDEX AlgId; SECOidTag signAlgTag; SECKEYPrivateKey *NSSprivkey = NULL; SECStatus rv; @@ -1073,7 +1016,7 @@ NSS_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, return (KMF_ERR_BAD_PARAMETER); /* Map the OID to a NSS algorithm */ - AlgId = X509_AlgorithmOidToAlgId(AlgOID); + AlgId = x509_algoid_to_algid(AlgOID); if (AlgId == KMF_ALGID_NONE) return (KMF_ERR_BAD_PARAMETER); @@ -1129,8 +1072,7 @@ NSS_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, } rvitem = SEC_ASN1EncodeItem(NULL, NULL, spki, - CERT_SubjectPublicKeyInfoTemplate); - + CERT_SubjectPublicKeyInfoTemplate); if (rvitem != NULL) { encoded->Data = malloc(rvitem->len); if (encoded->Data == NULL) { @@ -1152,50 +1094,65 @@ NSS_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, } KMF_RETURN -NSS_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, - KMF_KEY_HANDLE *key, boolean_t delete_token) +NSS_DeleteKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; PK11SlotInfo *nss_slot = NULL; + KMF_KEY_HANDLE *key; + KMF_CREDENTIAL cred; + boolean_t delete_token = B_TRUE; + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } /* * "delete_token" means to clear it from the token storage as well * as from memory. */ + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); if (key == NULL || key->keyp == NULL) return (KMF_ERR_BAD_PARAMETER); + rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr, + (void *)&delete_token, NULL); + if (rv != KMF_OK) + /* "delete_token" is optional. Default is TRUE */ + rv = KMF_OK; + if (delete_token) { SECStatus nssrv = SECSuccess; if (key->keyclass != KMF_ASYM_PUB && - key->keyclass != KMF_ASYM_PRI && - key->keyclass != KMF_SYMMETRIC) + key->keyclass != KMF_ASYM_PRI && + key->keyclass != KMF_SYMMETRIC) return (KMF_ERR_BAD_KEY_CLASS); - if (params == NULL) - return (KMF_ERR_BAD_PARAMETER); - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, FALSE, &nss_slot); + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); if (rv != KMF_OK) { return (rv); } - rv = nss_authenticate(handle, nss_slot, ¶ms->cred); + + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = nss_authenticate(handle, nss_slot, &cred); if (rv != KMF_OK) { return (rv); } if (key->keyclass == KMF_ASYM_PUB) { nssrv = PK11_DeleteTokenPublicKey( - (SECKEYPublicKey *)key->keyp); + (SECKEYPublicKey *)key->keyp); } else if (key->keyclass == KMF_ASYM_PRI) { nssrv = PK11_DeleteTokenPrivateKey( - (SECKEYPrivateKey *)key->keyp, PR_TRUE); + (SECKEYPrivateKey *)key->keyp, PR_TRUE); } else if (key->keyclass == KMF_SYMMETRIC) { nssrv = PK11_DeleteTokenSymKey( - (PK11SymKey *) key->keyp); + (PK11SymKey *) key->keyp); if (nssrv == SECSuccess) - PK11_FreeSymKey( - (PK11SymKey *) key->keyp); + PK11_FreeSymKey((PK11SymKey *) key->keyp); } if (nssrv != SECSuccess) { SET_ERROR(handle, PORT_GetError()); @@ -1218,460 +1175,6 @@ NSS_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, } KMF_RETURN -NSS_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - PK11SlotInfo *nss_slot = NULL; - CERTSignedCrl *nss_crl = NULL; - KMF_ENCODE_FORMAT format; - int importOptions; - SECItem crlDER; - KMF_DATA crl1; - KMF_DATA crl2; - - if (params == NULL || params->ks_opt_u.nss_opts.crlfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - /* - * Check if the input CRL file is a valid CRL file and auto-detect - * the encoded format of the file. - */ - ret = KMF_IsCRLFile(handle, params->ks_opt_u.nss_opts.crlfile, - &format); - if (ret != KMF_OK) - return (ret); - - ret = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, TRUE, &nss_slot); - if (ret != KMF_OK) { - return (ret); - } - - /* set importOptions */ - if (params->ks_opt_u.nss_opts.crl_check == B_FALSE) { - importOptions = CRL_IMPORT_DEFAULT_OPTIONS | - CRL_IMPORT_BYPASS_CHECKS; - } else { - importOptions = CRL_IMPORT_DEFAULT_OPTIONS; - } - - - /* Read in the CRL file */ - crl1.Data = NULL; - crl2.Data = NULL; - ret = KMF_ReadInputFile(handle, params->ks_opt_u.nss_opts.crlfile, - &crl1); - if (ret != KMF_OK) { - return (ret); - } - - /* If the input CRL is in PEM format, convert it to DER first. */ - if (format == KMF_FORMAT_PEM) { - int len; - ret = KMF_Pem2Der(crl1.Data, crl1.Length, - &crl2.Data, &len); - if (ret != KMF_OK) { - goto out; - } - crl2.Length = (size_t)len; - } - - crlDER.data = format == KMF_FORMAT_ASN1 ? crl1.Data : crl2.Data; - crlDER.len = format == KMF_FORMAT_ASN1 ? crl1.Length : crl2.Length; - - nss_crl = PK11_ImportCRL(nss_slot, &crlDER, NULL, SEC_CRL_TYPE, - NULL, importOptions, NULL, CRL_DECODE_DEFAULT_OPTIONS); - - if (nss_crl == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - ret = KMF_ERR_BAD_CRLFILE; - goto out; - } - -out: - if (nss_slot != NULL) { - PK11_FreeSlot(nss_slot); - } - - if (crl1.Data != NULL) { - free(crl1.Data); - } - - if (crl2.Data != NULL) { - free(crl2.Data); - } - - if (nss_crl != NULL) { - SEC_DestroyCrl(nss_crl); - } - - return (ret); -} - -KMF_RETURN -NSS_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) -{ - KMF_RETURN rv = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - CERTSignedCrl *crl = NULL; - CERTCertificate *cert = NULL; - PK11SlotInfo *nss_slot = NULL; - CERTCrlHeadNode *crlList = NULL; - CERTCrlNode *crlNode = NULL; - PRArenaPool *arena = NULL; - CERTName *name = NULL; - CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); - - /* check params */ - if (params == NULL || - (params->ks_opt_u.nss_opts.crl_issuerName == NULL && - params->ks_opt_u.nss_opts.crl_subjName == NULL) || - (params->ks_opt_u.nss_opts.crl_issuerName != NULL && - params->ks_opt_u.nss_opts.crl_subjName != NULL)) { - return (KMF_ERR_BAD_PARAMETER); - } - - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, TRUE, - &nss_slot); - if (rv != KMF_OK) { - return (rv); - } - - /* Find the CRL based on the deletion criteria. */ - if (params->ks_opt_u.nss_opts.crl_issuerName != NULL) { - /* - * If the deletion is based on the issuer's certificate - * nickname, we will get the issuer's cert first, then - * get the CRL from the cert. - */ - cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, - params->ks_opt_u.nss_opts.crl_issuerName); - if (!cert) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CERT_NOT_FOUND; - goto out; - } - - crl = SEC_FindCrlByName(certHandle, &cert->derSubject, - SEC_CRL_TYPE); - if (crl == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - goto out; - } - } else { - /* - * If the deletion is based on the CRL's subject name, we will - * get all the CRLs from the internal database and search - * for the CRL with the same subject name. - */ - boolean_t found = B_FALSE; - int nssrv; - - nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); - if (nssrv) { - SET_ERROR(kmfh, nssrv); - rv = KMF_ERR_CRL_NOT_FOUND; - goto out; - } - - if (crlList == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - goto out; - } - - /* Allocate space for name */ - arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if (arena == NULL) { - rv = KMF_ERR_MEMORY; - goto out; - } - - name = PORT_ArenaZAlloc(arena, sizeof (*name)); - if (name == NULL) { - rv = KMF_ERR_MEMORY; - goto out; - } - name->arena = arena; - - crlNode = crlList->first; - while (crlNode && !found) { - char *asciiname = NULL; - SECItem* issuer; - - name = &crlNode->crl->crl.name; - if (!name) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - break; - } - - asciiname = CERT_NameToAscii(name); - if (asciiname == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - break; - } - - if (strcmp(params->ks_opt_u.nss_opts.crl_subjName, - asciiname) == 0) { - found = B_TRUE; - issuer = &crlNode->crl->crl.derName; - crl = SEC_FindCrlByName(certHandle, issuer, - SEC_CRL_TYPE); - if (crl == NULL) { - /* We found a cert but no CRL */ - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - } - } - PORT_Free(asciiname); - crlNode = crlNode->next; - } - - if (rv) { - goto out; - } - } - - if (crl) { - (void) SEC_DeletePermCRL(crl); - } - -out: - if (nss_slot != NULL) { - PK11_FreeSlot(nss_slot); - } - - if (crlList != NULL) { - PORT_FreeArena(crlList->arena, PR_FALSE); - } - - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - - if (cert != NULL) { - CERT_DestroyCertificate(cert); - } - - if (crl != NULL) { - SEC_DestroyCrl(crl); - } - - return (rv); -} - - -KMF_RETURN -NSS_FindCRL(KMF_HANDLE_T handle, KMF_FINDCRL_PARAMS *params, - char **CRLNameList, int *CRLCount) -{ - KMF_RETURN rv = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - PK11SlotInfo *nss_slot = NULL; - CERTCrlHeadNode *crlList = NULL; - CERTCrlNode *crlNode = NULL; - PRArenaPool *arena = NULL; - CERTName *name = NULL; - SECStatus nssrv; - char *asciiname = NULL; - int crl_num; - int i; - CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); - - if (CRLCount == NULL || params == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - *CRLCount = 0; - - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, TRUE, &nss_slot); - if (rv != KMF_OK) { - return (rv); - } - - /* Look up Crls */ - nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); - if (nssrv) { - SET_ERROR(kmfh, rv); - rv = KMF_ERR_CRL_NOT_FOUND; - goto out; - } - - /* Allocate space for name first */ - arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if (arena == NULL) { - rv = KMF_ERR_MEMORY; - goto out; - } - - name = PORT_ArenaZAlloc(arena, sizeof (*name)); - if (name == NULL) { - rv = KMF_ERR_MEMORY; - goto out; - } - name->arena = arena; - - /* - * Loop thru the crlList and create a crl list with CRL's subject name. - */ - crlNode = crlList->first; - crl_num = 0; - while (crlNode) { - char *subj_name; - - /* Get the CRL subject name */ - name = &crlNode->crl->crl.name; - if (!name) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - break; - } - - - if (CRLNameList != NULL) { - asciiname = CERT_NameToAscii(name); - if (asciiname == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - break; - } - subj_name = strdup(asciiname); - PORT_Free(asciiname); - if (subj_name == NULL) { - rv = KMF_ERR_MEMORY; - break; - } - CRLNameList[crl_num] = subj_name; - } - - crl_num++; - crlNode = crlNode->next; - } - - if (rv == KMF_OK) { - /* success */ - *CRLCount = crl_num; - } - -out: - if (nss_slot != NULL) { - PK11_FreeSlot(nss_slot); - } - - if (crlList != NULL) { - PORT_FreeArena(crlList->arena, PR_FALSE); - } - - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - - /* If failed, free memory allocated for the returning rlist */ - if (rv && (CRLNameList != NULL)) { - for (i = 0; i < crl_num; i++) { - free(CRLNameList[i]); - } - } - - return (rv); -} - - -KMF_RETURN -NSS_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) -{ - KMF_RETURN rv = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - PK11SlotInfo *nss_slot = NULL; - CERTCertificate *cert = NULL; - CERTSignedCrl *crl = NULL; - CERTCrlEntry *entry; - boolean_t match = B_FALSE; - int i; - CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); - - /* check params */ - if (params == NULL || - (params->ks_opt_u.nss_opts.certLabel == NULL && - params->ks_opt_u.nss_opts.certificate == NULL)) { - return (KMF_ERR_BAD_PARAMETER); - } - - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, TRUE, &nss_slot); - if (rv != KMF_OK) { - return (rv); - } - - /* Find the certificate first */ - if (params->ks_opt_u.nss_opts.certLabel != NULL) { - cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, - params->ks_opt_u.nss_opts.certLabel); - } else { - SECItem derCert = { NULL, 0}; - - derCert.data = params->ks_opt_u.nss_opts.certificate->Data; - derCert.len = params->ks_opt_u.nss_opts.certificate->Length; - cert = CERT_FindCertByDERCert(certHandle, &derCert); - } - - if (!cert) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CERT_NOT_FOUND; - goto out; - } - - /* Find the CRL with the same issuer as the given certificate. */ - crl = SEC_FindCrlByName(certHandle, &cert->derIssuer, SEC_CRL_TYPE); - if (crl == NULL) { - /* - * Could not find the CRL issued by the same issuer. This - * usually means that the CRL is not installed in the DB. - */ - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - goto out; - - } - - /* Check if the certificate's serialNumber is revoked in the CRL */ - i = 0; - while ((entry = (crl->crl).entries[i++]) != NULL) { - if (SECITEM_CompareItem(&(cert->serialNumber), - &(entry->serialNumber)) == SECEqual) { - match = B_TRUE; - break; - } - } - - if (!match) { - rv = KMF_ERR_NOT_REVOKED; - } - -out: - if (nss_slot != NULL) { - PK11_FreeSlot(nss_slot); - } - - if (cert != NULL) { - CERT_DestroyCertificate(cert); - } - - if (crl != NULL) { - SEC_DestroyCrl(crl); - } - - return (rv); -} - -KMF_RETURN NSS_GetErrorString(KMF_HANDLE_T handle, char **msgstr) { KMF_RETURN ret = KMF_OK; @@ -1693,30 +1196,46 @@ NSS_GetErrorString(KMF_HANDLE_T handle, char **msgstr) } KMF_RETURN -NSS_GetPrikeyByCert(KMF_HANDLE_T handle, KMF_CRYPTOWITHCERT_PARAMS *params, - KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, - KMF_KEY_ALG keytype) +NSS_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { - CERTCertificate *nss_cert = NULL; - SECKEYPrivateKey* privkey = NULL; - PK11SlotInfo *nss_slot = NULL; KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + PK11SlotInfo *nss_slot = NULL; + KMF_CREDENTIAL cred; + KMF_KEY_HANDLE *key = NULL; + KMF_DATA *cert = NULL; + CERTCertificate *nss_cert = NULL; + SECKEYPrivateKey* privkey = NULL; - rv = Do_NSS_Init(handle, - params->nssparms, FALSE, &nss_slot); - if (rv != KMF_OK) { - return (rv); + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); } - rv = nss_authenticate(handle, nss_slot, ¶ms->cred); - if (rv != KMF_OK) { + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) return (rv); - } - nss_cert = CERT_DecodeCertFromPackage((char *)SignerCertData->Data, - SignerCertData->Length); + /* Get the credential */ + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + rv = nss_authenticate(handle, nss_slot, &cred); + if (rv != KMF_OK) + return (rv); + + /* Get the key handle */ + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (key == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* Get the cert data and decode it */ + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL || cert->Data == NULL) + return (KMF_ERR_BAD_PARAMETER); + nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data, + cert->Length); if (nss_cert == NULL) { SET_ERROR(kmfh, PORT_GetError()); return (KMF_ERR_BAD_CERT_FORMAT); @@ -1730,16 +1249,15 @@ NSS_GetPrikeyByCert(KMF_HANDLE_T handle, KMF_CRYPTOWITHCERT_PARAMS *params, key->kstype = KMF_KEYSTORE_NSS; key->keyclass = KMF_ASYM_PRI; - key->keyalg = keytype; key->keyp = (void *)privkey; key->keylabel = PK11_GetPrivateKeyNickname(privkey); CERT_DestroyCertificate(nss_cert); return (KMF_OK); - } + KMF_RETURN NSS_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, KMF_OID *AlgOID, KMF_DATA *ciphertext, @@ -1754,7 +1272,6 @@ NSS_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, uint8_t *in_data, *out_data; int i, blocks; - if (key == NULL || AlgOID == NULL || ciphertext == NULL || output == NULL || ciphertext->Data == NULL || @@ -1812,8 +1329,8 @@ pk11keytype2kmf(CK_KEY_TYPE type) } KMF_RETURN -NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, - KMF_KEY_HANDLE *keys, uint32_t *numkeys) +NSS_FindKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv; SECKEYPrivateKeyList *prilist; @@ -1824,14 +1341,32 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, PK11SymKey *symlist = NULL; int count; uint32_t maxkeys; + KMF_KEY_HANDLE *keys; + uint32_t *numkeys; + KMF_CREDENTIAL cred; + KMF_KEY_CLASS keyclass; + char *findLabel; + KMF_KEY_ALG keytype = KMF_KEYALG_NONE; + + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } + + numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (numkeys == NULL) + return (KMF_ERR_BAD_PARAMETER); - rv = Do_NSS_Init(handle, - parms->ks_opt_u.nss_opts, FALSE, &nss_slot); + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); if (rv != KMF_OK) { return (rv); } - rv = nss_authenticate(handle, nss_slot, &parms->cred); + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = nss_authenticate(handle, nss_slot, &cred); if (rv != KMF_OK) { return (rv); } @@ -1839,24 +1374,29 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, maxkeys = *numkeys; if (maxkeys == 0) maxkeys = 0xFFFFFFFF; - *numkeys = 0; - if (parms->keyclass == KMF_ASYM_PUB) { - publist = PK11_ListPublicKeysInSlot(nss_slot, parms->findLabel); + + rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, + (void *)&keyclass, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + + if (keyclass == KMF_ASYM_PUB) { + publist = PK11_ListPublicKeysInSlot(nss_slot, findLabel); if (publist == NULL) { rv = KMF_ERR_KEY_NOT_FOUND; goto cleanup; } - } else if (parms->keyclass == KMF_ASYM_PRI) { - prilist = PK11_ListPrivKeysInSlot(nss_slot, - parms->findLabel, NULL); + } else if (keyclass == KMF_ASYM_PRI) { + prilist = PK11_ListPrivKeysInSlot(nss_slot, findLabel, NULL); if (prilist == NULL) { rv = KMF_ERR_KEY_NOT_FOUND; goto cleanup; } - } else if (parms->keyclass == KMF_SYMMETRIC) { - symlist = PK11_ListFixedKeysInSlot(nss_slot, parms->findLabel, - NULL); + } else if (keyclass == KMF_SYMMETRIC) { + symlist = PK11_ListFixedKeysInSlot(nss_slot, findLabel, NULL); if (symlist == NULL) { rv = KMF_ERR_KEY_NOT_FOUND; goto cleanup; @@ -1866,18 +1406,19 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, goto cleanup; } - if (parms->keyclass == KMF_ASYM_PUB) { + keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + /* it is okay to have "keys" contains NULL */ + + if (keyclass == KMF_ASYM_PUB) { for (count = 0, pubnode = PUBKEY_LIST_HEAD(publist); - !PUBKEY_LIST_END(pubnode, publist) && - count < maxkeys; - pubnode = PUBKEY_LIST_NEXT(pubnode), count++) { + !PUBKEY_LIST_END(pubnode, publist) && count < maxkeys; + pubnode = PUBKEY_LIST_NEXT(pubnode), count++) { if (keys != NULL) { keys[count].kstype = KMF_KEYSTORE_NSS; keys[count].keyclass = KMF_ASYM_PUB; keys[count].keyp = (void *)pubnode->key; keys[count].keylabel = - PK11_GetPublicKeyNickname( - pubnode->key); + PK11_GetPublicKeyNickname(pubnode->key); if (pubnode->key->keyType == rsaKey) keys[count].keyalg = KMF_RSA; @@ -1886,18 +1427,16 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, } } *numkeys = count; - } else if (parms->keyclass == KMF_ASYM_PRI) { + } else if (keyclass == KMF_ASYM_PRI) { for (count = 0, prinode = PRIVKEY_LIST_HEAD(prilist); - !PRIVKEY_LIST_END(prinode, prilist) && - count < maxkeys; - prinode = PRIVKEY_LIST_NEXT(prinode), count++) { + !PRIVKEY_LIST_END(prinode, prilist) && count < maxkeys; + prinode = PRIVKEY_LIST_NEXT(prinode), count++) { if (keys != NULL) { keys[count].kstype = KMF_KEYSTORE_NSS; keys[count].keyclass = KMF_ASYM_PRI; keys[count].keyp = (void *)prinode->key; keys[count].keylabel = - PK11_GetPrivateKeyNickname( - prinode->key); + PK11_GetPrivateKeyNickname(prinode->key); if (prinode->key->keyType == rsaKey) keys[count].keyalg = KMF_RSA; @@ -1906,8 +1445,12 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, } } *numkeys = count; - } else if (parms->keyclass == KMF_SYMMETRIC) { + } else if (keyclass == KMF_SYMMETRIC) { count = 0; + rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); + if (rv != KMF_OK) + rv = KMF_OK; while (symlist && count < maxkeys) { PK11SymKey *symkey = symlist; CK_KEY_TYPE type; @@ -1916,15 +1459,15 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, type = PK11_GetSymKeyType(symkey); keyalg = pk11keytype2kmf(type); + symlist = PK11_GetNextSymKey(symkey); + /* * If keytype is specified in the searching parameter, * check the keytype and skip the key if its keytype * doesn't match. */ - symlist = PK11_GetNextSymKey(symkey); - if (parms->keytype != KMF_KEYALG_NONE && - parms->keytype != keyalg) { - /* free that key since we aren't using it */ + if (keytype != KMF_KEYALG_NONE && keytype != keyalg) { + /* free that key since we arent using it */ PK11_FreeSymKey(symkey); continue; } @@ -1946,12 +1489,13 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, */ while (symlist != NULL) { PK11SymKey *symkey = symlist; + PK11_FreeSymKey(symkey); symlist = PK11_GetNextSymKey(symkey); } + *numkeys = count; } - *numkeys = count; cleanup: if (nss_slot != NULL) { PK11_FreeSlot(nss_slot); @@ -2005,7 +1549,7 @@ p12u_ucs2_ascii_conversion_function( } /* Perform the conversion. */ ret = PORT_UCS2_UTF8Conversion(toUnicode, dup->data, dup->len, - outBuf, maxOutBufLen, outBufLen); + outBuf, maxOutBufLen, outBufLen); if (dup) SECITEM_ZfreeItem(dup, PR_TRUE); @@ -2020,11 +1564,10 @@ p12u_OpenFile(p12uContext *p12ctx, PRBool fileRead) } if (fileRead) { - p12ctx->file = PR_Open(p12ctx->filename, - PR_RDONLY, 0400); + p12ctx->file = PR_Open(p12ctx->filename, PR_RDONLY, 0400); } else { p12ctx->file = PR_Open(p12ctx->filename, - PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 0600); + PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 0600); } if (!p12ctx->file) { @@ -2124,7 +1667,7 @@ add_cert_to_bag(SEC_PKCS12ExportContext *p12ecx, certSafe = keySafe; } else { certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, pwitem, - SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC); + SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC); } if (!certSafe || !keySafe) { @@ -2133,22 +1676,17 @@ add_cert_to_bag(SEC_PKCS12ExportContext *p12ecx, } if (SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, cert, - CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem, - SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC) - != SECSuccess) { + CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem, + SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC) + != SECSuccess) { rv = KMF_ERR_INTERNAL; } out: return (rv); } -/*ARGSUSED*/ KMF_RETURN -NSS_ExportP12(KMF_HANDLE_T handle, - KMF_EXPORTP12_PARAMS *params, - int numcerts, KMF_X509_DER_CERT *certs, - int numkeys, KMF_KEY_HANDLE *keylist, - char *filename) +NSS_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -2159,33 +1697,56 @@ NSS_ExportP12(KMF_HANDLE_T handle, CERTCertListNode* node = NULL; PK11SlotInfo *slot = NULL; SECItem pwitem = {NULL, 0}; + KMF_CREDENTIAL *cred = NULL; + KMF_CREDENTIAL *p12cred = NULL; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + char *filename = NULL; + + if (kmfh == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } - rv = Do_NSS_Init(handle, - params->nssparms, FALSE, &slot); - if (rv != KMF_OK) { + rv = do_nss_init(handle, numattr, attrlist, FALSE, &slot); + if (rv != KMF_OK) return (rv); - } - rv = nss_authenticate(handle, slot, ¶ms->cred); - if (rv != KMF_OK) { + cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); + if (cred == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = nss_authenticate(handle, slot, cred); + if (rv != KMF_OK) return (rv); - } + + p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); + if (p12cred == NULL) + return (KMF_ERR_BAD_PARAMETER); + + filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, + numattr); + if (filename == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* Get optional search criteria attributes */ + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); /* * Find the certificate(s) first. */ - if (params->certLabel) { - nsscert = PK11_FindCertFromNickname(params->certLabel, - NULL); + if (certlabel != NULL) { + nsscert = PK11_FindCertFromNickname(certlabel, NULL); if (nsscert == NULL) { HANDLE_NSS_ERROR(KMF_ERR_CERT_NOT_FOUND) } } else { - rv = nss_find_matching_certs(slot, - params->issuer, - params->subject, - params->serial, - &certlist, 0); + rv = nss_find_matching_certs(slot, issuer, subject, serial, + &certlist, 0); if (rv == KMF_OK && certlist == NULL) { return (KMF_ERR_CERT_NOT_FOUND); @@ -2198,8 +1759,8 @@ NSS_ExportP12(KMF_HANDLE_T handle, * The KMF_CREDENTIAL holds the password to use for * encrypting the PKCS12 key information. */ - pwitem.data = (uchar_t *)params->p12cred.cred; - pwitem.len = params->p12cred.credlen; + pwitem.data = (uchar_t *)p12cred->cred; + pwitem.len = p12cred->credlen; p12ctx = p12u_InitContext(PR_FALSE, filename); if (!p12ctx) { @@ -2207,16 +1768,15 @@ NSS_ExportP12(KMF_HANDLE_T handle, } PORT_SetUCS2_ASCIIConversionFunction( - p12u_ucs2_ascii_conversion_function); + p12u_ucs2_ascii_conversion_function); - p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, - slot, NULL); + p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, slot, NULL); if (!p12ecx) { HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE) } if (SEC_PKCS12AddPasswordIntegrity(p12ecx, &pwitem, SEC_OID_SHA1) - != SECSuccess) { + != SECSuccess) { HANDLE_NSS_ERROR(KMF_ERR_INTERNAL) } @@ -2226,9 +1786,8 @@ NSS_ExportP12(KMF_HANDLE_T handle, */ if (certlist != NULL) { for (node = CERT_LIST_HEAD(certlist); - !CERT_LIST_END(node, certlist) && rv == KMF_OK; - node = CERT_LIST_NEXT(node)) { - + !CERT_LIST_END(node, certlist) && rv == KMF_OK; + node = CERT_LIST_NEXT(node)) { rv = add_cert_to_bag(p12ecx, node->cert, &pwitem); } } else if (nsscert != NULL) { @@ -2236,7 +1795,7 @@ NSS_ExportP12(KMF_HANDLE_T handle, } if (SEC_PKCS12Encode(p12ecx, p12u_WriteToExportFile, p12ctx) - != SECSuccess) { + != SECSuccess) { HANDLE_NSS_ERROR(KMF_ERR_ENCODING) } out: @@ -2261,105 +1820,8 @@ out: t[n].ulValueLen = (CK_ULONG)size; KMF_RETURN -NSS_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, - KMF_RAW_KEY_DATA *rawkey) -{ - KMF_RETURN rv = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - SECStatus ckrv = SECSuccess; - PK11SlotInfo *slot = NULL; - CERTCertificate *nss_cert = NULL; - SECKEYPrivateKeyInfo rpk; - SECItem nickname; - KMF_DATA derkey = { NULL, 0 }; - uchar_t ver = 0; - - if (!kmfh) - return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ - - if (params == NULL || params->certificate == NULL || rawkey == NULL) - return (KMF_ERR_BAD_PARAMETER); - - rv = Do_NSS_Init(handle, - params->nssparms, FALSE, &slot); - - if (rv != KMF_OK) - return (rv); - - rv = nss_authenticate(handle, slot, ¶ms->cred); - if (rv != KMF_OK) { - return (rv); - } - - /* - * Decode the cert into an NSS CERT object so we can access the - * SPKI and KeyUsage data later. - */ - nss_cert = CERT_DecodeCertFromPackage((char *)params->certificate->Data, - params->certificate->Length); - - if (nss_cert == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_BAD_CERT_FORMAT; - goto cleanup; - } - - (void) memset(&rpk, 0, sizeof (rpk)); - - rpk.arena = NULL; - rpk.version.type = siUnsignedInteger; - rpk.version.data = &ver; - rpk.version.len = 1; - if (rawkey->keytype == KMF_RSA) { - - rv = DerEncodeRSAPrivateKey(&derkey, &rawkey->rawdata.rsa); - if (rv != KMF_OK) - goto cleanup; - - rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm; - rpk.privateKey.data = derkey.Data; - rpk.privateKey.len = derkey.Length; - rpk.attributes = NULL; - - - } else if (rawkey->keytype == KMF_DSA) { - rv = DerEncodeDSAPrivateKey(&derkey, &rawkey->rawdata.dsa); - if (rv != KMF_OK) - goto cleanup; - - rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm; - rpk.privateKey.data = derkey.Data; - rpk.privateKey.len = derkey.Length; - rpk.attributes = NULL; - - } else { - return (KMF_ERR_BAD_PARAMETER); - } - - nickname.data = (uchar_t *)params->label; - nickname.len = (params->label ? strlen(params->label) : 0); - - ckrv = PK11_ImportPrivateKeyInfo(slot, &rpk, - &nickname, &nss_cert->subjectPublicKeyInfo.subjectPublicKey, - TRUE, TRUE, nss_cert->keyUsage, NULL); - - if (ckrv != CKR_OK) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_INTERNAL; - } - -cleanup: - if (nss_cert != NULL) { - CERT_DestroyCertificate(nss_cert); - } - KMF_FreeData(&derkey); - return (rv); -} - -KMF_RETURN NSS_CreateSymKey(KMF_HANDLE_T handle, - KMF_CREATESYMKEY_PARAMS *params, - KMF_KEY_HANDLE *symkey) + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -2368,21 +1830,49 @@ NSS_CreateSymKey(KMF_HANDLE_T handle, CK_MECHANISM_TYPE keyType; SECStatus nssrv; int keySize; - - if (params == NULL || symkey == NULL) { + KMF_KEY_HANDLE *symkey; + KMF_CREDENTIAL cred; + uint32_t keylen; + uint32_t keylen_size = sizeof (uint32_t); + KMF_KEY_ALG keytype; + char *keylabel = NULL; + + if (kmfh == NULL || attrlist == NULL || numattr == 0) { return (KMF_ERR_BAD_PARAMETER); } - switch (params->keytype) { + symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (symkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, (void *)&keytype, + NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, &keylen, + &keylen_size); + if (rv == KMF_ERR_ATTR_NOT_FOUND && + (keytype == KMF_DES || keytype == KMF_DES3)) + /* keylength is not required for DES and 3DES */ + rv = KMF_OK; + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + if (keylabel == NULL) + return (KMF_ERR_BAD_PARAMETER); + + switch (keytype) { case KMF_AES: keyType = CKM_AES_KEY_GEN; - keySize = params->keylength; + keySize = keylen; if (keySize == 0 || (keySize % 8) != 0) return (KMF_ERR_BAD_KEY_SIZE); break; case KMF_RC4: keyType = CKM_RC4_KEY_GEN; - keySize = params->keylength; + keySize = keylen; if (keySize == 0 || (keySize % 8) != 0) return (KMF_ERR_BAD_KEY_SIZE); break; @@ -2396,7 +1886,7 @@ NSS_CreateSymKey(KMF_HANDLE_T handle, break; case KMF_GENERIC_SECRET: keyType = CKM_GENERIC_SECRET_KEY_GEN; - keySize = params->keylength; + keySize = keylen; if (keySize == 0 || (keySize % 8) != 0) return (KMF_ERR_BAD_KEY_SIZE); break; @@ -2405,26 +1895,30 @@ NSS_CreateSymKey(KMF_HANDLE_T handle, goto out; } - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, FALSE, &nss_slot); + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); if (rv != KMF_OK) { return (rv); } - rv = nss_authenticate(handle, nss_slot, ¶ms->cred); + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = nss_authenticate(handle, nss_slot, &cred); if (rv != KMF_OK) { return (rv); } nsskey = PK11_TokenKeyGen(nss_slot, keyType, NULL, keySize, NULL, - PR_TRUE, (void *)params->cred.cred); + PR_TRUE, (void *)cred.cred); if (nsskey == NULL) { SET_ERROR(kmfh, PORT_GetError()); rv = KMF_ERR_KEYGEN_FAILED; goto out; } - nssrv = PK11_SetSymKeyNickname(nsskey, params->keylabel); + nssrv = PK11_SetSymKeyNickname(nsskey, keylabel); if (nssrv != SECSuccess) { SET_ERROR(kmfh, PORT_GetError()); rv = KMF_ERR_KEYGEN_FAILED; @@ -2432,7 +1926,7 @@ NSS_CreateSymKey(KMF_HANDLE_T handle, } symkey->kstype = KMF_KEYSTORE_NSS; - symkey->keyalg = params->keytype; + symkey->keyalg = keytype; symkey->keyclass = KMF_SYMMETRIC; symkey->israw = FALSE; symkey->keyp = (void *)nsskey; @@ -2478,7 +1972,7 @@ NSS_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) return (KMF_ERR_MEMORY); (void) memcpy(rkey->keydata.val, - rawkey->rawdata.sym.keydata.val, rkey->keydata.len); + rawkey->rawdata.sym.keydata.val, rkey->keydata.len); } else { nsskey = (PK11SymKey *)(symkey->keyp); if (nsskey == NULL) @@ -2519,24 +2013,30 @@ out: } KMF_RETURN -NSS_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, - KMF_CREDENTIAL *newpin) +NSS_SetTokenPin(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; int rv; PK11SlotInfo *nss_slot = NULL; + KMF_CREDENTIAL oldcred, newcred; - if (handle == NULL || params == NULL || newpin == NULL) { + if (handle == NULL || attrlist == NULL || numattr == 0) + return (KMF_ERR_BAD_PARAMETER); + + ret = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&oldcred, NULL); + if (ret != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + ret = kmf_get_attr(KMF_NEWPIN_ATTR, attrlist, numattr, + (void *)&newcred, NULL); + if (ret != KMF_OK) return (KMF_ERR_BAD_PARAMETER); - } - ret = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, - FALSE, &nss_slot); + ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); /* If it was uninitialized, set it */ if (ret == KMF_ERR_UNINITIALIZED_TOKEN) { - rv = PK11_InitPin(nss_slot, NULL, newpin->cred); + rv = PK11_InitPin(nss_slot, NULL, newcred.cred); if (rv != SECSuccess) { SET_ERROR(kmfh, PORT_GetError()); ret = KMF_ERR_AUTH_FAILED; @@ -2544,12 +2044,11 @@ NSS_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, ret = KMF_OK; } } else if (ret == KMF_OK) { - ret = nss_authenticate(handle, nss_slot, ¶ms->cred); + ret = nss_authenticate(handle, nss_slot, &oldcred); if (ret != KMF_OK) { return (ret); } - rv = PK11_ChangePW(nss_slot, - params->cred.cred, newpin->cred); + rv = PK11_ChangePW(nss_slot, oldcred.cred, newcred.cred); if (rv != SECSuccess) { SET_ERROR(kmfh, PORT_GetError()); ret = KMF_ERR_AUTH_FAILED; @@ -2558,3 +2057,795 @@ NSS_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, return (ret); } + +KMF_RETURN +NSS_StoreKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + PK11SlotInfo *nss_slot = NULL; + KMF_CREDENTIAL cred = {NULL, 0}; + KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL; + KMF_RAW_KEY_DATA *rawkey = NULL; + char *keylabel = NULL; + SECStatus ckrv = SECSuccess; + SECItem nickname = {NULL, 0}; + CERTCertificate *nss_cert = NULL; + + if (kmfh == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } + + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) { + return (rv); + } + + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = nss_authenticate(handle, nss_slot, &cred); + if (rv != KMF_OK) { + return (rv); + } + + pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); + if (pubkey == NULL) { + /* look for private key */ + prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, + numattr); + if (prikey == NULL) + /* look for raw key */ + rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, + attrlist, numattr); + } + + /* If no keys were found, return error */ + if (pubkey == NULL && prikey == NULL && rawkey == NULL) + return (KMF_ERR_ATTR_NOT_FOUND); + + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + if (keylabel != NULL) { + nickname.data = (uchar_t *)keylabel; + nickname.len = strlen(keylabel); + } + + if (rawkey != NULL) { + uchar_t ver = 0; + SECKEYPrivateKeyInfo rpk; + KMF_DATA derkey = {NULL, 0}; + KMF_DATA *cert; + + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL) + return (rv); + /* + * Decode the cert into an NSS CERT object so we can access the + * SPKI and KeyUsage data later. + */ + nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data, + cert->Length); + + if (nss_cert == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_BAD_CERT_FORMAT; + goto cleanup; + } + + (void) memset(&rpk, 0, sizeof (rpk)); + rpk.arena = NULL; + rpk.version.type = siUnsignedInteger; + rpk.version.data = &ver; + rpk.version.len = 1; + if (rawkey->keytype == KMF_RSA) { + rv = DerEncodeRSAPrivateKey(&derkey, + &rawkey->rawdata.rsa); + if (rv != KMF_OK) + goto cleanup; + + } else if (rawkey->keytype == KMF_DSA) { + rv = DerEncodeDSAPrivateKey(&derkey, + &rawkey->rawdata.dsa); + if (rv != KMF_OK) + goto cleanup; + } + rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm; + rpk.privateKey.data = derkey.Data; + rpk.privateKey.len = derkey.Length; + rpk.attributes = NULL; + + ckrv = PK11_ImportPrivateKeyInfo(nss_slot, &rpk, &nickname, + &nss_cert->subjectPublicKeyInfo.subjectPublicKey, TRUE, + TRUE, nss_cert->keyUsage, NULL); + if (ckrv != CKR_OK) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_INTERNAL; + } + kmf_free_data(&derkey); + } else if (pubkey != NULL && pubkey->kstype == KMF_KEYSTORE_NSS) { + CK_OBJECT_HANDLE pk; + SECKEYPublicKey *publicKey = (SECKEYPublicKey *) pubkey->keyp; + + pk = PK11_ImportPublicKey(nss_slot, publicKey, PR_TRUE); + if (pk == CK_INVALID_HANDLE) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_INTERNAL; + } + } else if (prikey != NULL && prikey->kstype == KMF_KEYSTORE_NSS) { + SECKEYPrivateKey *pk; + SECKEYPrivateKey *privKey = (SECKEYPrivateKey *) prikey->keyp; + + pk = PK11_LoadPrivKey(nss_slot, privKey, NULL, PR_TRUE, + PR_TRUE); + if (pk == CK_INVALID_HANDLE) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_INTERNAL; + } + /* We stored it, but don't need the handle anymore */ + SECKEY_DestroyPrivateKey(pk); + } + +cleanup: + if (nss_cert != NULL) + CERT_DestroyCertificate(nss_cert); + PK11_FreeSlot(nss_slot); + return (rv); +} + +/* + * This function is called by NSS_StoreCert() and NSS_ImportCert(). + * The "label" and "trust_flag" arguments can be NULL. + */ +static KMF_RETURN +store_cert(KMF_HANDLE_T handle, PK11SlotInfo *nss_slot, KMF_DATA *cert, + char *label, char *trust_flag) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + SECStatus nss_rv; + CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); + CERTCertificate *nss_cert = NULL; + CERTCertTrust *nss_trust = NULL; + + if (nss_slot == NULL || cert == NULL) + return (KMF_ERR_BAD_PARAMETER); + + nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data, + cert->Length); + if (nss_cert == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + ret = KMF_ERR_BAD_CERT_FORMAT; + goto out; + } + + /* Store the cert into the NSS database */ + nss_rv = PK11_ImportCert(nss_slot, nss_cert, CK_INVALID_HANDLE, + label, 0); + if (nss_rv) { + SET_ERROR(kmfh, nss_rv); + ret = KMF_ERR_BAD_CERT_FORMAT; + goto out; + } + + /* If trust_flag is NULL, then we are done */ + if (trust_flag == NULL) + goto out; + + nss_trust = (CERTCertTrust *) malloc(sizeof (CERTCertTrust)); + if (nss_trust == NULL) { + ret = KMF_ERR_MEMORY; + goto out; + } + + nss_rv = CERT_DecodeTrustString(nss_trust, trust_flag); + if (nss_rv) { + SET_ERROR(kmfh, nss_rv); + ret = KMF_ERR_BAD_PARAMETER; + goto out; + } + + nss_rv = CERT_ChangeCertTrust(certHandle, nss_cert, nss_trust); + if (nss_rv) { + SET_ERROR(kmfh, nss_rv); + ret = KMF_ERR_BAD_PARAMETER; + } + +out: + if (nss_cert != NULL) { + CERT_DestroyCertificate(nss_cert); + } + + if (nss_trust != NULL) { + free(nss_trust); + } + + return (ret); +} + + +KMF_RETURN +NSS_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + PK11SlotInfo *nss_slot = NULL; + KMF_DATA *cert = NULL; + char *label = NULL; + char *trust_flag = NULL; + + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } + + ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (ret != KMF_OK) + return (ret); + + /* Get the cert data */ + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL || cert->Data == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* The label attribute is optional */ + label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + + /* The trustflag attriburte is optional */ + trust_flag = kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR, attrlist, numattr); + + ret = store_cert(handle, nss_slot, cert, label, trust_flag); + +out: + if (nss_slot != NULL) { + PK11_FreeSlot(nss_slot); + } + + return (ret); +} + + +KMF_RETURN +NSS_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + PK11SlotInfo *nss_slot = NULL; + KMF_DATA cert = {NULL, 0}; + KMF_DATA cert_der = {NULL, 0}; + KMF_DATA *cptr = NULL; + KMF_ENCODE_FORMAT format; + char *label = NULL; + char *trust_flag = NULL; + char *certfile = NULL; + + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } + + ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (ret != KMF_OK) + return (ret); + + /* Get the input cert filename attribute */ + certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); + if (certfile == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* Check the cert file and auto-detect the file format of it. */ + ret = kmf_is_cert_file(handle, certfile, &format); + if (ret != KMF_OK) + return (ret); + + ret = kmf_read_input_file(handle, certfile, &cert); + if (ret != KMF_OK) { + return (ret); + } + + /* + * If the imported cert is in PEM format, convert it to + * DER format in order to store it in NSS token. + */ + if (format == KMF_FORMAT_PEM) { + int derlen; + ret = kmf_pem_to_der(cert.Data, cert.Length, + &cert_der.Data, &derlen); + if (ret != KMF_OK) { + goto cleanup; + } + cert_der.Length = (size_t)derlen; + cptr = &cert_der; + } else { + cptr = &cert; + } + + label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + trust_flag = kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR, attrlist, numattr); + ret = store_cert(handle, nss_slot, cptr, label, trust_flag); + +cleanup: + if (format == KMF_FORMAT_PEM) { + kmf_free_data(&cert_der); + } + + kmf_free_data(&cert); + + return (ret); +} + + +KMF_RETURN +NSS_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + PK11SlotInfo *nss_slot = NULL; + CERTSignedCrl *nss_crl = NULL; + KMF_ENCODE_FORMAT format; + int importOptions; + SECItem crlDER; + KMF_DATA crl1; + KMF_DATA crl2; + char *crlfilename; + boolean_t crlcheck = FALSE; + + if (attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } + + ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (ret != KMF_OK) { + return (ret); + } + + crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, + numattr); + if (crlfilename == NULL) + return (KMF_ERR_BAD_CRLFILE); + + /* + * Check if the input CRL file is a valid CRL file and auto-detect + * the encoded format of the file. + */ + ret = kmf_is_crl_file(handle, crlfilename, &format); + if (ret != KMF_OK) + return (ret); + + ret = kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr, + &crlcheck, NULL); + if (ret != KMF_OK) + ret = KMF_OK; /* CRL_CHECK is optional */ + + /* set importOptions */ + if (crlcheck == B_FALSE) { + importOptions = CRL_IMPORT_DEFAULT_OPTIONS | + CRL_IMPORT_BYPASS_CHECKS; + } else { + importOptions = CRL_IMPORT_DEFAULT_OPTIONS; + } + + + /* Read in the CRL file */ + crl1.Data = NULL; + crl2.Data = NULL; + ret = kmf_read_input_file(handle, crlfilename, &crl1); + if (ret != KMF_OK) { + return (ret); + } + + /* If the input CRL is in PEM format, convert it to DER first. */ + if (format == KMF_FORMAT_PEM) { + int len; + ret = kmf_pem_to_der(crl1.Data, crl1.Length, + &crl2.Data, &len); + if (ret != KMF_OK) { + goto out; + } + crl2.Length = (size_t)len; + } + + crlDER.data = format == KMF_FORMAT_ASN1 ? crl1.Data : crl2.Data; + crlDER.len = format == KMF_FORMAT_ASN1 ? crl1.Length : crl2.Length; + + nss_crl = PK11_ImportCRL(nss_slot, &crlDER, NULL, SEC_CRL_TYPE, + NULL, importOptions, NULL, CRL_DECODE_DEFAULT_OPTIONS); + + if (nss_crl == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + ret = KMF_ERR_BAD_CRLFILE; + goto out; + } + +out: + if (nss_slot != NULL) { + PK11_FreeSlot(nss_slot); + } + + if (crl1.Data != NULL) { + free(crl1.Data); + } + + if (crl2.Data != NULL) { + free(crl2.Data); + } + + if (nss_crl != NULL) { + SEC_DestroyCrl(nss_crl); + } + + return (ret); +} + +KMF_RETURN +NSS_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + CERTSignedCrl *crl = NULL; + CERTCertificate *cert = NULL; + PK11SlotInfo *nss_slot = NULL; + CERTCrlHeadNode *crlList = NULL; + CERTCrlNode *crlNode = NULL; + PRArenaPool *arena = NULL; + CERTName *name = NULL; + CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); + char *issuername, *subjectname; + + /* check params */ + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) { + return (rv); + } + + issuername = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, + numattr); + subjectname = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, + numattr); + + /* Caller must specify issuer or subject but not both */ + if ((issuername == NULL && subjectname == NULL) || + (issuername != NULL && subjectname != NULL)) + return (KMF_ERR_BAD_PARAMETER); + + /* Find the CRL based on the deletion criteria. */ + if (issuername != NULL) { + /* + * If the deletion is based on the issuer's certificate + * nickname, we will get the issuer's cert first, then + * get the CRL from the cert. + */ + cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, + issuername); + if (!cert) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CERT_NOT_FOUND; + goto out; + } + + crl = SEC_FindCrlByName(certHandle, &cert->derSubject, + SEC_CRL_TYPE); + if (crl == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + goto out; + } + } else { + /* + * If the deletion is based on the CRL's subject name, we will + * get all the CRLs from the internal database and search + * for the CRL with the same subject name. + */ + boolean_t found = B_FALSE; + int nssrv; + + nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); + if (nssrv) { + SET_ERROR(kmfh, nssrv); + rv = KMF_ERR_CRL_NOT_FOUND; + goto out; + } + + if (crlList == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + goto out; + } + + /* Allocate space for name */ + arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); + if (arena == NULL) { + rv = KMF_ERR_MEMORY; + goto out; + } + + name = PORT_ArenaZAlloc(arena, sizeof (*name)); + if (name == NULL) { + rv = KMF_ERR_MEMORY; + goto out; + } + name->arena = arena; + + crlNode = crlList->first; + while (crlNode && !found) { + char *asciiname = NULL; + SECItem* issuer; + + name = &crlNode->crl->crl.name; + if (!name) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + break; + } + + asciiname = CERT_NameToAscii(name); + if (asciiname == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + break; + } + + if (strcmp(subjectname, asciiname) == 0) { + found = B_TRUE; + issuer = &crlNode->crl->crl.derName; + crl = SEC_FindCrlByName(certHandle, issuer, + SEC_CRL_TYPE); + if (crl == NULL) { + /* We found a cert but no CRL */ + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + } + } + PORT_Free(asciiname); + crlNode = crlNode->next; + } + + if (rv) { + goto out; + } + } + + if (crl) { + (void) SEC_DeletePermCRL(crl); + } + +out: + if (nss_slot != NULL) { + PK11_FreeSlot(nss_slot); + } + + if (crlList != NULL) { + PORT_FreeArena(crlList->arena, PR_FALSE); + } + + if (arena != NULL) { + PORT_FreeArena(arena, PR_FALSE); + } + + if (cert != NULL) { + CERT_DestroyCertificate(cert); + } + + if (crl != NULL) { + SEC_DestroyCrl(crl); + } + + return (rv); +} + +KMF_RETURN +NSS_FindCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + PK11SlotInfo *nss_slot = NULL; + CERTCrlHeadNode *crlList = NULL; + CERTCrlNode *crlNode = NULL; + PRArenaPool *arena = NULL; + CERTName *name = NULL; + SECStatus nssrv; + char *asciiname = NULL; + int crl_num; + int i, *CRLCount; + CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); + char **CRLNameList; + + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) { + return (rv); + } + + CRLCount = kmf_get_attr_ptr(KMF_CRL_COUNT_ATTR, attrlist, numattr); + if (CRLCount == NULL) + return (KMF_ERR_BAD_PARAMETER); + + CRLNameList = (char **)kmf_get_attr_ptr(KMF_CRL_NAMELIST_ATTR, + attrlist, numattr); + + /* Look up Crls */ + nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); + if (nssrv) { + SET_ERROR(kmfh, rv); + rv = KMF_ERR_CRL_NOT_FOUND; + goto out; + } + + /* Allocate space for name first */ + arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); + if (arena == NULL) { + rv = KMF_ERR_MEMORY; + goto out; + } + + name = PORT_ArenaZAlloc(arena, sizeof (*name)); + if (name == NULL) { + rv = KMF_ERR_MEMORY; + goto out; + } + name->arena = arena; + + /* + * Loop thru the crlList and create a crl list with CRL's subject name. + */ + crlNode = crlList->first; + crl_num = 0; + while (crlNode) { + char *subj_name; + + /* Get the CRL subject name */ + name = &crlNode->crl->crl.name; + if (!name) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + break; + } + + + if (CRLNameList != NULL) { + asciiname = CERT_NameToAscii(name); + if (asciiname == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + break; + } + subj_name = strdup(asciiname); + PORT_Free(asciiname); + if (subj_name == NULL) { + rv = KMF_ERR_MEMORY; + break; + } + CRLNameList[crl_num] = subj_name; + } + + crl_num++; + crlNode = crlNode->next; + } + + if (rv == KMF_OK) { + /* success */ + *CRLCount = crl_num; + } + +out: + if (nss_slot != NULL) { + PK11_FreeSlot(nss_slot); + } + + if (crlList != NULL) { + PORT_FreeArena(crlList->arena, PR_FALSE); + } + + if (arena != NULL) { + PORT_FreeArena(arena, PR_FALSE); + } + + /* If failed, free memory allocated for the returning rlist */ + if (rv && (CRLNameList != NULL)) { + for (i = 0; i < crl_num; i++) { + free(CRLNameList[i]); + } + } + + return (rv); +} + +KMF_RETURN +NSS_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + PK11SlotInfo *nss_slot = NULL; + CERTCertificate *cert = NULL; + CERTSignedCrl *crl = NULL; + CERTCrlEntry *entry; + boolean_t match = B_FALSE; + int i; + CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); + char *certlabel; + KMF_DATA *certdata; + + /* check params */ + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) { + return (rv); + } + + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + + /* Find the certificate first */ + if (certlabel != NULL) { + cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, + certlabel); + } else { + SECItem derCert = { NULL, 0}; + + certdata = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, + attrlist, numattr); + + if (certdata == NULL) + return (KMF_ERR_BAD_PARAMETER); + + derCert.data = certdata->Data; + derCert.len = certdata->Length; + + cert = CERT_FindCertByDERCert(certHandle, &derCert); + } + + if (cert == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CERT_NOT_FOUND; + goto out; + } + + /* Find the CRL with the same issuer as the given certificate. */ + crl = SEC_FindCrlByName(certHandle, &cert->derIssuer, SEC_CRL_TYPE); + if (crl == NULL) { + /* + * Could not find the CRL issued by the same issuer. This + * usually means that the CRL is not installed in the DB. + */ + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + goto out; + + } + + /* Check if the certificate's serialNumber is revoked in the CRL */ + i = 0; + while ((entry = (crl->crl).entries[i++]) != NULL) { + if (SECITEM_CompareItem(&(cert->serialNumber), + &(entry->serialNumber)) == SECEqual) { + match = B_TRUE; + break; + } + } + + if (!match) { + rv = KMF_ERR_NOT_REVOKED; + } + +out: + if (nss_slot != NULL) { + PK11_FreeSlot(nss_slot); + } + + if (cert != NULL) { + CERT_DestroyCertificate(cert); + } + + if (crl != NULL) { + SEC_DestroyCrl(crl); + } + + return (rv); +} diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers b/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers index ae025ddd8f..08ad0b561f 100644 --- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers @@ -37,14 +37,14 @@ SUNWprivate_1.1 { OpenSSL_DeleteCert; OpenSSL_DeleteKey; OpenSSL_EncodePubKeyData; - OpenSSL_ExportP12; + OpenSSL_ExportPK12; OpenSSL_FindCert; OpenSSL_FindCertInCRL; OpenSSL_FindKey; + OpenSSL_FindPrikeyByCert; OpenSSL_FreeKMFCert; OpenSSL_GetErrorString; OpenSSL_GetOCSPStatusForCert; - OpenSSL_GetPrikeyByCert; OpenSSL_GetSymKeyValue; OpenSSL_ImportCRL; OpenSSL_IsCRLFile; @@ -52,10 +52,10 @@ SUNWprivate_1.1 { OpenSSL_ListCRL; OpenSSL_SignData; OpenSSL_StoreCert; - OpenSSL_StorePrivateKey; + OpenSSL_StoreKey; OpenSSL_VerifyCRLFile; - openssl_read_pkcs12; - openssl_import_keypair; + openssl_import_objects; + openssl_build_pk12; local: *; }; diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c index 2e88fee0ae..88ff83dbea 100644 --- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c @@ -103,7 +103,6 @@ KMF_X509_EXT_SUBJ_KEY_ID |\ KMF_X509_EXT_POLICY_MAPPING) -static BIO *bio_err = NULL; static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, @@ -135,13 +134,22 @@ static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, mutex_t init_lock = DEFAULTMUTEX; static int ssl_initialized = 0; +static BIO *bio_err = NULL; + +static int +test_for_file(char *, mode_t); static KMF_RETURN -extract_objects(KMF_HANDLE *, KMF_FINDCERT_PARAMS *, char *, - CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *); +extract_pem(KMF_HANDLE *, char *, char *, KMF_BIGINT *, char *, + CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *); static KMF_RETURN -kmf_load_cert(KMF_HANDLE *, KMF_FINDCERT_PARAMS *, char *, KMF_DATA *); +kmf_load_cert(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, + char *, KMF_DATA *); + +static KMF_RETURN +load_certs(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, + char *, KMF_DATA **, uint32_t *); static KMF_RETURN sslBN2KMFBN(BIGNUM *, KMF_BIGINT *); @@ -149,24 +157,26 @@ sslBN2KMFBN(BIGNUM *, KMF_BIGINT *); static EVP_PKEY * ImportRawRSAKey(KMF_RAW_RSA_KEY *); +static KMF_RETURN +convertToRawKey(EVP_PKEY *, KMF_RAW_KEY_DATA *); + KMF_RETURN -OpenSSL_FindCert(KMF_HANDLE_T, - KMF_FINDCERT_PARAMS *, - KMF_X509_DER_CERT *, - uint32_t *); +OpenSSL_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); void OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); KMF_RETURN -OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *, KMF_DATA *); +OpenSSL_StoreCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); + +KMF_RETURN +OpenSSL_DeleteCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *); +OpenSSL_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, - KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); +OpenSSL_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); @@ -176,20 +186,19 @@ OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, KMF_DATA *, KMF_DATA *); KMF_RETURN -OpenSSL_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, - KMF_KEY_HANDLE *, boolean_t); +OpenSSL_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *); +OpenSSL_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *); +OpenSSL_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_ListCRL(KMF_HANDLE_T, KMF_LISTCRL_PARAMS *, char **); +OpenSSL_ListCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *); +OpenSSL_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *, @@ -199,48 +208,35 @@ KMF_RETURN OpenSSL_GetErrorString(KMF_HANDLE_T, char **); KMF_RETURN -OpenSSL_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, - KMF_KEY_HANDLE *, KMF_KEY_ALG); +OpenSSL_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, KMF_DATA *, KMF_DATA *); KMF_RETURN -OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, KMF_OCSPREQUEST_PARAMS *, - char *reqfile); +OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, KMF_OCSPRESPONSE_PARAMS_INPUT *, - KMF_OCSPRESPONSE_PARAMS_OUTPUT *); +OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, - KMF_KEY_HANDLE *, uint32_t *); +OpenSSL_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_ExportP12(KMF_HANDLE_T, - KMF_EXPORTP12_PARAMS *, - int, KMF_X509_DER_CERT *, - int, KMF_KEY_HANDLE *, - char *); +OpenSSL_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, - KMF_RAW_KEY_DATA *); - -KMF_RETURN -OpenSSL_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, - KMF_KEY_HANDLE *); +OpenSSL_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); KMF_RETURN -OpenSSL_VerifyCRLFile(KMF_HANDLE_T, KMF_VERIFYCRL_PARAMS *); +OpenSSL_VerifyCRLFile(KMF_HANDLE_T, char *, KMF_DATA *); KMF_RETURN -OpenSSL_CheckCRLDate(KMF_HANDLE_T, KMF_CHECKCRLDATE_PARAMS *); +OpenSSL_CheckCRLDate(KMF_HANDLE_T, char *); KMF_RETURN OpenSSL_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, @@ -267,14 +263,14 @@ KMF_PLUGIN_FUNCLIST openssl_plugin_table = NULL, /* FindCRL */ OpenSSL_FindCertInCRL, OpenSSL_GetErrorString, - OpenSSL_GetPrikeyByCert, + OpenSSL_FindPrikeyByCert, OpenSSL_DecryptData, - OpenSSL_ExportP12, - OpenSSL_StorePrivateKey, + OpenSSL_ExportPK12, OpenSSL_CreateSymKey, OpenSSL_GetSymKeyValue, NULL, /* SetTokenPin */ OpenSSL_VerifyDataWithCert, + OpenSSL_StoreKey, NULL /* Finalize */ }; @@ -382,7 +378,7 @@ get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN) return (rv); } -static int +int isdir(char *path) { struct stat s; @@ -390,7 +386,7 @@ isdir(char *path) if (stat(path, &s) == -1) return (0); - return (s.st_mode & S_IFDIR); + return ((s.st_mode & S_IFMT) == S_IFDIR); } static KMF_RETURN @@ -441,8 +437,10 @@ cleanup: return (rv); } + static KMF_RETURN -check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) +check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial, + boolean_t *match) { KMF_RETURN rv = KMF_OK; boolean_t findIssuer = FALSE; @@ -461,21 +459,21 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME)); (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME)); - if (params->issuer != NULL && strlen(params->issuer)) { - rv = KMF_DNParser(params->issuer, &issuerDN); + if (issuer != NULL && strlen(issuer)) { + rv = kmf_dn_parser(issuer, &issuerDN); if (rv != KMF_OK) return (KMF_ERR_BAD_PARAMETER); rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN); if (rv != KMF_OK) { - KMF_FreeDN(&issuerDN); + kmf_free_dn(&issuerDN); return (KMF_ERR_BAD_PARAMETER); } findIssuer = TRUE; } - if (params->subject != NULL && strlen(params->subject)) { - rv = KMF_DNParser(params->subject, &subjectDN); + if (subject != NULL && strlen(subject)) { + rv = kmf_dn_parser(subject, &subjectDN); if (rv != KMF_OK) { rv = KMF_ERR_BAD_PARAMETER; goto cleanup; @@ -488,7 +486,7 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) } findSubject = TRUE; } - if (params->serial != NULL && params->serial->val != NULL) + if (serial != NULL && serial->val != NULL) findSerial = TRUE; if (findSerial) { @@ -499,7 +497,7 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) if (bn != NULL) { int bnlen = BN_num_bytes(bn); - if (bnlen == params->serial->len) { + if (bnlen == serial->len) { uchar_t *a = malloc(bnlen); if (a == NULL) { rv = KMF_ERR_MEMORY; @@ -507,9 +505,8 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) goto cleanup; } bnlen = BN_bn2bin(bn, a); - *match = !memcmp(a, - params->serial->val, - params->serial->len); + *match = (memcmp(a, serial->val, serial->len) == + 0); rv = KMF_OK; free(a); } @@ -522,15 +519,17 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) } } if (findIssuer) { - *match = !KMF_CompareRDNs(&issuerDN, &certIssuerDN); - if (!(*match)) { + *match = (kmf_compare_rdns(&issuerDN, &certIssuerDN) == 0); + if ((*match) == B_FALSE) { + /* stop checking and bail */ rv = KMF_OK; goto cleanup; } } if (findSubject) { - *match = !KMF_CompareRDNs(&subjectDN, &certSubjectDN); - if (!(*match)) { + *match = (kmf_compare_rdns(&subjectDN, &certSubjectDN) == 0); + if ((*match) == B_FALSE) { + /* stop checking and bail */ rv = KMF_OK; goto cleanup; } @@ -539,22 +538,27 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) *match = TRUE; cleanup: if (findIssuer) { - KMF_FreeDN(&issuerDN); - KMF_FreeDN(&certIssuerDN); + kmf_free_dn(&issuerDN); + kmf_free_dn(&certIssuerDN); } if (findSubject) { - KMF_FreeDN(&subjectDN); - KMF_FreeDN(&certSubjectDN); + kmf_free_dn(&subjectDN); + kmf_free_dn(&certSubjectDN); } return (rv); } + +/* + * This function loads a certificate file into an X509 data structure, and + * checks if its issuer, subject or the serial number matches with those + * values. If it matches, then return the X509 data structure. + */ static KMF_RETURN load_X509cert(KMF_HANDLE *kmfh, - KMF_FINDCERT_PARAMS *params, - char *pathname, - X509 **outcert) + char *issuer, char *subject, KMF_BIGINT *serial, + char *pathname, X509 **outcert) { KMF_RETURN rv = KMF_OK; X509 *xcert = NULL; @@ -566,7 +570,7 @@ load_X509cert(KMF_HANDLE *kmfh, * auto-detect the file format, regardless of what * the 'format' parameters in the params say. */ - rv = KMF_GetFileFormat(pathname, &format); + rv = kmf_get_file_format(pathname, &format); if (rv != KMF_OK) { if (rv == KMF_ERR_OPEN_FILE) rv = KMF_ERR_CERT_NOT_FOUND; @@ -605,7 +609,8 @@ load_X509cert(KMF_HANDLE *kmfh, goto cleanup; } - if (check_cert(xcert, params, &match) != KMF_OK || match == FALSE) { + if (check_cert(xcert, issuer, subject, serial, &match) != KMF_OK || + match == FALSE) { rv = KMF_ERR_CERT_NOT_FOUND; goto cleanup; } @@ -635,8 +640,9 @@ datacmp(const void *a, const void *b) } static KMF_RETURN -load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, - KMF_DATA **certlist, uint32_t *numcerts) +load_certs(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial, + KMF_CERT_VALIDITY validity, char *pathname, + KMF_DATA **certlist, uint32_t *numcerts) { KMF_RETURN rv = KMF_OK; int i; @@ -645,7 +651,7 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, int hits = 0; KMF_ENCODE_FORMAT format; - rv = KMF_GetFileFormat(pathname, &format); + rv = kmf_get_file_format(pathname, &format); if (rv != KMF_OK) { if (rv == KMF_ERR_OPEN_FILE) rv = KMF_ERR_CERT_NOT_FOUND; @@ -658,7 +664,8 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, return (KMF_ERR_MEMORY); certs->Data = NULL; certs->Length = 0; - rv = kmf_load_cert(kmfh, params, pathname, certs); + rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, + pathname, certs); if (rv == KMF_OK) { *certlist = certs; *numcerts = 1; @@ -671,7 +678,7 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, format != KMF_FORMAT_PEM_KEYPAIR) { /* This function only works on PEM files */ - rv = extract_objects(kmfh, params, pathname, + rv = extract_pem(kmfh, issuer, subject, serial, pathname, (uchar_t *)NULL, 0, NULL, &certs, &nc); } else { return (KMF_ERR_ENCODING); @@ -681,10 +688,10 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, return (rv); for (i = 0; i < nc; i++) { - if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) { - rv = KMF_CheckCertDate(kmfh, &certs[i]); - } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) { - rv = KMF_CheckCertDate(kmfh, &certs[i]); + if (validity == KMF_NONEXPIRED_CERTS) { + rv = kmf_check_cert_date(kmfh, &certs[i]); + } else if (validity == KMF_EXPIRED_CERTS) { + rv = kmf_check_cert_date(kmfh, &certs[i]); if (rv == KMF_OK) rv = KMF_ERR_CERT_NOT_FOUND; if (rv == KMF_ERR_VALIDITY_PERIOD) @@ -692,7 +699,7 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, } if (rv != KMF_OK) { /* Remove this cert from the list by clearing it. */ - KMF_FreeData(&certs[i]); + kmf_free_data(&certs[i]); } else { hits++; /* count valid certs found */ } @@ -714,25 +721,27 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, return (rv); } + static KMF_RETURN kmf_load_cert(KMF_HANDLE *kmfh, - KMF_FINDCERT_PARAMS *params, - char *pathname, - KMF_DATA *cert) + char *issuer, char *subject, KMF_BIGINT *serial, + KMF_CERT_VALIDITY validity, + char *pathname, + KMF_DATA *cert) { KMF_RETURN rv = KMF_OK; X509 *x509cert = NULL; - rv = load_X509cert(kmfh, params, pathname, &x509cert); + rv = load_X509cert(kmfh, issuer, subject, serial, pathname, &x509cert); if (rv == KMF_OK && x509cert != NULL && cert != NULL) { rv = ssl_cert2KMFDATA(kmfh, x509cert, cert); if (rv != KMF_OK) { goto cleanup; } - if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) { - rv = KMF_CheckCertDate(kmfh, cert); - } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) { - rv = KMF_CheckCertDate(kmfh, cert); + if (validity == KMF_NONEXPIRED_CERTS) { + rv = kmf_check_cert_date(kmfh, cert); + } else if (validity == KMF_EXPIRED_CERTS) { + rv = kmf_check_cert_date(kmfh, cert); if (rv == KMF_OK) { /* * This is a valid cert so skip it. @@ -926,7 +935,7 @@ openssl_load_key(KMF_HANDLE_T handle, const char *file) return (NULL); } - if (KMF_GetFileFormat((char *)file, &format) != KMF_OK) + if (kmf_get_file_format((char *)file, &format) != KMF_OK) return (NULL); keyfile = BIO_new_file(file, "rb"); @@ -941,12 +950,12 @@ openssl_load_key(KMF_HANDLE_T handle, const char *file) (void) BIO_free(keyfile); keyfile = NULL; /* Try odd ASN.1 variations */ - rv = KMF_ReadInputFile(kmfh, (char *)file, + rv = kmf_read_input_file(kmfh, (char *)file, &filedata); if (rv == KMF_OK) { (void) readAltFormatPrivateKey(&filedata, &pkey); - KMF_FreeData(&filedata); + kmf_free_data(&filedata); } } } else if (format == KMF_FORMAT_PEM || @@ -958,12 +967,12 @@ openssl_load_key(KMF_HANDLE_T handle, const char *file) * Check if this is the alt. format * RSA private key file. */ - rv = KMF_ReadInputFile(kmfh, (char *)file, + rv = kmf_read_input_file(kmfh, (char *)file, &filedata); if (rv == KMF_OK) { uchar_t *d = NULL; int len; - rv = KMF_Pem2Der(filedata.Data, + rv = kmf_pem_to_der(filedata.Data, filedata.Length, &d, &len); if (rv == KMF_OK && d != NULL) { derdata.Data = d; @@ -972,7 +981,7 @@ openssl_load_key(KMF_HANDLE_T handle, const char *file) &derdata, &pkey); free(d); } - KMF_FreeData(&filedata); + kmf_free_data(&filedata); } } } @@ -988,31 +997,59 @@ end: } KMF_RETURN -OpenSSL_FindCert(KMF_HANDLE_T handle, - KMF_FINDCERT_PARAMS *params, - KMF_X509_DER_CERT *kmf_cert, - uint32_t *num_certs) +OpenSSL_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - char *fullpath; int i, n; uint32_t maxcerts = 0; + uint32_t *num_certs; + KMF_X509_DER_CERT *kmf_cert = NULL; + char *dirpath = NULL; + char *filename = NULL; + char *fullpath = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; - if (num_certs == NULL || params == NULL) + num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (num_certs == NULL) return (KMF_ERR_BAD_PARAMETER); + /* num_certs should reference the size of kmf_cert */ maxcerts = *num_certs; if (maxcerts == 0) maxcerts = 0xFFFFFFFF; *num_certs = 0; - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.certfile); + /* Get the optional returned certificate list */ + kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, + numattr); + /* + * The dirpath attribute and the filename attribute can not be NULL + * at the same time. + */ + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, + numattr); + + fullpath = get_fullpath(dirpath, filename); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); + /* Get optional search criteria attributes */ + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); + if (rv != KMF_OK) { + validity = KMF_ALL_CERTS; + rv = KMF_OK; + } + if (isdir(fullpath)) { DIR *dirp; struct dirent *dp; @@ -1033,14 +1070,14 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, fname = get_fullpath(fullpath, (char *)&dp->d_name); - rv = load_certs(kmfh, params, fname, &certlist, - &loaded_certs); + rv = load_certs(kmfh, issuer, subject, serial, + validity, fname, &certlist, &loaded_certs); if (rv != KMF_OK) { free(fname); if (certlist != NULL) { for (i = 0; i < loaded_certs; i++) - KMF_FreeData(&certlist[i]); + kmf_free_data(&certlist[i]); free(certlist); } continue; @@ -1068,10 +1105,10 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, * certs that were not used. */ for (; i < loaded_certs; i++) - KMF_FreeData(&certlist[i]); + kmf_free_data(&certlist[i]); } else { for (i = 0; i < loaded_certs; i++) - KMF_FreeData(&certlist[i]); + kmf_free_data(&certlist[i]); n += loaded_certs; } free(certlist); @@ -1080,7 +1117,7 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, (*num_certs) = n; if (*num_certs == 0) rv = KMF_ERR_CERT_NOT_FOUND; - else + if (*num_certs > 0) rv = KMF_OK; exit: (void) closedir(dirp); @@ -1088,8 +1125,8 @@ exit: KMF_DATA *certlist = NULL; uint32_t loaded_certs = 0; - rv = load_certs(kmfh, params, fullpath, - &certlist, &loaded_certs); + rv = load_certs(kmfh, issuer, subject, serial, validity, + fullpath, &certlist, &loaded_certs); if (rv != KMF_OK) { free(fullpath); return (rv); @@ -1112,15 +1149,14 @@ exit: } /* If maxcerts < loaded_certs, clean up */ for (; i < loaded_certs; i++) - KMF_FreeData(&certlist[i]); + kmf_free_data(&certlist[i]); } else if (certlist != NULL) { for (i = 0; i < loaded_certs; i++) - KMF_FreeData(&certlist[i]); + kmf_free_data(&certlist[i]); n = loaded_certs; } - if (certlist) + if (certlist != NULL) free(certlist); - *num_certs = n; } @@ -1145,133 +1181,92 @@ OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, } } +/*ARGSUSED*/ KMF_RETURN -OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, - KMF_DATA * pcert) +OpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - X509 *xcert = NULL; - FILE *fp; - unsigned char *outbuf; - unsigned char *outbuf_p; - char *fullpath; - int outbuflen; - int len; + KMF_DATA *cert = NULL; + char *outfilename = NULL; + char *dirpath = NULL; + char *fullpath = NULL; KMF_ENCODE_FORMAT format; - if (params == NULL || params->ks_opt_u.openssl_opts.certfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - /* - * check if the cert output format is supported by OPENSSL. - * however, since the keystore for OPENSSL is just a file, we have - * no way to store the format along with the file. - */ - format = params->sslparms.format; - if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) - return (KMF_ERR_BAD_CERT_FORMAT); - - - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.certfile); - if (fullpath == NULL) + /* Get the cert data */ + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL || cert->Data == NULL) return (KMF_ERR_BAD_PARAMETER); - /* - * When storing a certificate, you must specify a filename. - */ - if (isdir(fullpath)) { - free(fullpath); + /* Check the output filename and directory attributes. */ + outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, + numattr); + if (outfilename == NULL) return (KMF_ERR_BAD_PARAMETER); - } - - /* copy cert data to outbuf */ - outbuflen = pcert->Length; - outbuf = malloc(outbuflen); - if (outbuf == NULL) { - free(fullpath); - return (KMF_ERR_MEMORY); - } - (void) memcpy(outbuf, pcert->Data, pcert->Length); - if ((fp = fopen(fullpath, "w")) == NULL) { - SET_SYS_ERROR(kmfh, errno); - ret = KMF_ERR_INTERNAL; - goto out; - } - - if (format == KMF_FORMAT_ASN1) { - len = fwrite(outbuf, 1, outbuflen, fp); - if (len != outbuflen) { - SET_SYS_ERROR(kmfh, errno); - ret = KMF_ERR_WRITE_FILE; - } else { - ret = KMF_OK; - } - goto out; - } + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + fullpath = get_fullpath(dirpath, outfilename); + if (fullpath == NULL) + return (KMF_ERR_BAD_CERTFILE); - /* - * The output format is not KMF_FORMAT_ASN1, so we will - * Convert the cert data to OpenSSL internal X509 first. - */ - outbuf_p = outbuf; /* use a temp pointer; required by openssl */ - xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, outbuflen); - if (xcert == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_ENCODING; + /* Check the optional format attribute */ + ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, + &format, NULL); + if (ret != KMF_OK) { + /* If there is no format attribute, then default to PEM */ + format = KMF_FORMAT_PEM; + ret = KMF_OK; + } else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) { + ret = KMF_ERR_BAD_CERT_FORMAT; goto out; } - if (format == KMF_FORMAT_PEM) { - /* Convert to the PEM format and write it out */ - if (!PEM_write_X509(fp, xcert)) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_ENCODING; - } else { - ret = KMF_OK; - } - goto out; - } + /* Store the certificate in the file with the specified format */ + ret = kmf_create_cert_file(cert, format, fullpath); out: if (fullpath != NULL) free(fullpath); - if (outbuf != NULL) { - free(outbuf); - } - if (fp != NULL) { - (void) fclose(fp); - } - - if (xcert != NULL) { - X509_free(xcert); - } - return (ret); } + KMF_RETURN -OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) +OpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - char *fullpath = NULL; KMF_DATA certdata = {NULL, 0}; + char *dirpath = NULL; + char *filename = NULL; + char *fullpath = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; - if (params == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.certfile); - + /* + * Get the DIRPATH and CERT_FILENAME attributes. They can not be + * NULL at the same time. + */ + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, + numattr); + fullpath = get_fullpath(dirpath, filename); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); + /* Get optional search criteria attributes */ + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); + if (rv != KMF_OK) { + validity = KMF_ALL_CERTS; + rv = KMF_OK; + } + if (isdir(fullpath)) { DIR *dirp; struct dirent *dp; @@ -1294,8 +1289,8 @@ OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) break; } - rv = kmf_load_cert(kmfh, params, fname, - &certdata); + rv = kmf_load_cert(kmfh, issuer, subject, + serial, validity, fname, &certdata); if (rv == KMF_ERR_CERT_NOT_FOUND) { free(fname); @@ -1322,7 +1317,8 @@ OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) (void) closedir(dirp); } else { /* Just try to load a single certificate */ - rv = kmf_load_cert(kmfh, params, fullpath, &certdata); + rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, + fullpath, &certdata); if (rv == KMF_OK) { if (unlink(fullpath) != 0) { SET_SYS_ERROR(kmfh, errno); @@ -1386,8 +1382,8 @@ cleanup: } static KMF_RETURN -ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, - KMF_CREDENTIAL *cred, EVP_PKEY *pkey) +ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, + KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private) { int rv = 0; RSA *rsa; @@ -1397,7 +1393,10 @@ ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, case KMF_FORMAT_ASN1: if (pkey->type == EVP_PKEY_RSA) { rsa = EVP_PKEY_get1_RSA(pkey); - rv = i2d_RSAPrivateKey_bio(out, rsa); + if (private) + rv = i2d_RSAPrivateKey_bio(out, rsa); + else + rv = i2d_RSAPublicKey_bio(out, rsa); RSA_free(rsa); } else if (pkey->type == EVP_PKEY_DSA) { dsa = EVP_PKEY_get1_DSA(pkey); @@ -1413,15 +1412,19 @@ ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, case KMF_FORMAT_PEM: if (pkey->type == EVP_PKEY_RSA) { rsa = EVP_PKEY_get1_RSA(pkey); - rv = PEM_write_bio_RSAPrivateKey(out, - rsa, NULL /* encryption type */, - NULL, 0, NULL, cred->cred); + if (private) + rv = PEM_write_bio_RSAPrivateKey(out, + rsa, NULL, NULL, 0, NULL, + (cred != NULL ? cred->cred : NULL)); + else + rv = PEM_write_bio_RSAPublicKey(out, + rsa); RSA_free(rsa); } else if (pkey->type == EVP_PKEY_DSA) { dsa = EVP_PKEY_get1_DSA(pkey); rv = PEM_write_bio_DSAPrivateKey(out, - dsa, NULL /* encryption type */, - NULL, 0, NULL, cred->cred); + dsa, NULL, NULL, 0, NULL, + (cred != NULL ? cred->cred : NULL)); DSA_free(dsa); } @@ -1440,35 +1443,46 @@ ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, } KMF_RETURN -OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, - KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey) +OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - int format; uint32_t eValue = 0x010001; RSA *sslPrivKey = NULL; DSA *sslDSAKey = NULL; EVP_PKEY *eprikey = NULL; EVP_PKEY *epubkey = NULL; BIO *out = NULL; - char *fullpath = NULL; - - if (params == NULL || params->sslparms.keyfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); + KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL; + uint32_t keylen = 1024; + uint32_t keylen_size = sizeof (uint32_t); + boolean_t storekey = TRUE; + KMF_KEY_ALG keytype = KMF_RSA; + + rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr, + &storekey, NULL); + if (rv != KMF_OK) { + /* "storekey" is optional. Default is TRUE */ + rv = KMF_OK; } - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.keyfile); + rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); + if (rv != KMF_OK) + /* keytype is optional. KMF_RSA is default */ + rv = KMF_OK; - if (fullpath == NULL) + pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); + if (pubkey == NULL) return (KMF_ERR_BAD_PARAMETER); - /* If the requested file exists, return an error */ - if (access(fullpath, F_OK) == 0) { - free(fullpath); - return (KMF_ERR_DUPLICATE_KEYFILE); - } + privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); + if (privkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); + (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); eprikey = EVP_PKEY_new(); if (eprikey == NULL) { @@ -1482,40 +1496,57 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, rv = KMF_ERR_KEYGEN_FAILED; goto cleanup; } - if (params->keytype == KMF_RSA) { - if (params->rsa_exponent.len > 0 && - params->rsa_exponent.len <= sizeof (eValue) && - params->rsa_exponent.val != NULL) - /*LINTED*/ - eValue = *(uint32_t *)params->rsa_exponent.val; + if (keytype == KMF_RSA) { + KMF_BIGINT *rsaexp = NULL; - sslPrivKey = RSA_generate_key(params->keylength, eValue, - NULL, NULL); + rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr); + if (rsaexp != NULL) { + if (rsaexp->len > 0 && + rsaexp->len <= sizeof (eValue) && + rsaexp->val != NULL) { + /*LINTED*/ + eValue = *(uint32_t *)rsaexp->val; + } else { + rv = KMF_ERR_BAD_PARAMETER; + goto cleanup; + } + } else { + /* RSA Exponent is optional. Default is 0x10001 */ + rv = KMF_OK; + } + + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, + &keylen, &keylen_size); + if (rv == KMF_ERR_ATTR_NOT_FOUND) + /* keylen is optional, default is 1024 */ + rv = KMF_OK; + if (rv != KMF_OK) { + rv = KMF_ERR_BAD_PARAMETER; + goto cleanup; + } + + sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL); if (sslPrivKey == NULL) { SET_ERROR(kmfh, ERR_get_error()); rv = KMF_ERR_KEYGEN_FAILED; } else { - if (privkey != NULL && - EVP_PKEY_set1_RSA(eprikey, sslPrivKey)) { - privkey->kstype = KMF_KEYSTORE_OPENSSL; - privkey->keyalg = KMF_RSA; - privkey->keyclass = KMF_ASYM_PRI; - privkey->israw = FALSE; - privkey->keylabel = (char *)strdup(fullpath); - privkey->keyp = (void *)eprikey; - } + (void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey); + privkey->kstype = KMF_KEYSTORE_OPENSSL; + privkey->keyalg = KMF_RSA; + privkey->keyclass = KMF_ASYM_PRI; + privkey->israw = FALSE; + privkey->keyp = (void *)eprikey; + /* OpenSSL derives the public key from the private */ - if (pubkey != NULL && - EVP_PKEY_set1_RSA(epubkey, sslPrivKey)) { - pubkey->kstype = KMF_KEYSTORE_OPENSSL; - pubkey->keyalg = KMF_RSA; - pubkey->israw = FALSE; - pubkey->keyclass = KMF_ASYM_PUB; - pubkey->keylabel = (char *)strdup(fullpath); - pubkey->keyp = (void *)epubkey; - } + (void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey); + pubkey->kstype = KMF_KEYSTORE_OPENSSL; + pubkey->keyalg = KMF_RSA; + pubkey->israw = FALSE; + pubkey->keyclass = KMF_ASYM_PUB; + pubkey->keyp = (void *)epubkey; } - } else if (params->keytype == KMF_DSA) { + } else if (keytype == KMF_DSA) { + DSA *dp; sslDSAKey = DSA_new(); if (sslDSAKey == NULL) { SET_ERROR(kmfh, ERR_get_error()); @@ -1547,89 +1578,116 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, goto cleanup; } - if (privkey != NULL) { - privkey->kstype = KMF_KEYSTORE_OPENSSL; - privkey->keyalg = KMF_DSA; - privkey->keyclass = KMF_ASYM_PRI; - privkey->israw = FALSE; - privkey->keylabel = (char *)strdup(fullpath); - if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { - privkey->keyp = (void *)eprikey; + privkey->kstype = KMF_KEYSTORE_OPENSSL; + privkey->keyalg = KMF_DSA; + privkey->keyclass = KMF_ASYM_PRI; + privkey->israw = FALSE; + if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { + privkey->keyp = (void *)eprikey; + } else { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_KEYGEN_FAILED; + goto cleanup; + } + dp = DSA_new(); + /* Make a copy for the public key */ + if (dp != NULL) { + if ((dp->p = BN_new()) == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_MEMORY; + DSA_free(dp); + goto cleanup; + } + if ((dp->q = BN_new()) == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_MEMORY; + BN_free(dp->p); + DSA_free(dp); + goto cleanup; + } + if ((dp->g = BN_new()) == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_MEMORY; + BN_free(dp->q); + BN_free(dp->p); + DSA_free(dp); + goto cleanup; + } + if ((dp->pub_key = BN_new()) == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_MEMORY; + BN_free(dp->q); + BN_free(dp->p); + BN_free(dp->g); + DSA_free(dp); + goto cleanup; + } + (void) BN_copy(dp->p, sslDSAKey->p); + (void) BN_copy(dp->q, sslDSAKey->q); + (void) BN_copy(dp->g, sslDSAKey->g); + (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); + + pubkey->kstype = KMF_KEYSTORE_OPENSSL; + pubkey->keyalg = KMF_DSA; + pubkey->keyclass = KMF_ASYM_PUB; + pubkey->israw = FALSE; + + if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { + pubkey->keyp = (void *)epubkey; } else { SET_ERROR(kmfh, ERR_get_error()); rv = KMF_ERR_KEYGEN_FAILED; goto cleanup; } } - if (pubkey != NULL) { - DSA *dp = DSA_new(); - /* Make a copy for the public key */ - if (dp != NULL) { - if ((dp->p = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - DSA_free(dp); - goto cleanup; - } - if ((dp->q = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - BN_free(dp->p); - DSA_free(dp); - goto cleanup; - } - if ((dp->g = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - BN_free(dp->q); - BN_free(dp->p); - DSA_free(dp); - goto cleanup; - } - if ((dp->pub_key = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - BN_free(dp->q); - BN_free(dp->p); - BN_free(dp->g); - DSA_free(dp); - goto cleanup; - } - (void) BN_copy(dp->p, sslDSAKey->p); - (void) BN_copy(dp->q, sslDSAKey->q); - (void) BN_copy(dp->g, sslDSAKey->g); - (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); - - pubkey->kstype = KMF_KEYSTORE_OPENSSL; - pubkey->keyalg = KMF_DSA; - pubkey->keyclass = KMF_ASYM_PUB; - pubkey->israw = FALSE; - pubkey->keylabel = (char *)strdup(fullpath); - - if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { - pubkey->keyp = (void *)epubkey; - } else { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_KEYGEN_FAILED; - goto cleanup; - } - } - } } if (rv != KMF_OK) { goto cleanup; } - /* Store the private key to the keyfile */ - format = params->sslparms.format; - out = BIO_new_file(fullpath, "wb"); - if (out == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_OPEN_FILE; - goto cleanup; + if (storekey) { + KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */ + int i = 0; + char *keyfile = NULL, *dirpath = NULL; + KMF_ENCODE_FORMAT format; + /* + * Construct a new attribute arrray and call openssl_store_key + */ + kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR, + privkey, sizeof (privkey)); + i++; + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + if (dirpath != NULL) { + storeattrs[i].type = KMF_DIRPATH_ATTR; + storeattrs[i].pValue = dirpath; + storeattrs[i].valueLen = strlen(dirpath); + i++; + } else { + rv = KMF_OK; /* DIRPATH is optional */ + } + keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, + attrlist, numattr); + if (keyfile != NULL) { + storeattrs[i].type = KMF_KEY_FILENAME_ATTR; + storeattrs[i].pValue = keyfile; + storeattrs[i].valueLen = strlen(keyfile); + i++; + } else { + goto cleanup; /* KEYFILE is required */ + } + rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, + (void *)&format, NULL); + if (rv == KMF_OK) { + storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR; + storeattrs[i].pValue = &format; + storeattrs[i].valueLen = sizeof (format); + i++; + } + + rv = OpenSSL_StoreKey(handle, i, storeattrs); } - rv = ssl_write_private_key(kmfh, format, out, ¶ms->cred, eprikey); cleanup: if (rv != KMF_OK) { @@ -1659,17 +1717,9 @@ cleanup: if (sslDSAKey) DSA_free(sslDSAKey); - if (out != NULL) (void) BIO_free(out); - if (fullpath) - free(fullpath); - - /* Protect the file by making it read-only */ - if (rv == KMF_OK) { - (void) chmod(fullpath, 0400); - } return (rv); } @@ -1690,7 +1740,7 @@ OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, return (KMF_ERR_BAD_PARAMETER); /* Map the OID to an OpenSSL algorithm */ - AlgId = X509_AlgorithmOidToAlgId(AlgOID); + AlgId = x509_algoid_to_algid(AlgOID); if (AlgId == KMF_ALGID_NONE) return (KMF_ERR_BAD_PARAMETER); @@ -1777,20 +1827,31 @@ cleanup: KMF_RETURN /*ARGSUSED*/ -OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, - KMF_KEY_HANDLE *key, boolean_t destroy) +OpenSSL_DeleteKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; + KMF_KEY_HANDLE *key; + boolean_t destroy = B_TRUE; + + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); if (key == NULL || key->keyp == NULL) return (KMF_ERR_BAD_PARAMETER); + rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr, + (void *)&destroy, NULL); + if (rv != KMF_OK) { + /* "destroy" is optional. Default is TRUE */ + rv = KMF_OK; + } + if (key->keyclass != KMF_ASYM_PUB && key->keyclass != KMF_ASYM_PRI && key->keyclass != KMF_SYMMETRIC) return (KMF_ERR_BAD_KEY_CLASS); if (key->keyclass == KMF_SYMMETRIC) { - KMF_FreeRawSymKey((KMF_RAW_SYM_KEY *)key->keyp); + kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp); key->keyp = NULL; } else { if (key->keyp != NULL) { @@ -1826,409 +1887,6 @@ OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, } KMF_RETURN -OpenSSL_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - X509_CRL *xcrl = NULL; - X509 *xcert = NULL; - EVP_PKEY *pkey; - KMF_ENCODE_FORMAT format; - BIO *in = NULL, *out = NULL; - int openssl_ret = 0; - char *outcrlfile = NULL; - KMF_ENCODE_FORMAT outformat; - - if (params == NULL || params->sslparms.crlfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - if (params->sslparms.crl_check == B_TRUE && - params->sslparms.certfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - outcrlfile = get_fullpath(params->sslparms.dirpath, - params->sslparms.outcrlfile); - - if (outcrlfile == NULL) - return (KMF_ERR_BAD_PARAMETER); - - if (isdir(outcrlfile)) { - free(outcrlfile); - return (KMF_ERR_BAD_PARAMETER); - } - - ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); - if (ret != KMF_OK) { - free(outcrlfile); - return (ret); - } - - in = BIO_new_file(params->sslparms.crlfile, "rb"); - if (in == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (format == KMF_FORMAT_ASN1) { - xcrl = d2i_X509_CRL_bio(in, NULL); - } else if (format == KMF_FORMAT_PEM) { - xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); - } - - if (xcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CRLFILE; - goto end; - } - - /* If bypasscheck is specified, no need to verify. */ - if (params->sslparms.crl_check == B_FALSE) { - goto output; - } - - ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); - if (ret != KMF_OK) - goto end; - - /* Read in the CA cert file and convert to X509 */ - if (BIO_read_filename(in, params->sslparms.certfile) <= 0) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (format == KMF_FORMAT_ASN1) { - xcert = d2i_X509_bio(in, NULL); - } else if (format == KMF_FORMAT_PEM) { - xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); - } else { - ret = KMF_ERR_BAD_CERT_FORMAT; - goto end; - } - - if (xcert == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CERT_FORMAT; - goto end; - } - /* Now get the public key from the CA cert */ - pkey = X509_get_pubkey(xcert); - if (!pkey) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CERTFILE; - goto end; - } - - /* Verify the CRL with the CA's public key */ - openssl_ret = X509_CRL_verify(xcrl, pkey); - EVP_PKEY_free(pkey); - if (openssl_ret > 0) { - ret = KMF_OK; /* verify succeed */ - } else { - SET_ERROR(kmfh, openssl_ret); - ret = KMF_ERR_BAD_CRLFILE; - } - -output: - outformat = params->sslparms.format; - - out = BIO_new_file(outcrlfile, "wb"); - if (out == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (outformat == KMF_FORMAT_ASN1) { - openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); - } else if (outformat == KMF_FORMAT_PEM) { - openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); - } else { - ret = KMF_ERR_BAD_PARAMETER; - goto end; - } - - if (openssl_ret <= 0) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_WRITE_FILE; - } else { - ret = KMF_OK; - } - -end: - if (xcrl != NULL) - X509_CRL_free(xcrl); - - if (xcert != NULL) - X509_free(xcert); - - if (in != NULL) - (void) BIO_free(in); - - if (out != NULL) - (void) BIO_free(out); - - if (outcrlfile != NULL) - free(outcrlfile); - - return (ret); -} - -KMF_RETURN -OpenSSL_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params, - char **crldata) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - X509_CRL *x = NULL; - KMF_ENCODE_FORMAT format; - char *crlfile = NULL; - BIO *in = NULL; - BIO *mem = NULL; - long len; - char *memptr; - char *data = NULL; - - if (params == NULL || params->sslparms.crlfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - crlfile = get_fullpath(params->sslparms.dirpath, - params->sslparms.crlfile); - - if (crlfile == NULL) - return (KMF_ERR_BAD_PARAMETER); - - if (isdir(crlfile)) { - free(crlfile); - return (KMF_ERR_BAD_PARAMETER); - } - - ret = KMF_IsCRLFile(handle, crlfile, &format); - if (ret != KMF_OK) { - free(crlfile); - return (ret); - } - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - in = BIO_new_file(crlfile, "rb"); - if (in == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (format == KMF_FORMAT_ASN1) { - x = d2i_X509_CRL_bio(in, NULL); - } else if (format == KMF_FORMAT_PEM) { - x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); - } - - if (x == NULL) { /* should not happen */ - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - mem = BIO_new(BIO_s_mem()); - if (mem == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_MEMORY; - goto end; - } - - (void) X509_CRL_print(mem, x); - len = BIO_get_mem_data(mem, &memptr); - if (len <= 0) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_MEMORY; - goto end; - } - - data = malloc(len + 1); - if (data == NULL) { - ret = KMF_ERR_MEMORY; - goto end; - } - - (void) memcpy(data, memptr, len); - data[len] = '\0'; - *crldata = data; - -end: - if (x != NULL) - X509_CRL_free(x); - - if (crlfile != NULL) - free(crlfile); - - if (in != NULL) - (void) BIO_free(in); - - if (mem != NULL) - (void) BIO_free(mem); - - return (ret); -} - -KMF_RETURN -OpenSSL_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - KMF_ENCODE_FORMAT format; - char *crlfile = NULL; - BIO *in = NULL; - - if (params == NULL || params->sslparms.crlfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - crlfile = get_fullpath(params->sslparms.dirpath, - params->sslparms.crlfile); - - if (crlfile == NULL) - return (KMF_ERR_BAD_PARAMETER); - - if (isdir(crlfile)) { - ret = KMF_ERR_BAD_PARAMETER; - goto end; - } - - ret = KMF_IsCRLFile(handle, crlfile, &format); - if (ret != KMF_OK) - goto end; - - if (unlink(crlfile) != 0) { - SET_SYS_ERROR(kmfh, errno); - ret = KMF_ERR_INTERNAL; - goto end; - } - -end: - if (in != NULL) - (void) BIO_free(in); - if (crlfile != NULL) - free(crlfile); - - return (ret); -} - - -KMF_RETURN -OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - KMF_ENCODE_FORMAT format; - BIO *in = NULL; - X509 *xcert = NULL; - X509_CRL *xcrl = NULL; - STACK_OF(X509_REVOKED) *revoke_stack = NULL; - X509_REVOKED *revoke; - int i; - - if (params == NULL || params->sslparms.crlfile == NULL || - params->sslparms.certfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); - if (ret != KMF_OK) - return (ret); - - /* Read the CRL file and load it into a X509_CRL structure */ - in = BIO_new_file(params->sslparms.crlfile, "rb"); - if (in == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (format == KMF_FORMAT_ASN1) { - xcrl = d2i_X509_CRL_bio(in, NULL); - } else if (format == KMF_FORMAT_PEM) { - xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); - } - - if (xcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CRLFILE; - goto end; - } - (void) BIO_free(in); - - /* Read the Certificate file and load it into a X509 structure */ - ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); - if (ret != KMF_OK) - goto end; - - in = BIO_new_file(params->sslparms.certfile, "rb"); - if (in == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (format == KMF_FORMAT_ASN1) { - xcert = d2i_X509_bio(in, NULL); - } else if (format == KMF_FORMAT_PEM) { - xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); - } - - if (xcert == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CERTFILE; - goto end; - } - - /* Check if the certificate and the CRL have same issuer */ - if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { - ret = KMF_ERR_ISSUER; - goto end; - } - - /* Check to see if the certificate serial number is revoked */ - revoke_stack = X509_CRL_get_REVOKED(xcrl); - if (sk_X509_REVOKED_num(revoke_stack) <= 0) { - /* No revoked certificates in the CRL file */ - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_EMPTY_CRL; - goto end; - } - - for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { - /*LINTED*/ - revoke = sk_X509_REVOKED_value(revoke_stack, i); - if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, - revoke->serialNumber) == 0) { - break; - } - } - - if (i < sk_X509_REVOKED_num(revoke_stack)) { - ret = KMF_OK; - } else { - ret = KMF_ERR_NOT_REVOKED; - } - -end: - if (in != NULL) - (void) BIO_free(in); - if (xcrl != NULL) - X509_CRL_free(xcrl); - if (xcert != NULL) - X509_free(xcert); - - return (ret); -} - -KMF_RETURN OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr) { KMF_RETURN ret = KMF_OK; @@ -2452,8 +2110,7 @@ OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); if (BIO_printf(mem, ": %s\n", - X509_EXTENSION_get_critical(ex) ? "critical" : "") <= - 0) { + X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) { SET_ERROR(kmfh, ERR_get_error()); ret = KMF_ERR_ENCODING; goto out; @@ -2489,33 +2146,64 @@ out: return (ret); } + KMF_RETURN /*ARGSUSED*/ -OpenSSL_GetPrikeyByCert(KMF_HANDLE_T handle, - KMF_CRYPTOWITHCERT_PARAMS *params, - KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, - KMF_KEY_ALG keytype) +OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; - KMF_FINDKEY_PARAMS fkparms; - uint32_t numkeys = 0; - - if (params == NULL || params->sslparms.keyfile == NULL) - return (KMF_ERR_BAD_PARAMETER); + KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; + KMF_KEY_CLASS keyclass = KMF_ASYM_PRI; + KMF_KEY_HANDLE *key = NULL; + uint32_t numkeys = 1; /* 1 key only */ + char *dirpath = NULL; + char *keyfile = NULL; + KMF_ATTRIBUTE new_attrlist[16]; + int i = 0; /* * This is really just a FindKey operation, reuse the * FindKey function. */ - (void *)memset(&fkparms, 0, sizeof (fkparms)); - fkparms.kstype = KMF_KEYSTORE_OPENSSL; - fkparms.keyclass = KMF_ASYM_PRI; - fkparms.keytype = keytype; - fkparms.format = params->format; - fkparms.sslparms = params->sslparms; + kmf_set_attr_at_index(new_attrlist, i, + KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); + i++; - rv = OpenSSL_FindKey(handle, &fkparms, key, &numkeys); + kmf_set_attr_at_index(new_attrlist, i, + KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t)); + i++; + kmf_set_attr_at_index(new_attrlist, i, + KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); + i++; + + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (key == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } else { + kmf_set_attr_at_index(new_attrlist, i, + KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); + i++; + } + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + if (dirpath != NULL) { + kmf_set_attr_at_index(new_attrlist, i, + KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); + i++; + } + + keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); + if (keyfile == NULL) + return (KMF_ERR_BAD_PARAMETER); + else { + kmf_set_attr_at_index(new_attrlist, i, + KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); + i++; + } + + rv = OpenSSL_FindKey(handle, i, new_attrlist); return (rv); } @@ -2637,22 +2325,34 @@ end: } KMF_RETURN -OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, - char *reqfile) +OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; OCSP_CERTID *id = NULL; OCSP_REQUEST *req = NULL; BIO *derbio = NULL; + char *reqfile; + KMF_DATA *issuer_cert; + KMF_DATA *user_cert; - if (params->user_cert == NULL || params->issuer_cert == NULL || - reqfile == NULL) { + user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, + attrlist, numattr); + if (user_cert == NULL) return (KMF_ERR_BAD_PARAMETER); - } - ret = create_certid(handle, params->issuer_cert, params->user_cert, - &id); + issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, + attrlist, numattr); + if (issuer_cert == NULL) + return (KMF_ERR_BAD_PARAMETER); + + reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR, + attrlist, numattr); + if (reqfile == NULL) + return (KMF_ERR_BAD_PARAMETER); + + ret = create_certid(handle, issuer_cert, user_cert, &id); if (ret != KMF_OK) { return (ret); } @@ -2854,8 +2554,7 @@ end: KMF_RETURN OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, - KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, - KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out) + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; BIO *derbio = NULL; @@ -2865,19 +2564,46 @@ OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, OCSP_SINGLERESP *single = NULL; ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; int index, status, reason; + KMF_DATA *issuer_cert; + KMF_DATA *user_cert; + KMF_DATA *signer_cert; + KMF_DATA *response; + int *response_reason, *response_status, *cert_status; + boolean_t ignore_response_sign = B_FALSE; /* default is FALSE */ + uint32_t response_lifetime; + + issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, + attrlist, numattr); + if (issuer_cert == NULL) + return (KMF_ERR_BAD_PARAMETER); - if (params_in == NULL || params_in->issuer_cert == NULL || - params_in->user_cert == NULL || params_in->response == NULL) { + user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, + attrlist, numattr); + if (user_cert == NULL) return (KMF_ERR_BAD_PARAMETER); - } - if (params_out == NULL) { + response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, + attrlist, numattr); + if (response == NULL) + return (KMF_ERR_BAD_PARAMETER); + + response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR, + attrlist, numattr); + if (response_status == NULL) + return (KMF_ERR_BAD_PARAMETER); + + response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR, + attrlist, numattr); + if (response_reason == NULL) + return (KMF_ERR_BAD_PARAMETER); + + cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, + attrlist, numattr); + if (cert_status == NULL) return (KMF_ERR_BAD_PARAMETER); - } /* Read in the response */ - derbio = BIO_new_mem_buf(params_in->response->Data, - params_in->response->Length); + derbio = BIO_new_mem_buf(response->Data, response->Length); if (!derbio) { ret = KMF_ERR_MEMORY; return (ret); @@ -2891,7 +2617,7 @@ OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, /* Check the response status */ status = OCSP_response_status(resp); - params_out->response_status = status; + *response_status = status; if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { ret = KMF_ERR_OCSP_RESPONSE_STATUS; goto end; @@ -2913,9 +2639,17 @@ OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, #endif /* DEBUG */ /* Check the basic response signature if required */ - if (params_in->ignore_response_sign == B_FALSE) { + ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr, + (void *)&ignore_response_sign, NULL); + if (ret != KMF_OK) + ret = KMF_OK; + + signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, + attrlist, numattr); + + if (ignore_response_sign == B_FALSE) { ret = check_response_signature(handle, bs, - params_in->signer_cert, params_in->issuer_cert); + signer_cert, issuer_cert); if (ret != KMF_OK) goto end; } @@ -2925,8 +2659,7 @@ OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, #endif /* DEBUG */ /* Create a certid for the certificate in question */ - ret = create_certid(handle, params_in->issuer_cert, - params_in->user_cert, &id); + ret = create_certid(handle, issuer_cert, user_cert, &id); if (ret != KMF_OK) { ret = KMF_ERR_OCSP_CERTID; goto end; @@ -2953,18 +2686,21 @@ OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, status = OCSP_single_get0_status(single, &reason, &rev, &thisupd, &nextupd); if (status == V_OCSP_CERTSTATUS_GOOD) { - params_out->cert_status = OCSP_GOOD; + *cert_status = OCSP_GOOD; } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) { - params_out->cert_status = OCSP_UNKNOWN; + *cert_status = OCSP_UNKNOWN; } else { /* revoked */ - params_out->cert_status = OCSP_REVOKED; - params_out->reason = reason; + *cert_status = OCSP_REVOKED; + *response_reason = reason; } ret = KMF_OK; - /* Verify the time */ + /* resp. time is optional, so we don't care about the return code. */ + (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr, + (void *)&response_lifetime, NULL); + if (!OCSP_check_validity(thisupd, nextupd, 300, - params_in->response_lifetime)) { + response_lifetime)) { ret = KMF_ERR_OCSP_STATUS_TIME_INVALID; goto end; } @@ -2994,14 +2730,9 @@ fetch_key(KMF_HANDLE_T handle, char *path, KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key) { KMF_RETURN rv = KMF_OK; - EVP_PKEY *pkey; + EVP_PKEY *pkey = NULL; KMF_RAW_SYM_KEY *rkey = NULL; - /* Make sure the requested file actually exists. */ - if (access(path, F_OK) != 0) { - return (KMF_ERR_KEY_NOT_FOUND); - } - if (keyclass == KMF_ASYM_PRI || keyclass == KMF_ASYM_PUB) { pkey = openssl_load_key(handle, path); @@ -3029,7 +2760,7 @@ fetch_key(KMF_HANDLE_T handle, char *path, * If the file is a recognized format, * then it is NOT a symmetric key. */ - rv = KMF_GetFileFormat(path, &fmt); + rv = kmf_get_file_format(path, &fmt); if (rv == KMF_OK || fmt != 0) { return (KMF_ERR_KEY_NOT_FOUND); } else if (rv == KMF_ERR_ENCODING) { @@ -3038,6 +2769,8 @@ fetch_key(KMF_HANDLE_T handle, char *path, * it is probably a symmetric key. */ rv = KMF_OK; + } else if (rv == KMF_ERR_OPEN_FILE) { + return (KMF_ERR_KEY_NOT_FOUND); } if (key != NULL) { @@ -3049,7 +2782,7 @@ fetch_key(KMF_HANDLE_T handle, char *path, } (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); - rv = KMF_ReadInputFile(handle, path, &keyvalue); + rv = kmf_read_input_file(handle, path, &keyvalue); if (rv != KMF_OK) goto out; @@ -3066,7 +2799,7 @@ fetch_key(KMF_HANDLE_T handle, char *path, out: if (rv != KMF_OK) { if (rkey != NULL) { - KMF_FreeRawSymKey(rkey); + kmf_free_raw_sym_key(rkey); } if (pkey != NULL) EVP_PKEY_free(pkey); @@ -3082,23 +2815,40 @@ out: } KMF_RETURN -OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, - KMF_KEY_HANDLE *key, uint32_t *numkeys) +OpenSSL_FindKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; char *fullpath = NULL; uint32_t maxkeys; + KMF_KEY_HANDLE *key; + uint32_t *numkeys; + KMF_KEY_CLASS keyclass; + KMF_RAW_KEY_DATA *rawkey; + char *dirpath; + char *keyfile; + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); + + numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (numkeys == NULL) + return (KMF_ERR_BAD_PARAMETER); - if (handle == NULL || params == NULL || numkeys == NULL) + rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, + (void *)&keyclass, NULL); + if (rv != KMF_OK) return (KMF_ERR_BAD_PARAMETER); - if (params->keyclass != KMF_ASYM_PUB && - params->keyclass != KMF_ASYM_PRI && - params->keyclass != KMF_SYMMETRIC) + if (keyclass != KMF_ASYM_PUB && + keyclass != KMF_ASYM_PRI && + keyclass != KMF_SYMMETRIC) return (KMF_ERR_BAD_KEY_CLASS); - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.keyfile); + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); + + fullpath = get_fullpath(dirpath, keyfile); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -3106,9 +2856,17 @@ OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, maxkeys = *numkeys; if (maxkeys == 0) maxkeys = 0xFFFFFFFF; - *numkeys = 0; + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + /* it is okay to have "keys" contains NULL */ + + /* + * The caller may want a list of the raw key data as well. + * Useful for importing keys from a file into other keystores. + */ + rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); + if (isdir(fullpath)) { DIR *dirp; struct dirent *dp; @@ -3128,11 +2886,14 @@ OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, (char *)&dp->d_name); rv = fetch_key(handle, fname, - params->keyclass, - key ? &key[n] : NULL); + keyclass, key ? &key[n] : NULL); - if (rv == KMF_OK) + if (rv == KMF_OK) { + if (key != NULL && rawkey != NULL) + rv = convertToRawKey( + key[n].keyp, &rawkey[n]); n++; + } if (rv != KMF_OK || key == NULL) free(fname); @@ -3142,12 +2903,16 @@ OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, free(fullpath); (*numkeys) = n; } else { - rv = fetch_key(handle, fullpath, params->keyclass, key); + rv = fetch_key(handle, fullpath, keyclass, key); if (rv == KMF_OK) (*numkeys) = 1; if (rv != KMF_OK || key == NULL) free(fullpath); + + if (rv == KMF_OK && key != NULL && rawkey != NULL) { + rv = convertToRawKey(key->keyp, rawkey); + } } if (rv == KMF_OK && (*numkeys) == 0) @@ -3236,8 +3001,7 @@ write_pkcs12(KMF_HANDLE *kmfh, X509 *ca = NULL; uchar_t *p = (uchar_t *)c->certificate.Data; - ca = d2i_X509(NULL, &p, - c->certificate.Length); + ca = d2i_X509(NULL, &p, c->certificate.Length); if (ca == NULL) { HANDLE_PK12_ERROR } @@ -3466,6 +3230,12 @@ ImportRawDSAKey(KMF_RAW_DSA_KEY *key) dsa->priv_key)) == NULL) return (NULL); + if (key->pubvalue.val != NULL) { + if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val, + key->pubvalue.len, dsa->pub_key)) == NULL) + return (NULL); + } + if ((newkey = EVP_PKEY_new()) == NULL) return (NULL); @@ -3541,45 +3311,49 @@ cleanup: return (rv); } + KMF_RETURN -OpenSSL_ExportP12(KMF_HANDLE_T handle, - KMF_EXPORTP12_PARAMS *params, - int numcerts, KMF_X509_DER_CERT *certlist, - int numkeys, KMF_KEY_HANDLE *keylist, - char *filename) +openssl_build_pk12(KMF_HANDLE_T handle, int numcerts, + KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist, + KMF_CREDENTIAL *p12cred, char *filename) +{ + KMF_RETURN rv; + + if (certlist == NULL && keylist == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = ExportPK12FromRawData(handle, p12cred, numcerts, certlist, + numkeys, keylist, filename); + + return (rv); +} + + +KMF_RETURN +OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - KMF_FINDCERT_PARAMS fcargs; BIO *bio = NULL; X509 *xcert = NULL; char *fullpath = NULL; EVP_PKEY *pkey = NULL; + char *dirpath = NULL; + char *certfile = NULL; + char *keyfile = NULL; + char *filename = NULL; + KMF_CREDENTIAL *p12cred = NULL; - /* - * First, find the certificate. - */ - if (params == NULL) + if (handle == NULL) return (KMF_ERR_BAD_PARAMETER); /* - * If the caller already sent the raw keys and certs, - * shortcut the search and just export that - * data. - * - * One *may* export a key OR a cert by itself. + * First, find the certificate. */ - if (certlist != NULL || keylist != NULL) { - rv = ExportPK12FromRawData(handle, - ¶ms->p12cred, numcerts, certlist, - numkeys, keylist, filename); - return (rv); - } - - if (params->sslparms.certfile != NULL) { - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.certfile); - + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); + if (certfile != NULL) { + fullpath = get_fullpath(dirpath, certfile); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -3588,29 +3362,19 @@ OpenSSL_ExportP12(KMF_HANDLE_T handle, return (KMF_ERR_AMBIGUOUS_PATHNAME); } - (void *)memset(&fcargs, 0, sizeof (fcargs)); - fcargs.kstype = params->kstype; - fcargs.certLabel = params->certLabel; - fcargs.issuer = params->issuer; - fcargs.subject = params->subject; - fcargs.serial = params->serial; - fcargs.idstr = params->idstr; - fcargs.sslparms.dirpath = NULL; - fcargs.sslparms.certfile = fullpath; - fcargs.sslparms.format = params->sslparms.format; - - rv = load_X509cert(kmfh, &fcargs, fullpath, &xcert); + rv = load_X509cert(kmfh, NULL, NULL, NULL, fullpath, &xcert); if (rv != KMF_OK) goto end; + + free(fullpath); } /* * Now find the private key. */ - if (params->sslparms.keyfile != NULL) { - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.keyfile); - + keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); + if (keyfile != NULL) { + fullpath = get_fullpath(dirpath, keyfile); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -3629,6 +3393,13 @@ OpenSSL_ExportP12(KMF_HANDLE_T handle, /* * Open the output file. */ + filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, + numattr); + if (filename == NULL) { + rv = KMF_ERR_BAD_PARAMETER; + goto end; + } + if ((bio = BIO_new_file(filename, "wb")) == NULL) { SET_ERROR(kmfh, ERR_get_error()); rv = KMF_ERR_OPEN_FILE; @@ -3636,8 +3407,13 @@ OpenSSL_ExportP12(KMF_HANDLE_T handle, } /* Stick the key and the cert into a PKCS#12 file */ - rv = write_pkcs12(kmfh, bio, ¶ms->p12cred, - pkey, xcert); + p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); + if (p12cred == NULL) { + rv = KMF_ERR_BAD_PARAMETER; + goto end; + } + + rv = write_pkcs12(kmfh, bio, p12cred, pkey, xcert); end: if (fullpath) @@ -3652,6 +3428,7 @@ end: return (rv); } + #define MAX_CHAIN_LENGTH 100 /* * Helper function to extract keys and certificates from @@ -3660,7 +3437,8 @@ end: * However, the file may be just a list of X509 certs with no keys. */ static KMF_RETURN -extract_objects(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, +extract_pem(KMF_HANDLE *kmfh, + char *issuer, char *subject, KMF_BIGINT *serial, char *filename, CK_UTF8CHAR *pin, CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs, int *numcerts) @@ -3690,10 +3468,11 @@ extract_objects(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, return (KMF_ERR_ENCODING); } + for (i = 0; i < sk_X509_INFO_num(x509_info_stack) && i < MAX_CHAIN_LENGTH; i++) { - /*LINTED*/ + /* LINTED */ cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i); ncerts++; } @@ -3736,12 +3515,10 @@ extract_objects(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, boolean_t match = FALSE; info = cert_infos[ncerts - 1 - i]; - if (params != NULL) { - rv = check_cert(info->x509, params, &match); - if (rv != KMF_OK || match != TRUE) { - rv = KMF_OK; - continue; - } + rv = check_cert(info->x509, issuer, subject, serial, &match); + if (rv != KMF_OK || match != TRUE) { + rv = KMF_OK; + continue; } rv = ssl_cert2KMFDATA(kmfh, info->x509, @@ -3880,7 +3657,7 @@ exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) goto cleanup; cleanup: if (rv != KMF_OK) - KMF_FreeRawKey(key); + kmf_free_raw_key(key); else key->keytype = KMF_RSA; @@ -3914,7 +3691,7 @@ exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) cleanup: if (rv != KMF_OK) - KMF_FreeRawKey(key); + kmf_free_raw_key(key); else key->keytype = KMF_DSA; @@ -3983,6 +3760,33 @@ add_key_to_list(KMF_RAW_KEY_DATA **keylist, return (KMF_OK); } +static KMF_RETURN +convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key) +{ + KMF_RETURN rv = KMF_OK; + + if (pkey == NULL || key == NULL) + return (KMF_ERR_BAD_PARAMETER); + /* Convert SSL key to raw key */ + switch (pkey->type) { + case EVP_PKEY_RSA: + rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey), + key); + if (rv != KMF_OK) + return (rv); + break; + case EVP_PKEY_DSA: + rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey), + key); + if (rv != KMF_OK) + return (rv); + break; + default: + return (KMF_ERR_BAD_PARAMETER); + } + + return (rv); +} static KMF_RETURN convertPK12Objects( @@ -3996,27 +3800,10 @@ convertPK12Objects( int i; if (sslkey != NULL) { - /* Convert SSL key to raw key */ - switch (sslkey->type) { - case EVP_PKEY_RSA: - rv = exportRawRSAKey(EVP_PKEY_get1_RSA(sslkey), - &key); - if (rv != KMF_OK) - return (rv); - - break; - case EVP_PKEY_DSA: - rv = exportRawDSAKey(EVP_PKEY_get1_DSA(sslkey), - &key); - if (rv != KMF_OK) - return (rv); - - break; - default: - return (KMF_ERR_BAD_PARAMETER); - } + rv = convertToRawKey(sslkey, &key); + if (rv == KMF_OK) + rv = add_key_to_list(keylist, &key, nkeys); - rv = add_key_to_list(keylist, &key, nkeys); if (rv != KMF_OK) return (rv); } @@ -4049,160 +3836,79 @@ convertPK12Objects( } KMF_RETURN -openssl_read_pkcs12(KMF_HANDLE *kmfh, +openssl_import_objects(KMF_HANDLE *kmfh, char *filename, KMF_CREDENTIAL *cred, KMF_DATA **certlist, int *ncerts, KMF_RAW_KEY_DATA **keylist, int *nkeys) { KMF_RETURN rv = KMF_OK; - BIO *bio = NULL; EVP_PKEY *privkey = NULL; + KMF_ENCODE_FORMAT format; + BIO *bio = NULL; X509 *cert = NULL; STACK_OF(X509) *cacerts = NULL; - bio = BIO_new_file(filename, "rb"); - if (bio == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_OPEN_FILE; - goto end; - } - - *certlist = NULL; - *keylist = NULL; - *ncerts = 0; - *nkeys = 0; - - rv = extract_pkcs12(bio, (uchar_t *)cred->cred, - (uint32_t)cred->credlen, &privkey, &cert, &cacerts); - - if (rv == KMF_OK) - /* Convert keys and certs to exportable format */ - rv = convertPK12Objects(kmfh, privkey, cert, cacerts, - keylist, nkeys, certlist, ncerts); - -end: - if (bio != NULL) - (void) BIO_free(bio); - - if (privkey) - EVP_PKEY_free(privkey); - - if (cert) - X509_free(cert); - - if (cacerts) - sk_X509_free(cacerts); - - return (rv); -} - -KMF_RETURN -openssl_import_keypair(KMF_HANDLE *kmfh, - char *filename, KMF_CREDENTIAL *cred, - KMF_DATA **certlist, int *ncerts, - KMF_RAW_KEY_DATA **keylist, int *nkeys) -{ - KMF_RETURN rv = KMF_OK; - EVP_PKEY *privkey = NULL; - KMF_ENCODE_FORMAT format; - /* * auto-detect the file format, regardless of what * the 'format' parameters in the params say. */ - rv = KMF_GetFileFormat(filename, &format); + rv = kmf_get_file_format(filename, &format); if (rv != KMF_OK) { - if (rv == KMF_ERR_OPEN_FILE) - rv = KMF_ERR_CERT_NOT_FOUND; return (rv); } - /* This function only works on PEM files */ + /* This function only works for PEM or PKCS#12 files */ if (format != KMF_FORMAT_PEM && - format != KMF_FORMAT_PEM_KEYPAIR) + format != KMF_FORMAT_PEM_KEYPAIR && + format != KMF_FORMAT_PKCS12) return (KMF_ERR_ENCODING); *certlist = NULL; *keylist = NULL; *ncerts = 0; *nkeys = 0; - rv = extract_objects(kmfh, NULL, filename, - (uchar_t *)cred->cred, (uint32_t)cred->credlen, - &privkey, certlist, ncerts); - - /* Reached end of import file? */ - if (rv == KMF_OK) - /* Convert keys and certs to exportable format */ - rv = convertPK12Objects(kmfh, privkey, NULL, NULL, - keylist, nkeys, NULL, NULL); - -end: - if (privkey) - EVP_PKEY_free(privkey); - - return (rv); -} - -KMF_RETURN -OpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, - KMF_RAW_KEY_DATA *key) -{ - KMF_RETURN rv = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - char *fullpath; - EVP_PKEY *pkey = NULL; - BIO *bio = NULL; - if (key != NULL) { - if (key->keytype == KMF_RSA) { - pkey = ImportRawRSAKey(&key->rawdata.rsa); - } else if (key->keytype == KMF_DSA) { - pkey = ImportRawDSAKey(&key->rawdata.dsa); - } else { - rv = KMF_ERR_BAD_PARAMETER; + if (format == KMF_FORMAT_PKCS12) { + bio = BIO_new_file(filename, "rb"); + if (bio == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_OPEN_FILE; + goto end; } - } else { - rv = KMF_ERR_BAD_PARAMETER; - } - if (rv != KMF_OK || pkey == NULL) - return (rv); - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.keyfile); + rv = extract_pkcs12(bio, (uchar_t *)cred->cred, + (uint32_t)cred->credlen, &privkey, &cert, &cacerts); - if (fullpath == NULL) - return (KMF_ERR_BAD_PARAMETER); + if (rv == KMF_OK) + /* Convert keys and certs to exportable format */ + rv = convertPK12Objects(kmfh, privkey, cert, cacerts, + keylist, nkeys, certlist, ncerts); - /* If the requested file exists, return an error */ - if (access(fullpath, F_OK) == 0) { - free(fullpath); - return (KMF_ERR_DUPLICATE_KEYFILE); - } + } else { + rv = extract_pem(kmfh, NULL, NULL, NULL, filename, + (uchar_t *)cred->cred, (uint32_t)cred->credlen, + &privkey, certlist, ncerts); - bio = BIO_new_file(fullpath, "wb"); - if (bio == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_OPEN_FILE; - goto cleanup; + /* Reached end of import file? */ + if (rv == KMF_OK) + /* Convert keys and certs to exportable format */ + rv = convertPK12Objects(kmfh, privkey, NULL, NULL, + keylist, nkeys, NULL, NULL); } - rv = ssl_write_private_key(kmfh, params->sslparms.format, - bio, ¶ms->cred, pkey); +end: + if (privkey) + EVP_PKEY_free(privkey); -cleanup: - if (fullpath) - free(fullpath); + if (bio != NULL) + (void) BIO_free(bio); - if (pkey) - EVP_PKEY_free(pkey); + if (cert) + X509_free(cert); - if (bio) - (void) BIO_free(bio); + if (cacerts) + sk_X509_free(cacerts); - /* Protect the file by making it read-only */ - if (rv == KMF_OK) { - (void) chmod(fullpath, 0400); - } return (rv); } @@ -4322,8 +4028,8 @@ out: } KMF_RETURN -OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, - KMF_KEY_HANDLE *symkey) +OpenSSL_CreateSymKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -4333,21 +4039,46 @@ OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, unsigned char *des3key = NULL; unsigned char *random = NULL; int fd = -1; + KMF_KEY_HANDLE *symkey; + KMF_KEY_ALG keytype; + uint32_t keylen; + uint32_t keylen_size = sizeof (keylen); + char *dirpath; + char *keyfile; if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); - if (params == NULL || params->sslparms.keyfile == NULL) { + symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (symkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + + keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); + if (keyfile == NULL) return (KMF_ERR_BAD_PARAMETER); - } - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.keyfile); + ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); + if (ret != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, + &keylen, &keylen_size); + if (ret == KMF_ERR_ATTR_NOT_FOUND && + (keytype == KMF_DES || keytype == KMF_DES3)) + /* keylength is not required for DES and 3DES */ + ret = KMF_OK; + if (ret != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + fullpath = get_fullpath(dirpath, keyfile); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); /* If the requested file exists, return an error */ - if (access(fullpath, F_OK) == 0) { + if (test_for_file(fullpath, 0400) == 1) { free(fullpath); return (KMF_ERR_DUPLICATE_KEYFILE); } @@ -4365,7 +4096,7 @@ OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, } (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); - if (params->keytype == KMF_DES) { + if (keytype == KMF_DES) { if ((ret = create_deskey(&deskey)) != KMF_OK) { goto out; } @@ -4374,7 +4105,7 @@ OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, symkey->keyalg = KMF_DES; - } else if (params->keytype == KMF_DES3) { + } else if (keytype == KMF_DES3) { if ((ret = create_des3key(&des3key)) != KMF_OK) { goto out; } @@ -4382,25 +4113,25 @@ OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, rkey->keydata.len = DES3_KEY_SIZE; symkey->keyalg = KMF_DES3; - } else if (params->keytype == KMF_AES || params->keytype == KMF_RC4 || - params->keytype == KMF_GENERIC_SECRET) { + } else if (keytype == KMF_AES || keytype == KMF_RC4 || + keytype == KMF_GENERIC_SECRET) { int bytes; - if (params->keylength % 8 != 0) { + if (keylen % 8 != 0) { ret = KMF_ERR_BAD_KEY_SIZE; goto out; } - if (params->keytype == KMF_AES) { - if (params->keylength != 128 && - params->keylength != 192 && - params->keylength != 256) { + if (keytype == KMF_AES) { + if (keylen != 128 && + keylen != 192 && + keylen != 256) { ret = KMF_ERR_BAD_KEY_SIZE; goto out; } } - bytes = params->keylength/8; + bytes = keylen/8; random = malloc(bytes); if (random == NULL) { ret = KMF_ERR_MEMORY; @@ -4413,7 +4144,7 @@ OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, rkey->keydata.val = (uchar_t *)random; rkey->keydata.len = bytes; - symkey->keyalg = params->keytype; + symkey->keyalg = keytype; } else { ret = KMF_ERR_BAD_KEY_TYPE; @@ -4436,7 +4167,7 @@ out: free(fullpath); } if (ret != KMF_OK) { - KMF_FreeRawSymKey(rkey); + kmf_free_raw_sym_key(rkey); symkey->keyp = NULL; symkey->keyalg = KMF_KEYALG_NONE; } @@ -4444,159 +4175,6 @@ out: return (ret); } - -KMF_RETURN -OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, KMF_VERIFYCRL_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - BIO *bcrl = NULL; - X509_CRL *xcrl = NULL; - X509 *xcert = NULL; - EVP_PKEY *pkey; - int sslret; - KMF_ENCODE_FORMAT crl_format; - unsigned char *p; - long len; - - if (params->crl_name == NULL || params->tacert == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - ret = KMF_GetFileFormat(params->crl_name, &crl_format); - if (ret != KMF_OK) - return (ret); - - bcrl = BIO_new_file(params->crl_name, "rb"); - if (bcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto cleanup; - } - - if (crl_format == KMF_FORMAT_ASN1) { - xcrl = d2i_X509_CRL_bio(bcrl, NULL); - } else if (crl_format == KMF_FORMAT_PEM) { - xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); - } else { - ret = KMF_ERR_BAD_PARAMETER; - goto cleanup; - } - - if (xcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CRLFILE; - goto cleanup; - } - - p = params->tacert->Data; - len = params->tacert->Length; - xcert = d2i_X509(NULL, (const uchar_t **)&p, len); - - if (xcert == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CERTFILE; - goto cleanup; - } - - /* Get issuer certificate public key */ - pkey = X509_get_pubkey(xcert); - if (!pkey) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CERT_FORMAT; - goto cleanup; - } - - /* Verify CRL signature */ - sslret = X509_CRL_verify(xcrl, pkey); - EVP_PKEY_free(pkey); - if (sslret > 0) { - ret = KMF_OK; - } else { - SET_ERROR(kmfh, sslret); - ret = KMF_ERR_BAD_CRLFILE; - } - -cleanup: - if (bcrl != NULL) - (void) BIO_free(bcrl); - - if (xcrl != NULL) - X509_CRL_free(xcrl); - - if (xcert != NULL) - X509_free(xcert); - - return (ret); - -} - -KMF_RETURN -OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, - KMF_CHECKCRLDATE_PARAMS *params) -{ - - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - KMF_ENCODE_FORMAT crl_format; - BIO *bcrl = NULL; - X509_CRL *xcrl = NULL; - int i; - - if (params == NULL || params->crl_name == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - ret = KMF_IsCRLFile(handle, params->crl_name, &crl_format); - if (ret != KMF_OK) - return (ret); - - bcrl = BIO_new_file(params->crl_name, "rb"); - if (bcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto cleanup; - } - - if (crl_format == KMF_FORMAT_ASN1) { - xcrl = d2i_X509_CRL_bio(bcrl, NULL); - } else if (crl_format == KMF_FORMAT_PEM) { - xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); - } - - if (xcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CRLFILE; - goto cleanup; - } - - i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); - if (i >= 0) { - ret = KMF_ERR_VALIDITY_PERIOD; - goto cleanup; - } - - if (X509_CRL_get_nextUpdate(xcrl)) { - i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); - - if (i <= 0) { - ret = KMF_ERR_VALIDITY_PERIOD; - goto cleanup; - } - } - - ret = KMF_OK; - -cleanup: - if (bcrl != NULL) - (void) BIO_free(bcrl); - - if (xcrl != NULL) - X509_CRL_free(xcrl); - - return (ret); -} - /* * Check a file to see if it is a CRL file with PEM or DER format. * If success, return its format in the "pformat" argument. @@ -4669,7 +4247,7 @@ OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, return (KMF_ERR_BAD_PARAMETER); } - ret = KMF_GetFileFormat(filename, pformat); + ret = kmf_get_file_format(filename, pformat); if (ret != KMF_OK) return (ret); @@ -4733,7 +4311,7 @@ OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, (void) memcpy(rkey->keydata.val, rawkey->keydata.val, rkey->keydata.len); } else { - rv = KMF_ReadInputFile(handle, symkey->keylabel, &keyvalue); + rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue); if (rv != KMF_OK) return (rv); rkey->keydata.len = keyvalue.Length; @@ -4815,7 +4393,7 @@ OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle, } pkey = X509_get_pubkey(xcert); - if (!pkey) { + if (pkey == NULL) { SET_ERROR(kmfh, ERR_get_error()); ret = KMF_ERR_BAD_CERT_FORMAT; goto cleanup; @@ -4944,3 +4522,764 @@ cleanup: return (ret); } + +/* + * substitute for the unsafe access(2) function. + * If the file in question already exists, return 1. + * else 0. If an error occurs during testing (other + * than EEXIST), return -1. + */ +static int +test_for_file(char *filename, mode_t mode) +{ + int fd; + + /* + * Try to create the file with the EXCL flag. + * The call should fail if the file exists. + */ + fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode); + if (fd == -1 && errno == EEXIST) + return (1); + else if (fd == -1) /* some other error */ + return (-1); + + /* The file did NOT exist. Delete the testcase. */ + (void) close(fd); + (void) unlink(filename); + return (0); +} + +KMF_RETURN +OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL; + KMF_RAW_KEY_DATA *rawkey; + EVP_PKEY *pkey = NULL; + KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM; + KMF_CREDENTIAL cred = {NULL, 0}; + BIO *out = NULL; + int keys = 0; + char *fullpath = NULL; + char *keyfile = NULL; + char *dirpath = NULL; + + pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); + if (pubkey != NULL) + keys++; + + prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); + if (prikey != NULL) + keys++; + + rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); + if (rawkey != NULL) + keys++; + + /* + * Exactly 1 type of key must be passed to this function. + */ + if (keys != 1) + return (KMF_ERR_BAD_PARAMETER); + + keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, + numattr); + if (keyfile == NULL) + return (KMF_ERR_BAD_PARAMETER); + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + + fullpath = get_fullpath(dirpath, keyfile); + + /* Once we have the full path, we don't need the pieces */ + if (fullpath == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* If the requested file exists, return an error */ + if (test_for_file(fullpath, 0400) == 1) { + free(fullpath); + return (KMF_ERR_DUPLICATE_KEYFILE); + } + + rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, + &format, NULL); + if (rv != KMF_OK) + /* format is optional. */ + rv = KMF_OK; + + /* CRED is not required for OpenSSL files */ + (void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + &cred, NULL); + + /* Store the private key to the keyfile */ + out = BIO_new_file(fullpath, "wb"); + if (out == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_OPEN_FILE; + goto end; + } + + if (prikey != NULL && prikey->keyp != NULL) { + if (prikey->keyalg == KMF_RSA || + prikey->keyalg == KMF_DSA) { + pkey = (EVP_PKEY *)prikey->keyp; + + rv = ssl_write_key(kmfh, format, + out, &cred, pkey, TRUE); + + if (rv == KMF_OK && prikey->keylabel == NULL) { + prikey->keylabel = strdup(fullpath); + if (prikey->keylabel == NULL) + rv = KMF_ERR_MEMORY; + } + } + } else if (pubkey != NULL && pubkey->keyp != NULL) { + if (pubkey->keyalg == KMF_RSA || + pubkey->keyalg == KMF_DSA) { + pkey = (EVP_PKEY *)pubkey->keyp; + + rv = ssl_write_key(kmfh, format, + out, &cred, pkey, FALSE); + + if (rv == KMF_OK && pubkey->keylabel == NULL) { + pubkey->keylabel = strdup(fullpath); + if (pubkey->keylabel == NULL) + rv = KMF_ERR_MEMORY; + } + } + } else if (rawkey != NULL) { + /* RAW keys are always private */ + if (rawkey->keytype == KMF_RSA) { + pkey = ImportRawRSAKey(&rawkey->rawdata.rsa); + } else if (rawkey->keytype == KMF_DSA) { + pkey = ImportRawDSAKey(&rawkey->rawdata.dsa); + } else { + rv = KMF_ERR_BAD_PARAMETER; + } + rv = ssl_write_key(kmfh, format, out, &cred, pkey, TRUE); + } + +end: + + if (out) + (void) BIO_free(out); + + if (rv == KMF_OK) + (void) chmod(fullpath, 0400); + + free(fullpath); + return (rv); +} + +KMF_RETURN +OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + X509_CRL *xcrl = NULL; + X509 *xcert = NULL; + EVP_PKEY *pkey; + KMF_ENCODE_FORMAT format; + BIO *in = NULL, *out = NULL; + int openssl_ret = 0; + KMF_ENCODE_FORMAT outformat; + boolean_t crlcheck = FALSE; + char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile; + + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + /* CRL check is optional */ + (void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr, + &crlcheck, NULL); + + certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); + if (crlcheck == B_TRUE && certfile == NULL) { + return (KMF_ERR_BAD_CERTFILE); + } + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr); + outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr); + + crlfile = get_fullpath(dirpath, incrl); + + if (crlfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + outcrlfile = get_fullpath(dirpath, outcrl); + if (outcrlfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + if (isdir(outcrlfile)) { + free(outcrlfile); + return (KMF_ERR_BAD_CRLFILE); + } + + ret = kmf_is_crl_file(handle, crlfile, &format); + if (ret != KMF_OK) { + free(outcrlfile); + return (ret); + } + + in = BIO_new_file(crlfile, "rb"); + if (in == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (format == KMF_FORMAT_ASN1) { + xcrl = d2i_X509_CRL_bio(in, NULL); + } else if (format == KMF_FORMAT_PEM) { + xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + } + + if (xcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CRLFILE; + goto end; + } + + /* If bypasscheck is specified, no need to verify. */ + if (crlcheck == B_FALSE) + goto output; + + ret = kmf_is_cert_file(handle, certfile, &format); + if (ret != KMF_OK) + goto end; + + /* Read in the CA cert file and convert to X509 */ + if (BIO_read_filename(in, certfile) <= 0) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (format == KMF_FORMAT_ASN1) { + xcert = d2i_X509_bio(in, NULL); + } else if (format == KMF_FORMAT_PEM) { + xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); + } else { + ret = KMF_ERR_BAD_CERT_FORMAT; + goto end; + } + + if (xcert == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CERT_FORMAT; + goto end; + } + /* Now get the public key from the CA cert */ + pkey = X509_get_pubkey(xcert); + if (pkey == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CERTFILE; + goto end; + } + + /* Verify the CRL with the CA's public key */ + openssl_ret = X509_CRL_verify(xcrl, pkey); + EVP_PKEY_free(pkey); + if (openssl_ret > 0) { + ret = KMF_OK; /* verify succeed */ + } else { + SET_ERROR(kmfh, openssl_ret); + ret = KMF_ERR_BAD_CRLFILE; + } + +output: + ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, + &outformat, NULL); + if (ret != KMF_OK) { + ret = KMF_OK; + outformat = KMF_FORMAT_PEM; + } + + out = BIO_new_file(outcrlfile, "wb"); + if (out == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (outformat == KMF_FORMAT_ASN1) { + openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); + } else if (outformat == KMF_FORMAT_PEM) { + openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); + } else { + ret = KMF_ERR_BAD_PARAMETER; + goto end; + } + + if (openssl_ret <= 0) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_WRITE_FILE; + } else { + ret = KMF_OK; + } + +end: + if (xcrl != NULL) + X509_CRL_free(xcrl); + + if (xcert != NULL) + X509_free(xcert); + + if (in != NULL) + (void) BIO_free(in); + + if (out != NULL) + (void) BIO_free(out); + + if (outcrlfile != NULL) + free(outcrlfile); + + return (ret); +} + +KMF_RETURN +OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + X509_CRL *x = NULL; + KMF_ENCODE_FORMAT format; + char *crlfile = NULL; + BIO *in = NULL; + BIO *mem = NULL; + long len; + char *memptr; + char *data = NULL; + char **crldata; + char *crlfilename, *dirpath; + + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, + attrlist, numattr); + if (crlfilename == NULL) + return (KMF_ERR_BAD_CRLFILE); + + crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR, + attrlist, numattr); + + if (crldata == NULL) + return (KMF_ERR_BAD_PARAMETER); + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + + crlfile = get_fullpath(dirpath, crlfilename); + + if (crlfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + if (isdir(crlfile)) { + free(crlfile); + return (KMF_ERR_BAD_CRLFILE); + } + + ret = kmf_is_crl_file(handle, crlfile, &format); + if (ret != KMF_OK) { + free(crlfile); + return (ret); + } + + if (bio_err == NULL) + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + + in = BIO_new_file(crlfile, "rb"); + if (in == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (format == KMF_FORMAT_ASN1) { + x = d2i_X509_CRL_bio(in, NULL); + } else if (format == KMF_FORMAT_PEM) { + x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + } + + if (x == NULL) { /* should not happen */ + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + mem = BIO_new(BIO_s_mem()); + if (mem == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_MEMORY; + goto end; + } + + (void) X509_CRL_print(mem, x); + len = BIO_get_mem_data(mem, &memptr); + if (len <= 0) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_MEMORY; + goto end; + } + + data = malloc(len + 1); + if (data == NULL) { + ret = KMF_ERR_MEMORY; + goto end; + } + + (void) memcpy(data, memptr, len); + data[len] = '\0'; + *crldata = data; + +end: + if (x != NULL) + X509_CRL_free(x); + + if (crlfile != NULL) + free(crlfile); + + if (in != NULL) + (void) BIO_free(in); + + if (mem != NULL) + (void) BIO_free(mem); + + return (ret); +} + +KMF_RETURN +OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_ENCODE_FORMAT format; + char *crlfile = NULL; + BIO *in = NULL; + char *crlfilename, *dirpath; + + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, + attrlist, numattr); + + if (crlfilename == NULL) + return (KMF_ERR_BAD_CRLFILE); + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + + crlfile = get_fullpath(dirpath, crlfilename); + + if (crlfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + if (isdir(crlfile)) { + ret = KMF_ERR_BAD_CRLFILE; + goto end; + } + + ret = kmf_is_crl_file(handle, crlfile, &format); + if (ret != KMF_OK) + goto end; + + if (unlink(crlfile) != 0) { + SET_SYS_ERROR(kmfh, errno); + ret = KMF_ERR_INTERNAL; + goto end; + } + +end: + if (in != NULL) + (void) BIO_free(in); + if (crlfile != NULL) + free(crlfile); + + return (ret); +} + +KMF_RETURN +OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_ENCODE_FORMAT format; + BIO *in = NULL; + X509 *xcert = NULL; + X509_CRL *xcrl = NULL; + STACK_OF(X509_REVOKED) *revoke_stack = NULL; + X509_REVOKED *revoke; + int i; + char *crlfilename, *crlfile, *dirpath, *certfile; + + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, + attrlist, numattr); + + if (crlfilename == NULL) + return (KMF_ERR_BAD_CRLFILE); + + certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); + if (certfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + + crlfile = get_fullpath(dirpath, crlfilename); + + if (crlfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + if (isdir(crlfile)) { + ret = KMF_ERR_BAD_CRLFILE; + goto end; + } + + ret = kmf_is_crl_file(handle, crlfile, &format); + if (ret != KMF_OK) + goto end; + + /* Read the CRL file and load it into a X509_CRL structure */ + in = BIO_new_file(crlfilename, "rb"); + if (in == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (format == KMF_FORMAT_ASN1) { + xcrl = d2i_X509_CRL_bio(in, NULL); + } else if (format == KMF_FORMAT_PEM) { + xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + } + + if (xcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CRLFILE; + goto end; + } + (void) BIO_free(in); + + /* Read the Certificate file and load it into a X509 structure */ + ret = kmf_is_cert_file(handle, certfile, &format); + if (ret != KMF_OK) + goto end; + + in = BIO_new_file(certfile, "rb"); + if (in == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (format == KMF_FORMAT_ASN1) { + xcert = d2i_X509_bio(in, NULL); + } else if (format == KMF_FORMAT_PEM) { + xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); + } + + if (xcert == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CERTFILE; + goto end; + } + + /* Check if the certificate and the CRL have same issuer */ + if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { + ret = KMF_ERR_ISSUER; + goto end; + } + + /* Check to see if the certificate serial number is revoked */ + revoke_stack = X509_CRL_get_REVOKED(xcrl); + if (sk_X509_REVOKED_num(revoke_stack) <= 0) { + /* No revoked certificates in the CRL file */ + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_EMPTY_CRL; + goto end; + } + + for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { + /*LINTED*/ + revoke = sk_X509_REVOKED_value(revoke_stack, i); + if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, + revoke->serialNumber) == 0) { + break; + } + } + + if (i < sk_X509_REVOKED_num(revoke_stack)) { + ret = KMF_OK; + } else { + ret = KMF_ERR_NOT_REVOKED; + } + +end: + if (in != NULL) + (void) BIO_free(in); + if (xcrl != NULL) + X509_CRL_free(xcrl); + if (xcert != NULL) + X509_free(xcert); + + return (ret); +} + +KMF_RETURN +OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + BIO *bcrl = NULL; + X509_CRL *xcrl = NULL; + X509 *xcert = NULL; + EVP_PKEY *pkey; + int sslret; + KMF_ENCODE_FORMAT crl_format; + unsigned char *p; + long len; + + if (handle == NULL || crlname == NULL || tacert == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + ret = kmf_get_file_format(crlname, &crl_format); + if (ret != KMF_OK) + return (ret); + + bcrl = BIO_new_file(crlname, "rb"); + if (bcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto cleanup; + } + + if (crl_format == KMF_FORMAT_ASN1) { + xcrl = d2i_X509_CRL_bio(bcrl, NULL); + } else if (crl_format == KMF_FORMAT_PEM) { + xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); + } else { + ret = KMF_ERR_BAD_PARAMETER; + goto cleanup; + } + + if (xcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CRLFILE; + goto cleanup; + } + + p = tacert->Data; + len = tacert->Length; + xcert = d2i_X509(NULL, (const uchar_t **)&p, len); + + if (xcert == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CERTFILE; + goto cleanup; + } + + /* Get issuer certificate public key */ + pkey = X509_get_pubkey(xcert); + if (pkey == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CERT_FORMAT; + goto cleanup; + } + + /* Verify CRL signature */ + sslret = X509_CRL_verify(xcrl, pkey); + EVP_PKEY_free(pkey); + if (sslret > 0) { + ret = KMF_OK; + } else { + SET_ERROR(kmfh, sslret); + ret = KMF_ERR_BAD_CRLFILE; + } + +cleanup: + if (bcrl != NULL) + (void) BIO_free(bcrl); + + if (xcrl != NULL) + X509_CRL_free(xcrl); + + if (xcert != NULL) + X509_free(xcert); + + return (ret); + +} + +KMF_RETURN +OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_ENCODE_FORMAT crl_format; + BIO *bcrl = NULL; + X509_CRL *xcrl = NULL; + int i; + + if (handle == NULL || crlname == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + ret = kmf_is_crl_file(handle, crlname, &crl_format); + if (ret != KMF_OK) + return (ret); + + bcrl = BIO_new_file(crlname, "rb"); + if (bcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto cleanup; + } + + if (crl_format == KMF_FORMAT_ASN1) { + xcrl = d2i_X509_CRL_bio(bcrl, NULL); + } else if (crl_format == KMF_FORMAT_PEM) { + xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); + } + + if (xcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CRLFILE; + goto cleanup; + } + + i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); + if (i >= 0) { + ret = KMF_ERR_VALIDITY_PERIOD; + goto cleanup; + } + + if (X509_CRL_get_nextUpdate(xcrl)) { + i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); + + if (i <= 0) { + ret = KMF_ERR_VALIDITY_PERIOD; + goto cleanup; + } + } + + ret = KMF_OK; + +cleanup: + if (bcrl != NULL) + (void) BIO_free(bcrl); + + if (xcrl != NULL) + X509_CRL_free(xcrl); + + return (ret); +} diff --git a/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com b/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com index fd46f0e5f8..2651b5d4de 100644 --- a/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com +++ b/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com @@ -29,7 +29,10 @@ LIBRARY= kmf_pkcs11.a VERS= .1 -OBJECTS= pkcs11_spi.o + +PKCS11_COBJECTS = pkcs11_spi.o +BIGNUM_COBJECTS = bignumimpl.o +OBJECTS = $(PKCS11_COBJECTS) $(BIGNUM_COBJECTS) include $(SRC)/lib/Makefile.lib @@ -38,11 +41,18 @@ KMFINC= -I../../../include -I../../../ber_der/inc PKCS11LIBS= -lkmf -lkmfberder -lmd -lpkcs11 -lcryptoutil -lc +BIGNUMDIR= $(SRC)/common/bignum + SRCDIR= ../common INCDIR= ../../include +SRCS = \ + $(PKCS11_COBJECTS:%.o=$(SRCDIR)/%.c) \ + $(BIGNUM_COBJECTS:%.o=$(BIGNUMDIR)/%.c) + + CFLAGS += $(CCVERBOSE) -CPPFLAGS += -D_REENTRANT $(KMFINC) -I$(INCDIR) -I/usr/include/libxml2 +CPPFLAGS += -D_REENTRANT $(KMFINC) -I$(INCDIR) -I/usr/include/libxml2 -I$(BIGNUMDIR) PICS= $(OBJECTS:%=pics/%) SONAME= $(PLUGIN) @@ -62,4 +72,8 @@ lint: lintcheck FRC: +pics/%.o: $(BIGNUMDIR)/%.c + $(COMPILE.c) -o $@ $(BIGNUM_CFG) $< + $(POST_PROCESS_O) + include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/mapfile-vers b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/mapfile-vers index ee3b6bcb92..0e120d0b9b 100644 --- a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/mapfile-vers +++ b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/mapfile-vers @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -28,23 +28,24 @@ SUNWprivate_1.1 { global: KMF_Plugin_Initialize; - KMFPK11_FindCert; - KMFPK11_FreeKMFCert; - KMFPK11_StoreCert; - KMFPK11_ImportCert; - KMFPK11_DeleteCert; - KMFPK11_CreateKeypair; - KMFPK11_FindKey; - KMFPK11_EncodePubKeyData; - KMFPK11_SignData; - KMFPK11_DeleteKey; - KMFPK11_GetErrorString; - KMFPK11_GetPrikeyByCert; - KMFPK11_DecryptData; - KMFPK11_StorePrivateKey; - KMFPK11_CreateSymKey; - KMFPK11_GetSymKeyValue; - KMFPK11_SetTokenPin; + KMFPK11_CreateKeypair; + KMFPK11_CreateSymKey; + KMFPK11_DecryptData; + KMFPK11_DeleteCert; + KMFPK11_DeleteKey; + KMFPK11_EncodePubKeyData; + KMFPK11_ExportPK12; + KMFPK11_FindCert; + KMFPK11_FindKey; + KMFPK11_FindPrikeyByCert; + KMFPK11_FreeKMFCert; + KMFPK11_GetErrorString; + KMFPK11_GetSymKeyValue; + KMFPK11_ImportCert; + KMFPK11_SetTokenPin; + KMFPK11_SignData; + KMFPK11_StoreCert; + KMFPK11_StoreKey; local: *; }; diff --git a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c index f000c5eadd..3d7cfae6d2 100644 --- a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c +++ b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c @@ -36,6 +36,7 @@ #include <algorithm.h> #include <fcntl.h> #include <sha1.h> +#include <bignum.h> #include <cryptoutil.h> #include <security/cryptoki.h> @@ -67,38 +68,36 @@ static KMF_RETURN keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **); static KMF_RETURN -create_generic_secret_key(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, - CK_OBJECT_HANDLE *); +create_generic_secret_key(KMF_HANDLE_T, + int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *); KMF_RETURN -KMFPK11_ConfigureKeystore(KMF_HANDLE_T, KMF_CONFIG_PARAMS *); +KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_FindCert(KMF_HANDLE_T, - KMF_FINDCERT_PARAMS *, - KMF_X509_DER_CERT *, - uint32_t *); +KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); void KMFPK11_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *kmf_cert); KMF_RETURN -KMFPK11_StoreCert(KMF_HANDLE_T, KMF_STORECERT_PARAMS *, KMF_DATA *); +KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_ImportCert(KMF_HANDLE_T, KMF_IMPORTCERT_PARAMS *); +KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_DeleteCert(KMF_HANDLE_T, KMF_DELETECERT_PARAMS *); +KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, - KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); +KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, - KMF_KEY_HANDLE *, boolean_t); +KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); + +KMF_RETURN +KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); @@ -111,35 +110,32 @@ KMF_RETURN KMFPK11_GetErrorString(KMF_HANDLE_T, char **); KMF_RETURN -KMFPK11_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, - KMF_KEY_HANDLE *, KMF_KEY_ALG); +KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, KMF_DATA *, KMF_DATA *); KMF_RETURN -KMFPK11_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, - KMF_KEY_HANDLE *, uint32_t *); +KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, - KMF_RAW_KEY_DATA *); - -KMF_RETURN -KMFPK11_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, - KMF_KEY_HANDLE *); +KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); KMF_RETURN -KMFPK11_SetTokenPin(KMF_HANDLE_T, KMF_SETPIN_PARAMS *, KMF_CREDENTIAL *); +KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN KMFPK11_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, KMF_DATA *, KMF_DATA *, KMF_DATA *); +KMF_RETURN +KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); + + static KMF_PLUGIN_FUNCLIST pk11token_plugin_table = { @@ -161,14 +157,14 @@ KMF_PLUGIN_FUNCLIST pk11token_plugin_table = NULL, /* FindCRL */ NULL, /* FindCertInCRL */ KMFPK11_GetErrorString, - KMFPK11_GetPrikeyByCert, + KMFPK11_FindPrikeyByCert, KMFPK11_DecryptData, - NULL, /* ExportP12 */ - KMFPK11_StorePrivateKey, + KMFPK11_ExportPK12, KMFPK11_CreateSymKey, KMFPK11_GetSymKeyValue, KMFPK11_SetTokenPin, KMFPK11_VerifyDataWithCert, + KMFPK11_StoreKey, NULL /* Finalize */ }; @@ -179,15 +175,23 @@ KMF_Plugin_Initialize() } KMF_RETURN -KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) +KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; + char *label; + boolean_t readonly = B_TRUE; - if (params == NULL || params->pkcs11config.label == NULL) + label = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr); + if (label == NULL) { return (KMF_ERR_BAD_PARAMETER); + } + + /* "readonly" is optional. Default is TRUE */ + (void) kmf_get_attr(KMF_READONLY_ATTR, attrlist, numattr, + (void *)&readonly, NULL); - rv = KMF_SelectToken(handle, params->pkcs11config.label, - params->pkcs11config.readonly); + rv = kmf_select_token(handle, label, readonly); return (rv); } @@ -207,8 +211,8 @@ pk11_authenticate(KMF_HANDLE_T handle, return (KMF_ERR_BAD_PARAMETER); } - if ((ck_rv = C_Login(hSession, CKU_USER, - (uchar_t *)cred->cred, cred->credlen)) != CKR_OK) { + if ((ck_rv = C_Login(hSession, CKU_USER, (uchar_t *)cred->cred, + cred->credlen)) != CKR_OK) { if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) { handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; handle->lasterr.errcode = ck_rv; @@ -306,7 +310,7 @@ PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj, /* re-query the object with room for the value attr */ ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, - templ, i); + templ, i); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); @@ -318,7 +322,7 @@ PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj, kmfcert->certificate.Length = value_len; kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED; kmfcert->kmf_private.keystore_type = - KMF_KEYSTORE_PK11TOKEN; + KMF_KEYSTORE_PK11TOKEN; ckrv = getObjectLabel(kmfh, hObj, &label); if (ckrv == CKR_OK && label != NULL) { @@ -417,8 +421,8 @@ matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, name.Length = certattr.ulValueLen; rv = DerDecodeName(&name, &dn); if (rv == KMF_OK) { - rv = KMF_CompareRDNs(issuer, &dn); - KMF_FreeDN(&dn); + rv = kmf_compare_rdns(issuer, &dn); + kmf_free_dn(&dn); } free(certattr.pValue); } @@ -438,8 +442,8 @@ matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, name.Length = certattr.ulValueLen; rv = DerDecodeName(&name, &dn); if (rv == KMF_OK) { - rv = KMF_CompareRDNs(subject, &dn); - KMF_FreeDN(&dn); + rv = kmf_compare_rdns(subject, &dn); + kmf_free_dn(&dn); } free(certattr.pValue); } @@ -470,7 +474,7 @@ pk11_delete_obj_from_list(OBJLIST **newlist, } /* - * prepare_object_search + * search_certs * * Because this code is shared by the FindCert and * DeleteCert functions, put it in a separate routine @@ -502,8 +506,7 @@ search_certs(KMF_HANDLE_T handle, i = 0; SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); i++; SETATTR(templ, i, CKA_CLASS, &oclass, sizeof (oclass)); i++; - SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype, - sizeof (ctype)); i++; + SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype, sizeof (ctype)); i++; if (label != NULL && strlen(label)) { SETATTR(templ, i, CKA_LABEL, label, strlen(label)); @@ -514,17 +517,16 @@ search_certs(KMF_HANDLE_T handle, } if (issuer != NULL && strlen(issuer)) { - if ((rv = KMF_DNParser(issuer, &issuerDN)) != KMF_OK) + if ((rv = kmf_dn_parser(issuer, &issuerDN)) != KMF_OK) return (rv); } if (subject != NULL && strlen(subject)) { - if ((rv = KMF_DNParser(subject, &subjectDN)) != KMF_OK) + if ((rv = kmf_dn_parser(subject, &subjectDN)) != KMF_OK) return (rv); } if (serial != NULL && serial->val != NULL && serial->len > 0) { - SETATTR(templ, i, CKA_SERIAL_NUMBER, - serial->val, serial->len); + SETATTR(templ, i, CKA_SERIAL_NUMBER, serial->val, serial->len); i++; } @@ -606,7 +608,7 @@ cleanup: goto cleanup1; } - rv = KMF_CheckCertDate(handle, + rv = kmf_check_cert_date(handle, &tmp_kmf_cert.certificate); if (validity == KMF_NONEXPIRED_CERTS) { @@ -643,7 +645,7 @@ cleanup: } } i++; - KMF_FreeKMFCert(handle, &tmp_kmf_cert); + kmf_free_kmf_cert(handle, &tmp_kmf_cert); } *numobj = num_ok_certs; *objlist = newlist; @@ -658,10 +660,10 @@ cleanup1: } if (issuer != NULL) - KMF_FreeDN(&issuerDN); + kmf_free_dn(&issuerDN); if (subject != NULL) - KMF_FreeDN(&subjectDN); + kmf_free_dn(&subjectDN); return (rv); } @@ -671,22 +673,29 @@ cleanup1: * just return the number of certs found (in num_certs). */ KMF_RETURN -KMFPK11_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, - KMF_X509_DER_CERT *kmf_cert, - uint32_t *num_certs) +KMFPK11_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = 0; uint32_t want_certs; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; OBJLIST *objlist = NULL; + uint32_t *num_certs; + KMF_X509_DER_CERT *kmf_cert = NULL; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; + boolean_t private; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL || num_certs == NULL) + num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (num_certs == NULL) return (KMF_ERR_BAD_PARAMETER); if (*num_certs > 0) @@ -696,19 +705,40 @@ KMFPK11_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, *num_certs = 0; - rv = search_certs(handle, - params->certLabel, params->issuer, - params->subject, params->serial, - params->pkcs11parms.private, - params->find_cert_validity, - &objlist, num_certs); + /* Get the optional returned certificate list */ + kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, + numattr); + + /* Get optional search criteria attributes */ + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); + if (rv != KMF_OK) { + validity = KMF_ALL_CERTS; + rv = KMF_OK; + } + + rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr, + (void *)&private, NULL); + if (rv != KMF_OK) { + private = B_FALSE; + rv = KMF_OK; + } + + /* Start searching */ + rv = search_certs(handle, certlabel, issuer, subject, serial, private, + validity, &objlist, num_certs); if (rv == KMF_OK && objlist != NULL && kmf_cert != NULL) { OBJLIST *node = objlist; int i = 0; while (node != NULL && i < want_certs) { rv = PK11Cert2KMFCert(kmfh, node->handle, - &kmf_cert[i]); + &kmf_cert[i]); i++; node = node->next; } @@ -725,8 +755,7 @@ KMFPK11_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, /*ARGSUSED*/ void -KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, - KMF_X509_DER_CERT *kmf_cert) +KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) { if (kmf_cert != NULL && kmf_cert->certificate.Data != NULL) { free(kmf_cert->certificate.Data); @@ -758,7 +787,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, CK_ATTRIBUTE rsaTemplate[4]; CK_ATTRIBUTE dsaTemplate[6]; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) @@ -778,7 +807,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, SETATTR(rsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType, sizeof (ckKeyType)); SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data, &Modulus.Length); SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT, Exponent.Data, - &Exponent.Length); + &Exponent.Length); SETATTR(dsaTemplate, 0, CKA_CLASS, &ckObjClass, sizeof (ckObjClass)); SETATTR(dsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType, sizeof (ckKeyType)); @@ -791,8 +820,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, case KMF_RSA: /* Get the length of the fields */ rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pKey->keyp, - rsaTemplate, 4); + (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4); if (rv != CKR_OK) { SET_ERROR(kmfh, rv); return (KMF_ERR_BAD_PARAMETER); @@ -811,13 +839,12 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, } SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data, - Modulus.Length); + Modulus.Length); SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT, - Exponent.Data, Exponent.Length); + Exponent.Data, Exponent.Length); /* Now get the values */ rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pKey->keyp, - rsaTemplate, 4); + (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4); if (rv != CKR_OK) { SET_ERROR(kmfh, rv); free(Modulus.Data); @@ -829,7 +856,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, * This is the KEY algorithm, not the * signature algorithm. */ - Algorithm = X509_AlgIdToAlgorithmOid(KMF_ALGID_RSA); + Algorithm = x509_algid_to_algoid(KMF_ALGID_RSA); if (Algorithm != NULL) { /* Encode the RSA Key Data */ @@ -838,9 +865,9 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, free(Exponent.Data); return (KMF_ERR_MEMORY); } - if (kmfber_printf(asn1, "{II}", - Modulus.Data, Modulus.Length, - Exponent.Data, Exponent.Length) == -1) { + if (kmfber_printf(asn1, "{II}", Modulus.Data, + Modulus.Length, Exponent.Data, + Exponent.Length) == -1) { kmfber_free(asn1, 1); free(Modulus.Data); free(Exponent.Data); @@ -862,8 +889,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, case KMF_DSA: /* Get the length of the fields */ rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pKey->keyp, - dsaTemplate, 6); + (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6); if (rv != CKR_OK) { SET_ERROR(kmfh, rv); return (KMF_ERR_BAD_PARAMETER); @@ -898,18 +924,17 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, return (KMF_ERR_MEMORY); } SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data, - Prime.Length); + Prime.Length); SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data, - Subprime.Length); + Subprime.Length); SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data, - Base.Length); + Base.Length); SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data, - Value.Length); + Value.Length); /* Now get the values */ rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pKey->keyp, - dsaTemplate, 6); + (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6); if (rv != CKR_OK) { free(Prime.Data); free(Subprime.Data); @@ -922,8 +947,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, * This is the KEY algorithm, not the * signature algorithm. */ - Algorithm = - X509_AlgIdToAlgorithmOid(KMF_ALGID_DSA); + Algorithm = x509_algid_to_algoid(KMF_ALGID_DSA); /* Encode the DSA Algorithm Parameters */ if ((asn1 = kmfder_alloc()) == NULL) { @@ -934,10 +958,9 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, return (KMF_ERR_MEMORY); } - if (kmfber_printf(asn1, "{III}", - Prime.Data, Prime.Length, - Subprime.Data, Subprime.Length, - Base.Data, Base.Length) == -1) { + if (kmfber_printf(asn1, "{III}", Prime.Data, + Prime.Length, Subprime.Data, Subprime.Length, + Base.Data, Base.Length) == -1) { kmfber_free(asn1, 1); free(Prime.Data); @@ -966,7 +989,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, } if (kmfber_printf(asn1, "I", - Value.Data, Value.Length) == -1) { + Value.Data, Value.Length) == -1) { kmfber_free(asn1, 1); free(Value.Data); return (KMF_ERR_ENCODING); @@ -987,7 +1010,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, spki.algorithm.algorithm = *Algorithm; if (PubKeyParams != NULL) { spki.algorithm.parameters.Data = - (uchar_t *)PubKeyParams->bv_val; + (uchar_t *)PubKeyParams->bv_val; spki.algorithm.parameters.Length = PubKeyParams->bv_len; } else { spki.algorithm.parameters.Data = NULL; @@ -1040,7 +1063,7 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) CK_OBJECT_HANDLE hCert = NULL; int i; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_INTERNAL); /* should not happen */ if (kmfh->pk11handle == CK_INVALID_HANDLE) @@ -1055,7 +1078,7 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) * the PKCS#11 attributes can be filled in correctly. */ rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert, - &signed_cert_ptr); + &signed_cert_ptr); if (rv != KMF_OK) { return (KMF_ERR_ENCODING); } @@ -1101,7 +1124,7 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) /* Generate an ID from the SPKI data */ rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo, - &Id); + &Id); if (rv != KMF_OK) { SET_ERROR(kmfh, rv); @@ -1109,10 +1132,10 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) } i = 0; - SETATTR(x509templ, i, CKA_CLASS, &certClass, - sizeof (certClass)); i++; + SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++; SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype, - sizeof (certtype)); i++; + sizeof (certtype)); + i++; SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++; SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++; SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++; @@ -1120,8 +1143,7 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++; SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++; if (label != NULL && strlen(label)) { - SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); - i++; + SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); i++; } /* * The cert object handle is actually "leaked" here. If the app @@ -1141,7 +1163,7 @@ cleanup: free(Id.Data); if (signed_cert_ptr) { - KMF_FreeSignedCert(signed_cert_ptr); + kmf_free_signed_cert(signed_cert_ptr); free(signed_cert_ptr); } return (rv); @@ -1149,67 +1171,75 @@ cleanup: KMF_RETURN -KMFPK11_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, - KMF_DATA *pcert) +KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = 0; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_DATA *cert = NULL; + char *label = NULL; - if (!kmfh) - return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ + if (kmfh == NULL) + return (KMF_ERR_UNINITIALIZED); if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL || cert->Data == NULL || cert->Length == 0) return (KMF_ERR_BAD_PARAMETER); - rv = CreateCertObject(handle, params->certLabel, pcert); + /* label attribute is optional */ + label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + + rv = CreateCertObject(handle, label, cert); return (rv); } - - KMF_RETURN -KMFPK11_ImportCert(KMF_HANDLE_T handle, KMF_IMPORTCERT_PARAMS *params) +KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = 0; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + char *certfile = NULL; + char *label = NULL; KMF_ENCODE_FORMAT format; KMF_DATA cert1 = { NULL, 0}; KMF_DATA cert2 = { NULL, 0}; - if (!kmfh) - return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ + if (kmfh == NULL) + return (KMF_ERR_UNINITIALIZED); if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL || params->certfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - /* - * Check if the input cert file is a valid certificate and - * auto-detect the file format of it. + * Get the input cert filename attribute, check if it is a valid + * certificate and auto-detect the file format of it. */ - rv = KMF_IsCertFile(handle, params->certfile, &format); + certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); + if (certfile == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_is_cert_file(handle, certfile, &format); if (rv != KMF_OK) return (rv); /* Read in the CERT file */ - rv = KMF_ReadInputFile(handle, params->certfile, &cert1); + rv = kmf_read_input_file(handle, certfile, &cert1); if (rv != KMF_OK) { return (rv); } + /* The label attribute is optional */ + label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + /* * If the input certificate is in PEM format, we need to convert * it to DER first. */ if (format == KMF_FORMAT_PEM) { int derlen; - rv = KMF_Pem2Der(cert1.Data, cert1.Length, + rv = kmf_pem_to_der(cert1.Data, cert1.Length, &cert2.Data, &derlen); if (rv != KMF_OK) { goto out; @@ -1217,7 +1247,7 @@ KMFPK11_ImportCert(KMF_HANDLE_T handle, KMF_IMPORTCERT_PARAMS *params) cert2.Length = (size_t)derlen; } - rv = CreateCertObject(handle, params->certLabel, + rv = CreateCertObject(handle, label, format == KMF_FORMAT_ASN1 ? &cert1 : &cert2); out: @@ -1233,41 +1263,60 @@ out: } KMF_RETURN -KMFPK11_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) +KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = 0; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; OBJLIST *objlist; uint32_t numObjects = 0; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; + boolean_t private; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL) - return (KMF_ERR_BAD_PARAMETER); + + /* Get the search criteria attributes. They are all optional. */ + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); + if (rv != KMF_OK) { + validity = KMF_ALL_CERTS; + rv = KMF_OK; + } + + rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr, + (void *)&private, NULL); + if (rv != KMF_OK) { + private = B_FALSE; + rv = KMF_OK; + } /* - * Use the same search routine as is used for the FindCert - * operation. + * Start searching for certificates that match the criteria and + * delete them. */ objlist = NULL; - rv = search_certs(handle, - params->certLabel, params->issuer, - params->subject, params->serial, - params->pkcs11parms.private, - params->find_cert_validity, - &objlist, &numObjects); + rv = search_certs(handle, certlabel, issuer, subject, serial, + private, validity, &objlist, &numObjects); if (rv == KMF_OK && objlist != NULL) { OBJLIST *node = objlist; while (node != NULL) { CK_RV ckrv; - ckrv = C_DestroyObject(kmfh->pk11handle, - node->handle); + ckrv = C_DestroyObject(kmfh->pk11handle, node->handle); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; @@ -1286,8 +1335,9 @@ out: } KMF_RETURN -KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, - KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey) +KMFPK11_CreateKeypair(KMF_HANDLE_T handle, + int numattr, + KMF_ATTRIBUTE *attlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -1302,14 +1352,15 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, static CK_ULONG rsaKeyType = CKK_RSA; static CK_ULONG modulusBits = 1024; + uint32_t modulusBits_size = sizeof (CK_ULONG); static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01}; static CK_BBOOL true = TRUE; static CK_BBOOL ontoken = TRUE; static CK_BBOOL false = FALSE; static CK_ULONG dsaKeyType = CKK_DSA; - CK_ATTRIBUTE rsaPubKeyTemplate[8]; - CK_ATTRIBUTE rsaPriKeyTemplate[6]; + CK_ATTRIBUTE rsaPubKeyTemplate[16]; + CK_ATTRIBUTE rsaPriKeyTemplate[16]; static CK_BYTE ckDsaPrime[128] = { 0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2, @@ -1381,106 +1432,146 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, char IDHashData[SHA1_HASH_LENGTH]; KMF_DATA IDInput, IDOutput; SHA1_CTX ctx; + KMF_CREDENTIAL *cred; + KMF_KEY_ALG keytype = KMF_RSA; + boolean_t storekey = TRUE; + char *keylabel = NULL; + KMF_KEY_HANDLE *pubkey, *privkey; #define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \ sizeof (CK_ATTRIBUTE)) #define MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \ sizeof (CK_ATTRIBUTE)) - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL) + /* "storekey" is optional. Default is TRUE */ + (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr, + &storekey, NULL); + + cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr); + if (cred == NULL) return (KMF_ERR_BAD_PARAMETER); - rv = pk11_authenticate(handle, ¶ms->cred); - if (rv != KMF_OK) { + rv = pk11_authenticate(handle, cred); + if (rv != KMF_OK) return (rv); - } - if (params->keytype == KMF_RSA) { - CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, - NULL, 0}; + /* keytype is optional. KMF_RSA is default */ + (void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr, + (void *)&keytype, NULL); + + pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr); + if (pubkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr); + if (privkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); + (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); + if (keytype == KMF_RSA) { + CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0}; CK_BYTE *modulus; CK_ULONG modulusLength; CK_ATTRIBUTE modattr[1]; + KMF_BIGINT *rsaexp = NULL; + int numpubattr = 0, numpriattr = 0; + + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr, + &modulusBits, &modulusBits_size); + if (rv == KMF_ERR_ATTR_NOT_FOUND) + /* Default modulusBits = 1024 */ + rv = KMF_OK; + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); - SETATTR(rsaPubKeyTemplate, 0, CKA_CLASS, - &pubClass, sizeof (pubClass)); - SETATTR(rsaPubKeyTemplate, 1, CKA_KEY_TYPE, - &rsaKeyType, sizeof (rsaKeyType)); - SETATTR(rsaPubKeyTemplate, 2, CKA_TOKEN, - &false, sizeof (false)); - SETATTR(rsaPubKeyTemplate, 3, CKA_PRIVATE, - &false, sizeof (false)); - SETATTR(rsaPubKeyTemplate, 4, CKA_MODULUS_BITS, - &modulusBits, sizeof (modulusBits)); - if (params->rsa_exponent.len > 0 && - params->rsa_exponent.val != NULL) { - SETATTR(rsaPubKeyTemplate, 5, - CKA_PUBLIC_EXPONENT, - params->rsa_exponent.val, - params->rsa_exponent.len); + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_CLASS, + &pubClass, sizeof (pubClass)); + numpubattr++; + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_KEY_TYPE, + &rsaKeyType, sizeof (rsaKeyType)); + numpubattr++; + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN, + (storekey ? &true : &false), sizeof (CK_BBOOL)); + numpubattr++; + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_PRIVATE, + &false, sizeof (false)); + numpubattr++; + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS, + &modulusBits, sizeof (modulusBits)); + numpubattr++; + + if ((rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist, + numattr)) != NULL && + (rsaexp->len > 0 && rsaexp->val != NULL)) { + SETATTR(rsaPubKeyTemplate, numpubattr, + CKA_PUBLIC_EXPONENT, + rsaexp->val, rsaexp->len); + numpubattr++; } else { - SETATTR(rsaPubKeyTemplate, 5, - CKA_PUBLIC_EXPONENT, &PubExpo, - sizeof (PubExpo)); - } - SETATTR(rsaPubKeyTemplate, 6, CKA_ENCRYPT, - &true, sizeof (true)); - SETATTR(rsaPubKeyTemplate, 7, CKA_VERIFY, - &true, sizeof (true)); - - SETATTR(rsaPriKeyTemplate, 0, CKA_CLASS, &priClass, - sizeof (priClass)); - SETATTR(rsaPriKeyTemplate, 1, CKA_KEY_TYPE, &rsaKeyType, - sizeof (rsaKeyType)); - SETATTR(rsaPriKeyTemplate, 2, CKA_TOKEN, &ontoken, - sizeof (ontoken)); - SETATTR(rsaPriKeyTemplate, 3, CKA_PRIVATE, &true, - sizeof (true)); - SETATTR(rsaPriKeyTemplate, 4, CKA_DECRYPT, &true, - sizeof (true)); - SETATTR(rsaPriKeyTemplate, 5, CKA_SIGN, &true, - sizeof (true)); + rv = KMF_OK; + SETATTR(rsaPubKeyTemplate, numpubattr, + CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo)); + numpubattr++; + } + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT, + &true, sizeof (true)); + numpubattr++; + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY, + &true, sizeof (true)); + numpubattr++; + + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_CLASS, &priClass, + sizeof (priClass)); + numpriattr++; + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_KEY_TYPE, + &rsaKeyType, sizeof (rsaKeyType)); + numpriattr++; + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN, + (storekey ? &true : &false), sizeof (CK_BBOOL)); + numpriattr++; + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true, + sizeof (true)); + numpriattr++; + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true, + sizeof (true)); + numpriattr++; + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true, + sizeof (true)); + numpriattr++; SETATTR(modattr, 0, CKA_MODULUS, NULL, &modulusLength); - modulusBits = params->keylength; - pubKey = CK_INVALID_HANDLE; priKey = CK_INVALID_HANDLE; ckrv = C_GenerateKeyPair(hSession, &keyGenMech, - rsaPubKeyTemplate, - (sizeof (rsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)), - rsaPriKeyTemplate, - (sizeof (rsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)), - &pubKey, &priKey); + rsaPubKeyTemplate, numpubattr, + rsaPriKeyTemplate, numpriattr, + &pubKey, &priKey); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); return (KMF_ERR_KEYGEN_FAILED); } - if (privkey != NULL) { - privkey->kstype = KMF_KEYSTORE_PK11TOKEN; - privkey->keyalg = KMF_RSA; - privkey->keyclass = KMF_ASYM_PRI; - privkey->keyp = (void *)priKey; - } - if (pubkey != NULL) { - pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; - pubkey->keyalg = KMF_RSA; - pubkey->keyclass = KMF_ASYM_PUB; - pubkey->keyp = (void *)pubKey; - } + privkey->kstype = KMF_KEYSTORE_PK11TOKEN; + privkey->keyalg = KMF_RSA; + privkey->keyclass = KMF_ASYM_PRI; + privkey->keyp = (void *)priKey; + + pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; + pubkey->keyalg = KMF_RSA; + pubkey->keyclass = KMF_ASYM_PUB; + pubkey->keyp = (void *)pubKey; /* Get the Modulus field to use as input for creating the ID */ rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pubKey, - modattr, 1); + (CK_OBJECT_HANDLE)pubKey, modattr, 1); if (rv != CKR_OK) { SET_ERROR(kmfh, ckrv); return (KMF_ERR_BAD_PARAMETER); @@ -1493,8 +1584,7 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, modattr[0].pValue = modulus; rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pubKey, - modattr, 1); + (CK_OBJECT_HANDLE)pubKey, modattr, 1); if (rv != CKR_OK) { SET_ERROR(kmfh, ckrv); free(modulus); @@ -1504,43 +1594,40 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, IDInput.Data = modulus; IDInput.Length = modulusLength; - } else if (params->keytype == KMF_DSA) { + } else if (keytype == KMF_DSA) { CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0}; CK_BYTE *keyvalue; CK_ULONG valueLen; CK_ATTRIBUTE valattr[1]; SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN, - &ontoken, sizeof (ontoken)); + (storekey ? &true : &false), sizeof (CK_BBOOL)); SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen); ckrv = C_GenerateKeyPair(hSession, &keyGenMech, - ckDsaPubKeyTemplate, - (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)), - ckDsaPriKeyTemplate, - (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)), - &pubKey, &priKey); + ckDsaPubKeyTemplate, + (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)), + ckDsaPriKeyTemplate, + (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)), + &pubKey, &priKey); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); return (KMF_ERR_KEYGEN_FAILED); } - if (privkey != NULL) { - privkey->kstype = KMF_KEYSTORE_PK11TOKEN; - privkey->keyalg = KMF_DSA; - privkey->keyclass = KMF_ASYM_PRI; - privkey->keyp = (void *)priKey; - } - if (pubkey != NULL) { - pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; - pubkey->keyalg = KMF_DSA; - pubkey->keyclass = KMF_ASYM_PUB; - pubkey->keyp = (void *)pubKey; - } + privkey->kstype = KMF_KEYSTORE_PK11TOKEN; + privkey->keyalg = KMF_DSA; + privkey->keyclass = KMF_ASYM_PRI; + privkey->keyp = (void *)priKey; + + pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; + pubkey->keyalg = KMF_DSA; + pubkey->keyclass = KMF_ASYM_PUB; + pubkey->keyp = (void *)pubKey; + /* Get the Public Value to use as input for creating the ID */ rv = C_GetAttributeValue(hSession, - (CK_OBJECT_HANDLE)pubKey, - valattr, 1); + (CK_OBJECT_HANDLE)pubKey, valattr, 1); if (rv != CKR_OK) { SET_ERROR(kmfh, ckrv); return (KMF_ERR_BAD_PARAMETER); @@ -1553,8 +1640,7 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, valattr[0].pValue = keyvalue; rv = C_GetAttributeValue(hSession, - (CK_OBJECT_HANDLE)pubKey, - valattr, 1); + (CK_OBJECT_HANDLE)pubKey, valattr, 1); if (rv != CKR_OK) { SET_ERROR(kmfh, ckrv); free(keyvalue); @@ -1567,41 +1653,35 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, return (KMF_ERR_BAD_PARAMETER); } - if (params->keylabel != NULL && - strlen(params->keylabel)) { - - SETATTR(labelattr, 0, CKA_LABEL, params->keylabel, - strlen(params->keylabel)); + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr); + if (keylabel != NULL && strlen(keylabel)) { + SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel)); /* Set the CKA_LABEL if one was indicated */ if ((ckrv = C_SetAttributeValue(hSession, pubKey, - labelattr, 1)) != CKR_OK) { + labelattr, 1)) != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; goto cleanup; } - if (pubkey != NULL) { - pubkey->keylabel = - (char *)strdup(params->keylabel); - if (pubkey->keylabel == NULL) { - rv = KMF_ERR_MEMORY; - goto cleanup; - } + pubkey->keylabel = (char *)strdup(keylabel); + if (pubkey->keylabel == NULL) { + rv = KMF_ERR_MEMORY; + goto cleanup; } if ((ckrv = C_SetAttributeValue(hSession, priKey, - labelattr, 1)) != CKR_OK) { + labelattr, 1)) != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; goto cleanup; } - if (privkey != NULL) { - privkey->keylabel = - (char *)strdup(params->keylabel); - if (privkey->keylabel == NULL) { - rv = KMF_ERR_MEMORY; - goto cleanup; - } + privkey->keylabel = (char *)strdup(keylabel); + if (privkey->keylabel == NULL) { + rv = KMF_ERR_MEMORY; + goto cleanup; } + } else { + rv = KMF_OK; } /* Now, assign a CKA_ID value so it can be searched */ @@ -1623,13 +1703,13 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, } SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length); if ((ckrv = C_SetAttributeValue(hSession, pubKey, - idattr, 1)) != CKR_OK) { + idattr, 1)) != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; goto cleanup; } if ((ckrv = C_SetAttributeValue(hSession, priKey, - idattr, 1)) != CKR_OK) { + idattr, 1)) != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; goto cleanup; @@ -1641,44 +1721,52 @@ cleanup: (void) C_DestroyObject(hSession, pubKey); if (priKey != CK_INVALID_HANDLE) (void) C_DestroyObject(hSession, priKey); - if (privkey) { - privkey->keyp = NULL; - if (privkey->keylabel) - free(privkey->keylabel); - } - if (pubkey) { - pubkey->keyp = NULL; - if (pubkey->keylabel) - free(pubkey->keylabel); - } + + if (privkey->keylabel) + free(privkey->keylabel); + if (pubkey->keylabel) + free(pubkey->keylabel); } return (rv); } KMF_RETURN -KMFPK11_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, - KMF_KEY_HANDLE *key, boolean_t destroy) +KMFPK11_DeleteKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; CK_RV ckrv = CKR_OK; KMF_RETURN rv = KMF_OK; + KMF_KEY_HANDLE *key; + KMF_CREDENTIAL cred; + boolean_t destroy = B_TRUE; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); if (key == NULL || key->keyp == NULL) return (KMF_ERR_BAD_PARAMETER); if (key->keyclass != KMF_ASYM_PUB && - key->keyclass != KMF_ASYM_PRI && - key->keyclass != KMF_SYMMETRIC) + key->keyclass != KMF_ASYM_PRI && + key->keyclass != KMF_SYMMETRIC) return (KMF_ERR_BAD_KEY_CLASS); + /* "destroy" is optional. Default is TRUE */ + (void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr, + (void *)&destroy, NULL); + if (destroy) { - rv = pk11_authenticate(handle, ¶ms->cred); + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = pk11_authenticate(handle, &cred); if (rv != KMF_OK) { return (rv); } @@ -1686,19 +1774,17 @@ KMFPK11_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, if (!key->israw && destroy) ckrv = C_DestroyObject(kmfh->pk11handle, - (CK_OBJECT_HANDLE)key->keyp); + (CK_OBJECT_HANDLE)key->keyp); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); /* Report authentication failures to the caller */ - if (ckrv == CKR_PIN_EXPIRED || - ckrv == CKR_SESSION_READ_ONLY) + if (ckrv == CKR_PIN_EXPIRED || ckrv == CKR_SESSION_READ_ONLY) rv = KMF_ERR_AUTH_FAILED; else rv = KMF_ERR_INTERNAL; } return (rv); - } KMF_RETURN @@ -1712,9 +1798,9 @@ KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, CK_SESSION_HANDLE hSession = kmfh->pk11handle; CK_MECHANISM mechanism; PKCS_ALGORITHM_MAP *pAlgMap; - KMF_ALGORITHM_INDEX AlgId; + KMF_ALGORITHM_INDEX AlgId; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) @@ -1725,13 +1811,13 @@ KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, return (KMF_ERR_BAD_PARAMETER); /* These functions are available to the plugin from libkmf */ - AlgId = X509_AlgorithmOidToAlgId(algOID); + AlgId = x509_algoid_to_algid(algOID); if (AlgId == KMF_ALGID_NONE) return (KMF_ERR_BAD_PARAMETER); /* Map the Algorithm OID to a PKCS#11 mechanism */ - pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, - AlgId, PKCS_GetDefaultSignatureMode(AlgId)); + pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, + AlgId, PKCS_GetDefaultSignatureMode(AlgId)); if (pAlgMap == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -1746,9 +1832,8 @@ KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, return (KMF_ERR_INTERNAL); } - ckrv = C_Sign(hSession, - tobesigned->Data, tobesigned->Length, - output->Data, (CK_ULONG *)&output->Length); + ckrv = C_Sign(hSession, tobesigned->Data, tobesigned->Length, + output->Data, (CK_ULONG *)&output->Length); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); @@ -1816,11 +1901,10 @@ getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj, return (rv); } + KMF_RETURN -KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, - KMF_CRYPTOWITHCERT_PARAMS *params, - KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, - KMF_KEY_ALG keytype) +KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) { KMF_X509_SPKI *pubkey; KMF_X509_CERTIFICATE *SignerCert = NULL; @@ -1833,9 +1917,27 @@ KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, CK_OBJECT_CLASS certClass = CKO_PRIVATE_KEY; CK_BBOOL true = TRUE; KMF_DATA Id = { NULL, 0 }; + KMF_KEY_HANDLE *key = NULL; + KMF_DATA *cert = NULL; + KMF_CREDENTIAL cred; + KMF_ENCODE_FORMAT format = KMF_FORMAT_UNDEF; + CK_ULONG keytype; + + /* Get the key handle */ + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (key == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* Get the optional encoded format */ + (void) kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, + (void *)&format, NULL); /* Decode the signer cert so we can get the SPKI data */ - if ((rv = DerDecodeSignedCertificate(SignerCertData, + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL || cert->Data == NULL) + return (KMF_ERR_BAD_PARAMETER); + + if ((rv = DerDecodeSignedCertificate(cert, &SignerCert)) != KMF_OK) return (rv); @@ -1844,22 +1946,28 @@ KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, /* Generate an ID from the SPKI data */ rv = GetIDFromSPKI(pubkey, &Id); - if (rv != KMF_OK) { SET_ERROR(kmfh, rv); goto errout; } - SETATTR(templ, 0, CKA_CLASS, &certClass, sizeof (certClass)); - SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true)); - SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true)); - SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length); + /* Get the credential and login */ + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); - rv = pk11_authenticate(handle, ¶ms->cred); + rv = pk11_authenticate(handle, &cred); if (rv != KMF_OK) { return (rv); } + /* Start searching */ + SETATTR(templ, 0, CKA_CLASS, &certClass, sizeof (certClass)); + SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true)); + SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true)); + SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length); + if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; @@ -1881,14 +1989,29 @@ KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, key->kstype = KMF_KEYSTORE_PK11TOKEN; key->keyclass = KMF_ASYM_PRI; - key->keyalg = keytype; key->keyp = (void *)pri_obj; + key->israw = FALSE; (void) C_FindObjectsFinal(kmfh->pk11handle); ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp, - &key->keylabel); + &key->keylabel); + if (ckrv != CKR_OK) { + SET_ERROR(handle, ckrv); + rv = KMF_ERR_INTERNAL; + } else { + rv = KMF_OK; + } + /* + * The key->keyalg value is needed if we need to convert the key + * to raw key. However, the key->keyalg value will not be set if + * this function is not called thru the kmf_find_prikey_by_cert() + * framework function. To be safe, we will get the keytype from + * the key object and set key->keyalg value here. + */ + ckrv = getObjectKeytype(handle, (CK_OBJECT_HANDLE)key->keyp, + &keytype); if (ckrv != CKR_OK) { SET_ERROR(handle, ckrv); rv = KMF_ERR_INTERNAL; @@ -1896,7 +2019,17 @@ KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, rv = KMF_OK; } - if (rv == KMF_OK && params->format == KMF_FORMAT_RAWKEY) { + if (keytype == CKK_RSA) + key->keyalg = KMF_RSA; + else if (keytype == CKK_DSA) + key->keyalg = KMF_DSA; + else { + /* For asymmetric keys, we only support RSA and DSA */ + rv = KMF_ERR_KEY_NOT_FOUND; + goto errout; + } + + if (rv == KMF_OK && format == KMF_FORMAT_RAWKEY) { KMF_RAW_KEY_DATA *rkey = NULL; rv = keyObj2RawKey(handle, key, &rkey); if (rv == KMF_OK) { @@ -1910,7 +2043,7 @@ errout: free(Id.Data); if (SignerCert != NULL) { - KMF_FreeSignedCert(SignerCert); + kmf_free_signed_cert(SignerCert); free(SignerCert); } return (rv); @@ -1932,7 +2065,7 @@ KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, int i, blocks; CK_ATTRIBUTE ckTemplate[1]; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) @@ -1942,12 +2075,12 @@ KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, ciphertext == NULL || output == NULL) return (KMF_ERR_BAD_PARAMETER); - AlgId = X509_AlgorithmOidToAlgId(algOID); + AlgId = x509_algoid_to_algid(algOID); if (AlgId == KMF_ALGID_NONE) return (KMF_ERR_BAD_PARAMETER); /* Map the Algorithm ID to a PKCS#11 mechanism */ - pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, + pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, AlgId, PKCS_GetDefaultSignatureMode(AlgId)); if (pAlgMap == NULL) @@ -1980,7 +2113,7 @@ KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, for (i = 0; i < blocks; i++) { ckrv = C_DecryptInit(hSession, &mechanism, - (CK_OBJECT_HANDLE)key->keyp); + (CK_OBJECT_HANDLE)key->keyp); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); @@ -2019,7 +2152,7 @@ get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa) KMF_RETURN rv = KMF_OK; CK_RV ckrv; CK_SESSION_HANDLE sess = kmfh->pk11handle; - CK_ATTRIBUTE rsa_pri_attrs[8] = { + CK_ATTRIBUTE rsa_pri_attrs[8] = { { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 }, { CKA_PRIVATE_EXPONENT, NULL, 0 }, /* optional */ @@ -2029,11 +2162,11 @@ get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa) { CKA_EXPONENT_2, NULL, 0 }, /* | */ { CKA_COEFFICIENT, NULL, 0 } /* V */ }; - CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE); - int i; + CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE); + int i; if ((ckrv = C_GetAttributeValue(sess, obj, - rsa_pri_attrs, count)) != CKR_OK) { + rsa_pri_attrs, count)) != CKR_OK) { SET_ERROR(kmfh, ckrv); /* Tell the caller know why the key data cannot be retrieved. */ if (ckrv == CKR_ATTRIBUTE_SENSITIVE) @@ -2059,7 +2192,7 @@ get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa) } /* Now that we have space, really get the attributes */ if ((rv = C_GetAttributeValue(sess, obj, - rsa_pri_attrs, count)) != CKR_OK) { + rsa_pri_attrs, count)) != CKR_OK) { SET_ERROR(kmfh, rv); rv = KMF_ERR_INTERNAL; goto end; @@ -2109,10 +2242,78 @@ end: return (rv); } +#define DSA_PRIME_BUFSIZE 256 /* 8192 bits */ +#define DSA_PRIVATE_BUFSIZE 5 /* 160 bits */ + +/* + * This function calculates the pubkey value from the prime, + * base and private key values of a DSA key. + */ +static KMF_RETURN +compute_dsa_pubvalue(KMF_RAW_DSA_KEY *rawdsa) +{ + KMF_RETURN rv = KMF_OK; + BIGNUM p, g, x, y; + BIG_ERR_CODE err; + uchar_t *pubvalue; + uint32_t pubvalue_len; + + if ((err = big_init1(&p, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { + rv = KMF_ERR_MEMORY; + return (rv); + } + bytestring2bignum(&p, rawdsa->prime.val, rawdsa->prime.len); + + if ((err = big_init1(&g, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { + rv = KMF_ERR_MEMORY; + goto ret1; + } + bytestring2bignum(&g, rawdsa->base.val, rawdsa->base.len); + + if ((err = big_init1(&x, DSA_PRIVATE_BUFSIZE, NULL, 0)) != BIG_OK) { + rv = KMF_ERR_MEMORY; + goto ret2; + } + bytestring2bignum(&x, rawdsa->value.val, rawdsa->value.len); + + if ((err = big_init1(&y, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { + rv = KMF_ERR_MEMORY; + goto ret3; + } + + err = big_modexp(&y, &g, &x, &p, NULL); + if (err != BIG_OK) { + rv = KMF_ERR_INTERNAL; + goto ret3; + } + + pubvalue_len = y.len * (int)sizeof (uint32_t); + if ((pubvalue = malloc(pubvalue_len)) == NULL) { + rv = KMF_ERR_MEMORY; + goto ret4; + } + bignum2bytestring(pubvalue, &y, pubvalue_len); + + rawdsa->pubvalue.val = pubvalue; + rawdsa->pubvalue.len = pubvalue_len; + +ret4: + big_finish(&y); +ret3: + big_finish(&x); +ret2: + big_finish(&g); +ret1: + big_finish(&p); + return (rv); +} + + static KMF_RETURN get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) { KMF_RETURN rv = KMF_OK; + CK_RV ckrv; CK_SESSION_HANDLE sess = kmfh->pk11handle; CK_ATTRIBUTE dsa_pri_attrs[8] = { { CKA_PRIME, NULL, 0 }, @@ -2123,9 +2324,15 @@ get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE); int i; - if ((rv = C_GetAttributeValue(sess, obj, - dsa_pri_attrs, count)) != CKR_OK) { - SET_ERROR(kmfh, rv); + if ((ckrv = C_GetAttributeValue(sess, obj, + dsa_pri_attrs, count)) != CKR_OK) { + SET_ERROR(kmfh, ckrv); + + /* Tell the caller know why the key data cannot be retrieved. */ + if (ckrv == CKR_ATTRIBUTE_SENSITIVE) + return (KMF_ERR_SENSITIVE_KEY); + else if (ckrv == CKR_KEY_UNEXTRACTABLE) + return (KMF_ERR_UNEXTRACTABLE_KEY); return (KMF_ERR_INTERNAL); } @@ -2143,7 +2350,7 @@ get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) } } if ((rv = C_GetAttributeValue(sess, obj, - dsa_pri_attrs, count)) != CKR_OK) { + dsa_pri_attrs, count)) != CKR_OK) { SET_ERROR(kmfh, rv); rv = KMF_ERR_INTERNAL; goto end; @@ -2156,6 +2363,9 @@ get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base); attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value); + /* Compute the public key value and store it */ + rv = compute_dsa_pubvalue(rawdsa); + end: if (rv != KMF_OK) { for (i = 0; i < count; i++) { @@ -2181,19 +2391,16 @@ get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym) sym_attr[0].pValue = NULL; sym_attr[0].ulValueLen = value_len; if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) { - /* - * Don't return error if the key is sensitive, just - * don't return any raw data. Operations like "list" - * need to succeed even if the raw data is not - * available. - */ + rawsym->keydata.val = NULL; + rawsym->keydata.len = 0; if (ckrv == CKR_ATTRIBUTE_SENSITIVE) { - rawsym->keydata.val = NULL; - rawsym->keydata.len = 0; - return (CKR_OK); + return (KMF_ERR_SENSITIVE_KEY); + } else if (ckrv == CKR_KEY_UNEXTRACTABLE) { + return (KMF_ERR_UNEXTRACTABLE_KEY); + } else { + SET_ERROR(kmfh, ckrv); + return (KMF_ERR_INTERNAL); } - SET_ERROR(kmfh, ckrv); - return (KMF_ERR_INTERNAL); } /* Allocate memory for pValue */ @@ -2232,10 +2439,10 @@ keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey, if (inkey->keyalg == KMF_RSA) { rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, - &rkey->rawdata.rsa); + &rkey->rawdata.rsa); } else if (inkey->keyalg == KMF_DSA) { rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, - &rkey->rawdata.dsa); + &rkey->rawdata.dsa); } else if (inkey->keyalg == KMF_AES || inkey->keyalg == KMF_RC4 || inkey->keyalg == KMF_DES || @@ -2243,6 +2450,18 @@ keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey, inkey->keyalg == KMF_GENERIC_SECRET) { rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, &rkey->rawdata.sym); + /* + * If sensitive or non-extractable, mark them as such + * but return "OK" status so the keys get counted + * when doing FindKey operations. + */ + if (rv == KMF_ERR_SENSITIVE_KEY) { + rkey->sensitive = B_TRUE; + rv = KMF_OK; + } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) { + rkey->not_extractable = B_TRUE; + rv = KMF_OK; + } } else { rv = KMF_ERR_BAD_PARAMETER; } @@ -2333,8 +2552,8 @@ IDStringToData(char *idstr, KMF_DATA *iddata) } KMF_RETURN -KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, - KMF_KEY_HANDLE *keys, uint32_t *numkeys) +KMFPK11_FindKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -2344,63 +2563,80 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, CK_OBJECT_CLASS class; CK_BBOOL true = TRUE; CK_ULONG alg; - CK_BBOOL is_token; + boolean_t is_token, is_private; + KMF_KEY_HANDLE *keys; + uint32_t *numkeys; + KMF_CREDENTIAL cred; + KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE; + char *findLabel, *idstr; + KMF_KEY_ALG keytype = KMF_KEYALG_NONE; + KMF_ENCODE_FORMAT format; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (parms == NULL || numkeys == NULL) + numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (numkeys == NULL) return (KMF_ERR_BAD_PARAMETER); - if (numkeys != NULL && *numkeys > 0) + if (*numkeys > 0) want_keys = *numkeys; else want_keys = MAXINT; /* count them all */ - is_token = parms->pkcs11parms.token; - if (parms->keyclass == KMF_ASYM_PUB) { + /* keyclass is optional */ + (void) kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, + (void *)&keyclass, NULL); + + if (keyclass == KMF_ASYM_PUB) { class = CKO_PUBLIC_KEY; - } else if (parms->keyclass == KMF_ASYM_PRI) { + } else if (keyclass == KMF_ASYM_PRI) { class = CKO_PRIVATE_KEY; - } else if (parms->keyclass == KMF_SYMMETRIC) { + } else if (keyclass == KMF_SYMMETRIC) { class = CKO_SECRET_KEY; - } else { - return (KMF_ERR_BAD_KEY_CLASS); } + rv = kmf_get_attr(KMF_TOKEN_BOOL_ATTR, attrlist, numattr, + (void *)&is_token, NULL); + if (rv != KMF_OK) + return (rv); + i = 0; - pTmpl[i].type = CKA_TOKEN; - pTmpl[i].pValue = &is_token; - pTmpl[i].ulValueLen = sizeof (CK_BBOOL); - i++; + if (is_token) { + SETATTR(pTmpl, i, CKA_TOKEN, &true, sizeof (true)); + i++; + } - pTmpl[i].type = CKA_CLASS; - pTmpl[i].pValue = &class; - pTmpl[i].ulValueLen = sizeof (class); - i++; + if (keyclass != KMF_KEYCLASS_NONE) { + SETATTR(pTmpl, i, CKA_CLASS, &class, sizeof (class)); + i++; + } - if (parms->findLabel != NULL && strlen(parms->findLabel)) { - pTmpl[i].type = CKA_LABEL; - pTmpl[i].pValue = parms->findLabel; - pTmpl[i].ulValueLen = strlen(parms->findLabel); + findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + + if (findLabel != NULL && strlen(findLabel)) { + SETATTR(pTmpl, i, CKA_LABEL, findLabel, strlen(findLabel)); i++; } + /* keytype is optional */ + (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); - if (parms->keytype != 0) { - rv = kmf2pk11keytype(parms->keytype, &alg); + if (keytype != 0) { + rv = kmf2pk11keytype(keytype, &alg); if (rv != KMF_OK) { return (KMF_ERR_BAD_KEY_TYPE); } - pTmpl[i].type = CKA_KEY_TYPE; - pTmpl[i].pValue = &alg; - pTmpl[i].ulValueLen = sizeof (alg); + SETATTR(pTmpl, i, CKA_KEY_TYPE, &alg, sizeof (alg)); i++; } - if (parms->idstr != NULL) { + idstr = kmf_get_attr_ptr(KMF_IDSTR_ATTR, attrlist, numattr); + + if (idstr != NULL) { KMF_DATA iddata = { NULL, 0 }; /* @@ -2411,21 +2647,21 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, * We must convert this back to binary in order to * use it in a search. */ - rv = IDStringToData(parms->idstr, &iddata); + rv = IDStringToData(idstr, &iddata); if (rv == KMF_OK) { - pTmpl[i].type = CKA_ID; - pTmpl[i].pValue = iddata.Data; - pTmpl[i].ulValueLen = iddata.Length; + SETATTR(pTmpl, i, CKA_ID, iddata.Data, iddata.Length); i++; } else { return (rv); } } - if (parms->pkcs11parms.private) { - pTmpl[i].type = CKA_PRIVATE; - pTmpl[i].pValue = &true; - pTmpl[i].ulValueLen = sizeof (true); + /* is_private is optional */ + (void) kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr, + (void *)&is_private, NULL); + + if (is_private) { + SETATTR(pTmpl, i, CKA_PRIVATE, &true, sizeof (true)); i++; } @@ -2433,13 +2669,20 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, * Authenticate if the object is a token object, * a private or secred key, or if the user passed in credentials. */ - if (parms->cred.credlen > 0) { - rv = pk11_authenticate(handle, &parms->cred); - if (rv != KMF_OK) { - return (rv); + if ((rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL)) == KMF_OK) { + if (cred.credlen > 0) { + rv = pk11_authenticate(handle, &cred); + if (rv != KMF_OK) + return (rv); } + } else { + rv = KMF_OK; /* cred is optional */ } + keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + /* it is okay to have "keys" contains NULL */ + ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i); if (ckrv == CKR_OK) { CK_ULONG obj_count, n = 0; @@ -2447,42 +2690,56 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, CK_OBJECT_HANDLE hObj; ckrv = C_FindObjects(kmfh->pk11handle, &hObj, - 1, &obj_count); + 1, &obj_count); if (ckrv == CKR_OK && obj_count == 1) { if (keys != NULL) { CK_ULONG keytype; keys[n].kstype = KMF_KEYSTORE_PK11TOKEN; - keys[n].keyclass = parms->keyclass; + keys[n].keyclass = keyclass; keys[n].israw = FALSE; keys[n].keyp = (void *)hObj; ckrv = getObjectKeytype(handle, - (CK_OBJECT_HANDLE)keys[n].keyp, - &keytype); + (CK_OBJECT_HANDLE)keys[n].keyp, + &keytype); if (ckrv != CKR_OK) goto end; ckrv = getObjectLabel(handle, - (CK_OBJECT_HANDLE)keys[n].keyp, - &(keys[n].keylabel)); + (CK_OBJECT_HANDLE)keys[n].keyp, + &(keys[n].keylabel)); if (ckrv != CKR_OK) goto end; - if (keytype == CKK_RSA) + if (keytype == CKK_RSA) { keys[n].keyalg = KMF_RSA; - else if (keytype == CKK_DSA) + keys[n].keyclass = KMF_ASYM_PRI; + } else if (keytype == CKK_DSA) { keys[n].keyalg = KMF_DSA; - else if (keytype == CKK_AES) + keys[n].keyclass = KMF_ASYM_PRI; + } else if (keytype == CKK_AES) { keys[n].keyalg = KMF_AES; - else if (keytype == CKK_RC4) + keys[n].keyclass = + KMF_SYMMETRIC; + } else if (keytype == CKK_RC4) { keys[n].keyalg = KMF_RC4; - else if (keytype == CKK_DES) + keys[n].keyclass = + KMF_SYMMETRIC; + } else if (keytype == CKK_DES) { keys[n].keyalg = KMF_DES; - else if (keytype == CKK_DES3) + keys[n].keyclass = + KMF_SYMMETRIC; + } else if (keytype == CKK_DES3) { keys[n].keyalg = KMF_DES3; - else if (keytype == CKK_GENERIC_SECRET) + keys[n].keyclass = + KMF_SYMMETRIC; + } else if (keytype == + CKK_GENERIC_SECRET) { keys[n].keyalg = KMF_GENERIC_SECRET; + keys[n].keyclass = + KMF_SYMMETRIC; + } } n++; @@ -2495,21 +2752,30 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, /* "numkeys" indicates the number that were actually found */ *numkeys = n; } + if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) { - if (parms->format == KMF_FORMAT_RAWKEY) { - /* Convert keys to "rawkey" format */ - for (i = 0; i < (*numkeys); i++) { - KMF_RAW_KEY_DATA *rkey = NULL; - rv = keyObj2RawKey(handle, &keys[i], &rkey); - if (rv == KMF_OK) { - keys[i].keyp = rkey; - keys[i].israw = TRUE; - } else { - break; + if ((rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, + numattr, (void *)&format, NULL)) == KMF_OK) { + if (format == KMF_FORMAT_RAWKEY || + format == KMF_FORMAT_PEM) { + /* Convert keys to "rawkey" format */ + for (i = 0; i < (*numkeys); i++) { + KMF_RAW_KEY_DATA *rkey = NULL; + rv = keyObj2RawKey(handle, &keys[i], + &rkey); + if (rv == KMF_OK) { + keys[i].keyp = rkey; + keys[i].israw = TRUE; + } else { + break; + } } } + } else { + rv = KMF_OK; /* format is optional */ } } + end: if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); @@ -2549,8 +2815,9 @@ convertDate(char *fulldate) return ((char *)strdup(newtime)); } -KMF_RETURN -KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, +static KMF_RETURN +store_raw_key(KMF_HANDLE_T handle, + KMF_ATTRIBUTE *attrlist, int numattr, KMF_RAW_KEY_DATA *rawkey) { KMF_RETURN rv = KMF_OK; @@ -2567,20 +2834,18 @@ KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, KMF_DATA subject = {NULL, 0}; KMF_X509EXT_KEY_USAGE kuext; KMF_X509_CERTIFICATE *x509 = NULL; - CK_BBOOL kufound; + CK_BBOOL kufound = B_FALSE; + KMF_DATA *cert = NULL; char *notbefore = NULL, *start = NULL; char *notafter = NULL, *end = NULL; + char *keylabel = NULL; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL || params->certificate == NULL || - rawkey == NULL) - return (KMF_ERR_BAD_PARAMETER); - if (rawkey->keytype == KMF_RSA) keytype = CKK_RSA; else if (rawkey->keytype == KMF_DSA) @@ -2588,57 +2853,77 @@ KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, else return (KMF_ERR_BAD_PARAMETER); - rv = pk11_authenticate(handle, ¶ms->cred); - if (rv != KMF_OK) { - return (rv); - } + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); - id.Data = NULL; - id.Length = 0; - rv = KMF_GetCertIDData(params->certificate, &id); - if (rv != KMF_OK) { - goto cleanup; - } + i = 0; + SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++; + SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++; + SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++; + SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++; + SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++; - rv = DerDecodeSignedCertificate( - (const KMF_DATA *)params->certificate, &x509); - if (rv != KMF_OK) { - goto cleanup; - } + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert != NULL) { + id.Data = NULL; + id.Length = 0; + rv = kmf_get_cert_id_data(cert, &id); + if (rv != KMF_OK) { + goto cleanup; + } - rv = DerEncodeName(&x509->certificate.subject, &subject); - if (rv != KMF_OK) { - goto cleanup; - } + rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509); + if (rv != KMF_OK) { + goto cleanup; + } - rv = KMF_GetCertStartDateString(handle, params->certificate, - ¬before); - if (rv != KMF_OK) { - goto cleanup; - } - start = convertDate(notbefore); + rv = DerEncodeName(&x509->certificate.subject, &subject); + if (rv != KMF_OK) { + goto cleanup; + } + SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length); + i++; - rv = KMF_GetCertEndDateString(handle, params->certificate, - ¬after); - if (rv != KMF_OK) { - goto cleanup; - } - end = convertDate(notafter); + rv = kmf_get_cert_start_date_str(handle, cert, ¬before); + if (rv != KMF_OK) { + goto cleanup; + } + start = convertDate(notbefore); - if ((rv = KMF_GetCertKeyUsageExt(params->certificate, &kuext)) - != KMF_OK && rv != KMF_ERR_EXTENSION_NOT_FOUND) - goto cleanup; + rv = kmf_get_cert_end_date_str(handle, cert, ¬after); + if (rv != KMF_OK) { + goto cleanup; + } + end = convertDate(notafter); + if (id.Data != NULL && id.Data != NULL && id.Length > 0) { + SETATTR(templ, i, CKA_ID, id.Data, id.Length); + i++; + } + if (start != NULL) { + /* + * This makes some potentially dangerous assumptions: + * 1. that the startdate in the parameter block is + * properly formatted as YYYYMMDD + * 2. That the CK_DATE structure is always the same. + */ + (void) memcpy(&startdate, start, sizeof (CK_DATE)); + SETATTR(templ, i, CKA_START_DATE, &startdate, + sizeof (startdate)); + i++; + } + if (end != NULL) { + (void) memcpy(&enddate, end, sizeof (CK_DATE)); + SETATTR(templ, i, CKA_END_DATE, &enddate, + sizeof (enddate)); + i++; + } - kufound = (rv == KMF_OK); - rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND above */ + if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK && + rv != KMF_ERR_EXTENSION_NOT_FOUND) + goto cleanup; - i = 0; - SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++; - SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++; - SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++; - SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++; - SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length); i++; - SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++; + kufound = (rv == KMF_OK); + rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */ + } /* * Only set the KeyUsage stuff if the KU extension was present. @@ -2647,110 +2932,90 @@ KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, CK_BBOOL condition; condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ? - B_TRUE : B_FALSE; - SETATTR(templ, i, CKA_UNWRAP, &condition, - sizeof (CK_BBOOL)); i++; + B_TRUE : B_FALSE; + SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL)); + i++; condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ? - B_TRUE : B_FALSE; - SETATTR(templ, i, CKA_DECRYPT, &condition, - sizeof (CK_BBOOL)); i++; + B_TRUE : B_FALSE; + SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL)); + i++; condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? - B_TRUE : B_FALSE; - SETATTR(templ, i, CKA_SIGN, &condition, - sizeof (CK_BBOOL)); i++; + B_TRUE : B_FALSE; + SETATTR(templ, i, CKA_SIGN, &condition, sizeof (CK_BBOOL)); + i++; condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? - B_TRUE : B_FALSE; + B_TRUE : B_FALSE; SETATTR(templ, i, CKA_SIGN_RECOVER, &condition, - sizeof (CK_BBOOL)); i++; - } - if (params->label != NULL) { - SETATTR(templ, i, CKA_LABEL, params->label, - strlen(params->label)); - i++; - } - if (id.Data != NULL && - id.Data != NULL && id.Length > 0) { - SETATTR(templ, i, CKA_ID, id.Data, id.Length); - i++; - } - if (start != NULL) { - /* - * This make some potentially dangerous assumptions: - * 1. that the startdate in the parameter block is - * properly formatted as YYYYMMDD - * 2. That the CK_DATE structure is always the same. - */ - (void) memcpy(&startdate, start, sizeof (CK_DATE)); - SETATTR(templ, i, CKA_START_DATE, &startdate, - sizeof (startdate)); + sizeof (CK_BBOOL)); i++; + } - if (end != NULL) { - (void) memcpy(&enddate, end, sizeof (CK_DATE)); - SETATTR(templ, i, CKA_END_DATE, &enddate, sizeof (enddate)); + + if (keylabel != NULL) { + SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); i++; } if (keytype == CKK_RSA) { SETATTR(templ, i, CKA_MODULUS, - rawkey->rawdata.rsa.mod.val, - rawkey->rawdata.rsa.mod.len); + rawkey->rawdata.rsa.mod.val, + rawkey->rawdata.rsa.mod.len); i++; SETATTR(templ, i, CKA_PUBLIC_EXPONENT, - rawkey->rawdata.rsa.pubexp.val, - rawkey->rawdata.rsa.pubexp.len); + rawkey->rawdata.rsa.pubexp.val, + rawkey->rawdata.rsa.pubexp.len); i++; if (rawkey->rawdata.rsa.priexp.val != NULL) { SETATTR(templ, i, CKA_PRIVATE_EXPONENT, - rawkey->rawdata.rsa.priexp.val, - rawkey->rawdata.rsa.priexp.len); + rawkey->rawdata.rsa.priexp.val, + rawkey->rawdata.rsa.priexp.len); i++; } if (rawkey->rawdata.rsa.prime1.val != NULL) { SETATTR(templ, i, CKA_PRIME_1, - rawkey->rawdata.rsa.prime1.val, - rawkey->rawdata.rsa.prime1.len); + rawkey->rawdata.rsa.prime1.val, + rawkey->rawdata.rsa.prime1.len); i++; } if (rawkey->rawdata.rsa.prime2.val != NULL) { SETATTR(templ, i, CKA_PRIME_2, - rawkey->rawdata.rsa.prime2.val, - rawkey->rawdata.rsa.prime2.len); + rawkey->rawdata.rsa.prime2.val, + rawkey->rawdata.rsa.prime2.len); i++; } if (rawkey->rawdata.rsa.exp1.val != NULL) { SETATTR(templ, i, CKA_EXPONENT_1, - rawkey->rawdata.rsa.exp1.val, - rawkey->rawdata.rsa.exp1.len); + rawkey->rawdata.rsa.exp1.val, + rawkey->rawdata.rsa.exp1.len); i++; } if (rawkey->rawdata.rsa.exp2.val != NULL) { SETATTR(templ, i, CKA_EXPONENT_2, - rawkey->rawdata.rsa.exp2.val, - rawkey->rawdata.rsa.exp2.len); + rawkey->rawdata.rsa.exp2.val, + rawkey->rawdata.rsa.exp2.len); i++; } if (rawkey->rawdata.rsa.coef.val != NULL) { SETATTR(templ, i, CKA_COEFFICIENT, - rawkey->rawdata.rsa.coef.val, - rawkey->rawdata.rsa.coef.len); + rawkey->rawdata.rsa.coef.val, + rawkey->rawdata.rsa.coef.len); i++; } } else { SETATTR(templ, i, CKA_PRIME, - rawkey->rawdata.dsa.prime.val, - rawkey->rawdata.dsa.prime.len); + rawkey->rawdata.dsa.prime.val, + rawkey->rawdata.dsa.prime.len); i++; SETATTR(templ, i, CKA_SUBPRIME, - rawkey->rawdata.dsa.subprime.val, - rawkey->rawdata.dsa.subprime.len); + rawkey->rawdata.dsa.subprime.val, + rawkey->rawdata.dsa.subprime.len); i++; SETATTR(templ, i, CKA_BASE, - rawkey->rawdata.dsa.base.val, - rawkey->rawdata.dsa.base.len); + rawkey->rawdata.dsa.base.val, + rawkey->rawdata.dsa.base.len); i++; SETATTR(templ, i, CKA_VALUE, - rawkey->rawdata.dsa.value.val, - rawkey->rawdata.dsa.value.len); + rawkey->rawdata.dsa.value.val, + rawkey->rawdata.dsa.value.len); i++; } @@ -2770,17 +3035,17 @@ KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, rv = KMF_ERR_INTERNAL; } cleanup: - KMF_FreeData(&id); - KMF_FreeData(&subject); - KMF_FreeSignedCert(x509); + kmf_free_data(&id); + kmf_free_data(&subject); + kmf_free_signed_cert(x509); free(x509); return (rv); } KMF_RETURN -KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, - KMF_KEY_HANDLE *symkey) +KMFPK11_CreateSymKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -2794,7 +3059,17 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, CK_BBOOL true = TRUE; CK_BBOOL false = FALSE; CK_ATTRIBUTE templ[15]; - int i; + CK_BYTE *keydata = NULL; + int i = 0; + KMF_KEY_HANDLE *symkey; + KMF_KEY_ALG keytype; + uint32_t keylen = 0; + uint32_t attrkeylen = 0; + uint32_t keylen_size = sizeof (uint32_t); + char *keylabel = NULL; + KMF_CREDENTIAL cred; + uint32_t is_sensitive = B_FALSE; + uint32_t is_not_extractable = B_FALSE; if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); @@ -2802,8 +3077,29 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL) + symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (symkey == NULL) return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + if (keylabel == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr, + (void *)&is_sensitive, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr, + (void *)&is_not_extractable, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + /* * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key. * @@ -2811,68 +3107,115 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, * C_GenerateKey() for some PKCS11 providers, we will handle it * differently. */ - if (params->keytype == KMF_GENERIC_SECRET) { - rv = create_generic_secret_key(handle, params, &keyhandle); + if (keytype == KMF_GENERIC_SECRET) { + rv = create_generic_secret_key(handle, numattr, + attrlist, &keyhandle); if (rv != KMF_OK) goto out; else goto setup; } + rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr, + NULL, &attrkeylen); + if (rv == KMF_OK && attrkeylen > 0) { + keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist, + numattr); + } else { + keydata = NULL; + attrkeylen = 0; + rv = KMF_OK; + } + if (keydata != NULL) { + if (keytype == KMF_DES && attrkeylen != 8) { + rv = KMF_ERR_BAD_KEY_SIZE; + goto out; + } + if (keytype == KMF_DES3 && attrkeylen != 24) { + rv = KMF_ERR_BAD_KEY_SIZE; + goto out; + } + /* + * This may override what the user gave on the + * command line. + */ + keylen = attrkeylen * 8; /* bytes to bits */ + } else { + /* + * If keydata was not given, key length must be + * provided. + */ + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, + &keylen, &keylen_size); + if (rv == KMF_ERR_ATTR_NOT_FOUND && + (keytype == KMF_DES || keytype == KMF_DES3)) + /* keylength is not required for DES and 3DES */ + rv = KMF_OK; + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + } + + if ((keylen % 8) != 0) { + return (KMF_ERR_BAD_KEY_SIZE); + } + secKeyLen = keylen / 8; /* in bytes for RC4/AES */ + + /* + * Only set CKA_VALUE_LEN if the key data was not given and + * we are creating an RC4 or AES key. + */ + if (keydata == NULL && + (keytype == KMF_AES || keytype == KMF_RC4)) { + SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen, + sizeof (secKeyLen)); + i++; + } + /* Other keytypes */ keyGenMech.pParameter = NULL_PTR; keyGenMech.ulParameterLen = 0; - switch (params->keytype) { - case KMF_AES: - keyGenMech.mechanism = CKM_AES_KEY_GEN; - secKeyType = CKK_AES; - break; - case KMF_RC4: - keyGenMech.mechanism = CKM_RC4_KEY_GEN; - secKeyType = CKK_RC4; - break; - case KMF_DES: - keyGenMech.mechanism = CKM_DES_KEY_GEN; - secKeyType = CKK_DES; - break; - case KMF_DES3: - keyGenMech.mechanism = CKM_DES3_KEY_GEN; - secKeyType = CKK_DES3; - break; - default: - return (KMF_ERR_BAD_KEY_TYPE); + switch (keytype) { + case KMF_AES: + keyGenMech.mechanism = CKM_AES_KEY_GEN; + secKeyType = CKK_AES; + break; + case KMF_RC4: + keyGenMech.mechanism = CKM_RC4_KEY_GEN; + secKeyType = CKK_RC4; + break; + case KMF_DES: + keyGenMech.mechanism = CKM_DES_KEY_GEN; + secKeyType = CKK_DES; + break; + case KMF_DES3: + keyGenMech.mechanism = CKM_DES3_KEY_GEN; + secKeyType = CKK_DES3; + break; + default: + return (KMF_ERR_BAD_KEY_TYPE); + } + if (keydata != NULL) { + SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen); + i++; } - - i = 0; SETATTR(templ, i, CKA_CLASS, &class, sizeof (class)); i++; SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType)); i++; - if (params->keytype == KMF_AES || params->keytype == KMF_RC4) { - if ((params->keylength % 8) != 0) { - return (KMF_ERR_BAD_KEY_SIZE); - } - secKeyLen = params->keylength/8; /* in bytes for RC4/AES */ - SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen, - sizeof (secKeyLen)); + if (keylabel != NULL) { + SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); i++; } - if (params->keylabel != NULL) { - SETATTR(templ, i, CKA_LABEL, params->keylabel, - strlen(params->keylabel)); - i++; - } - - if (params->pkcs11parms.sensitive == B_TRUE) { + if (is_sensitive == B_TRUE) { SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); } else { SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); } i++; - if (params->pkcs11parms.not_extractable == B_TRUE) { + if (is_not_extractable == B_TRUE) { SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); } else { SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); @@ -2892,12 +3235,23 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true)); i++; - rv = pk11_authenticate(handle, ¶ms->cred); + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = pk11_authenticate(handle, &cred); if (rv != KMF_OK) { return (rv); } - ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i, &keyhandle); + /* If the key data was given, use C_CreateObject */ + if (keydata != NULL) { + ckrv = C_CreateObject(hSession, templ, i, &keyhandle); + } else { + ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i, + &keyhandle); + } if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_KEYGEN_FAILED; @@ -2906,7 +3260,7 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, setup: symkey->kstype = KMF_KEYSTORE_PK11TOKEN; - symkey->keyalg = params->keytype; + symkey->keyalg = keytype; symkey->keyclass = KMF_SYMMETRIC; symkey->israw = FALSE; symkey->keyp = (void *)keyhandle; @@ -2915,7 +3269,6 @@ out: return (rv); } - KMF_RETURN KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, KMF_RAW_SYM_KEY *rkey) @@ -2934,19 +3287,29 @@ KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, else if (symkey->keyclass != KMF_SYMMETRIC) return (KMF_ERR_BAD_KEY_CLASS); + /* + * If the key is already in "raw" format, copy the data + * to the new record if possible. + */ if (symkey->israw) { KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp; - if (rawkey == NULL || - rawkey->rawdata.sym.keydata.val == NULL || - rawkey->rawdata.sym.keydata.len == 0) + if (rawkey == NULL) return (KMF_ERR_BAD_KEYHANDLE); + if (rawkey->sensitive) + return (KMF_ERR_SENSITIVE_KEY); + if (rawkey->not_extractable) + return (KMF_ERR_UNEXTRACTABLE_KEY); + + if (rawkey->rawdata.sym.keydata.val == NULL || + rawkey->rawdata.sym.keydata.len == 0) + return (KMF_ERR_GETKEYVALUE_FAILED); rkey->keydata.len = rawkey->rawdata.sym.keydata.len; if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) return (KMF_ERR_MEMORY); (void) memcpy(rkey->keydata.val, - rawkey->rawdata.sym.keydata.val, rkey->keydata.len); + rawkey->rawdata.sym.keydata.val, rkey->keydata.len); } else { rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey); } @@ -2955,20 +3318,50 @@ KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, } KMF_RETURN -KMFPK11_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, - KMF_CREDENTIAL *newpin) +KMFPK11_SetTokenPin(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; CK_RV rv = CKR_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; CK_SESSION_HANDLE session = NULL; + KMF_CREDENTIAL oldcred = {NULL, 0}; + KMF_CREDENTIAL newcred = {NULL, 0}; + CK_SLOT_ID slotid; + + if (handle == NULL || attrlist == NULL || numattr == 0) + return (KMF_ERR_BAD_PARAMETER); - if (handle == NULL || params == NULL || newpin == NULL) + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&oldcred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_NEWPIN_ATTR, attrlist, numattr, + (void *)&newcred, NULL); + if (rv != KMF_OK) return (KMF_ERR_BAD_PARAMETER); - rv = C_OpenSession(params->pkcs11parms.slot, - CKF_SERIAL_SESSION | CKF_RW_SESSION, - NULL, NULL, &session); + rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr, + (void *)&slotid, NULL); + if (rv != KMF_OK) { + char *tokenlabel = NULL; + /* + * If a slot wasn't given, the user must pass + * a token label so we can find the slot here. + */ + rv = kmf_get_string_attr(KMF_TOKEN_LABEL_ATTR, attrlist, + numattr, &tokenlabel); + if (rv != KMF_OK) + return (rv); + + rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid); + if (rv != KMF_OK) + return (rv); + } + + rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION, + NULL, NULL, &session); if (rv != CKR_OK) { SET_ERROR(kmfh, rv); ret = KMF_ERR_UNINITIALIZED; @@ -2976,8 +3369,8 @@ KMFPK11_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, } rv = C_SetPIN(session, - (CK_BYTE *)params->cred.cred, params->cred.credlen, - (CK_BYTE *)newpin->cred, newpin->credlen); + (CK_BYTE *)oldcred.cred, oldcred.credlen, + (CK_BYTE *)newcred.cred, newcred.credlen); if (rv != CKR_OK) { SET_ERROR(kmfh, rv); @@ -3007,8 +3400,7 @@ create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech, int i; rv = C_Initialize(NULL); - if ((rv != CKR_OK) && - (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { + if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { kmf_rv = KMF_ERR_UNINITIALIZED; goto out; } @@ -3038,7 +3430,7 @@ create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech, } if (i < pulCount) { rv = C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION, - NULL, NULL, sessionp); + NULL, NULL, sessionp); if (rv != CKR_OK) { kmf_rv = KMF_ERR_UNINITIALIZED; @@ -3072,20 +3464,20 @@ verify_data(KMF_HANDLE_T handle, if (AlgorithmId == KMF_ALGID_NONE) return (KMF_ERR_BAD_ALGORITHM); - pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, - AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); + pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, + AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); if (!pAlgMap) return (KMF_ERR_BAD_ALGORITHM); ret = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism, - CKF_VERIFY); + CKF_VERIFY); if (ret != KMF_OK) return (ret); /* Fetch the verifying key */ ret = PKCS_AcquirePublicKeyHandle(ckSession, keyp, - pAlgMap->key_type, &ckKeyHandle, &bTempKey); + pAlgMap->key_type, &ckKeyHandle, &bTempKey); if (ret != KMF_OK) { return (ret); @@ -3104,11 +3496,9 @@ verify_data(KMF_HANDLE_T handle, goto cleanup; } - ckRv = C_Verify(ckSession, - (CK_BYTE *)data->Data, - (CK_ULONG)data->Length, - (CK_BYTE *)signed_data->Data, - (CK_ULONG)signed_data->Length); + ckRv = C_Verify(ckSession, (CK_BYTE *)data->Data, + (CK_ULONG)data->Length, (CK_BYTE *)signed_data->Data, + (CK_ULONG)signed_data->Length); if (ckRv != CKR_OK) { SET_ERROR(kmfh, ckRv); @@ -3150,7 +3540,7 @@ KMFPK11_VerifyDataWithCert(KMF_HANDLE_T handle, /* If no algorithm specified, use the certs signature algorithm */ if (algid == KMF_ALGID_NONE) { - algid = X509_AlgorithmOidToAlgId(CERT_ALG_OID(SignerCert)); + algid = x509_algoid_to_algid(CERT_ALG_OID(SignerCert)); } if (algid == KMF_ALGID_NONE) { @@ -3161,7 +3551,7 @@ KMFPK11_VerifyDataWithCert(KMF_HANDLE_T handle, cleanup: if (SignerCert) { - KMF_FreeSignedCert(SignerCert); + kmf_free_signed_cert(SignerCert); free(SignerCert); } @@ -3170,7 +3560,7 @@ cleanup: static KMF_RETURN create_generic_secret_key(KMF_HANDLE_T handle, - KMF_CREATESYMKEY_PARAMS *params, CK_OBJECT_HANDLE *key) + int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -3185,45 +3575,90 @@ create_generic_secret_key(KMF_HANDLE_T handle, int i; int random_fd = -1; int nread; + int freebuf = 0; char *buf = NULL; + uint32_t keylen = 0, attrkeylen = 0; + char *keylabel = NULL; + KMF_CREDENTIAL *cred; + uint32_t is_sensitive, is_not_extractable; - /* - * Check the key size. - */ - if ((params->keylength % 8) != 0) { - return (KMF_ERR_BAD_KEY_SIZE); + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + if (keylabel == NULL) + return (KMF_ERR_BAD_PARAMETER); + + cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); + if (cred == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr, + (void *)&is_sensitive, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr, + (void *)&is_not_extractable, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr, + NULL, &attrkeylen); + if (rv == KMF_OK && attrkeylen > 0) { + buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist, + numattr); + secKeyLen = attrkeylen; } else { - secKeyLen = params->keylength/8; /* in bytes */ + buf = NULL; + rv = KMF_OK; } + if (buf == NULL) { + /* + * If the key data was not given, key length must + * be provided. + */ + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, + &keylen, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); - /* - * Generate a random number with the key size first. - */ - buf = malloc(secKeyLen); - if (buf == NULL) - return (KMF_ERR_MEMORY); + /* + * Check the key size. + */ + if ((keylen % 8) != 0) { + return (KMF_ERR_BAD_KEY_SIZE); + } else { + secKeyLen = keylen/8; /* in bytes */ + } - while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) { - if (errno != EINTR) - break; - } + /* + * Generate a random number with the key size first. + */ + buf = malloc(secKeyLen); + if (buf == NULL) + return (KMF_ERR_MEMORY); - if (random_fd < 0) { - rv = KMF_ERR_KEYGEN_FAILED; - goto out; - } + freebuf = 1; + while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) { + if (errno != EINTR) + break; + } - nread = read(random_fd, buf, secKeyLen); - if (nread <= 0 || nread != secKeyLen) { - rv = KMF_ERR_KEYGEN_FAILED; - goto out; + if (random_fd < 0) { + rv = KMF_ERR_KEYGEN_FAILED; + goto out; + } + + nread = read(random_fd, buf, secKeyLen); + if (nread <= 0 || nread != secKeyLen) { + rv = KMF_ERR_KEYGEN_FAILED; + goto out; + } } /* * Authenticate into the token and call C_CreateObject to generate * a generic secret token key. */ - rv = pk11_authenticate(handle, ¶ms->cred); + rv = pk11_authenticate(handle, cred); if (rv != KMF_OK) { goto out; } @@ -3236,20 +3671,19 @@ create_generic_secret_key(KMF_HANDLE_T handle, SETATTR(templ, i, CKA_VALUE, buf, secKeyLen); i++; - if (params->keylabel != NULL) { - SETATTR(templ, i, CKA_LABEL, params->keylabel, - strlen(params->keylabel)); + if (keylabel != NULL) { + SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); i++; } - if (params->pkcs11parms.sensitive == B_TRUE) { + if (is_sensitive == B_TRUE) { SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); } else { SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); } i++; - if (params->pkcs11parms.not_extractable == B_TRUE) { + if (is_not_extractable == B_TRUE) { SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); } else { SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); @@ -3270,7 +3704,7 @@ create_generic_secret_key(KMF_HANDLE_T handle, } out: - if (buf != NULL) + if (buf != NULL && freebuf) free(buf); if (random_fd != -1) @@ -3278,3 +3712,241 @@ out: return (rv); } + +KMF_RETURN +KMFPK11_StoreKey(KMF_HANDLE_T handle, + int numattr, + KMF_ATTRIBUTE *attlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_CREDENTIAL cred = {NULL, 0}; + KMF_KEY_HANDLE *key; + KMF_RAW_KEY_DATA *rawkey; + CK_BBOOL btrue = TRUE; + CK_ATTRIBUTE tokenattr[1]; + CK_OBJECT_HANDLE newobj; + CK_RV ckrv; + + if (kmfh == NULL) + return (KMF_ERR_UNINITIALIZED); + + if (kmfh->pk11handle == CK_INVALID_HANDLE) + return (KMF_ERR_NO_TOKEN_SELECTED); + + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = pk11_authenticate(handle, &cred); + if (rv != KMF_OK) + return (rv); + + key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr); + if (key == NULL) { + key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, + numattr); + if (key == NULL) + rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist, + numattr); + } + if (key == NULL && rawkey == NULL) + return (KMF_ERR_ATTR_NOT_FOUND); + + if (rawkey != NULL) { + rv = store_raw_key(handle, attlist, numattr, rawkey); + } else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) { + + SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue)); + /* Copy the key object to the token */ + ckrv = C_CopyObject(kmfh->pk11handle, + (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj); + if (ckrv != CKR_OK) { + SET_ERROR(kmfh, ckrv); + return (KMF_ERR_INTERNAL); + } + + /* Replace the object handle with the new token-based one */ + ckrv = C_DestroyObject(kmfh->pk11handle, + (CK_OBJECT_HANDLE)key->keyp); + if (ckrv != CKR_OK) { + SET_ERROR(kmfh, ckrv); + return (KMF_ERR_INTERNAL); + } + key->keyp = (void *)newobj; + } else { + rv = KMF_ERR_BAD_PARAMETER; + } + + return (rv); +} + + +KMF_RETURN +KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_CREDENTIAL *cred = NULL; + KMF_CREDENTIAL *p12cred = NULL; + char *filename = NULL; + KMF_X509_DER_CERT *certlist = NULL; + KMF_KEY_HANDLE *keylist = NULL; + uint32_t numcerts; + uint32_t numkeys; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; + KMF_ATTRIBUTE fc_attrlist[16]; + int i; + + if (kmfh == NULL) + return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ + + if (kmfh->pk11handle == CK_INVALID_HANDLE) + return (KMF_ERR_NO_TOKEN_SELECTED); + + /* First get the required attributes */ + cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); + if (cred == NULL) + return (KMF_ERR_BAD_PARAMETER); + + p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); + if (p12cred == NULL) + return (KMF_ERR_BAD_PARAMETER); + + filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, + numattr); + if (filename == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* Find all the certificates that match the searching criteria */ + i = 0; + kmf_set_attr_at_index(fc_attrlist, i, + KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); + i++; + + kmf_set_attr_at_index(fc_attrlist, i, + KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t)); + i++; + + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + if (certlabel != NULL) { + kmf_set_attr_at_index(fc_attrlist, i, + KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); + i++; + } + + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + if (issuer != NULL) { + kmf_set_attr_at_index(fc_attrlist, i, + KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); + i++; + } + + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + if (subject != NULL) { + kmf_set_attr_at_index(fc_attrlist, i, + KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); + i++; + } + + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + if (serial != NULL) { + kmf_set_attr_at_index(fc_attrlist, i, + KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); + i++; + } + + rv = KMFPK11_FindCert(handle, i, fc_attrlist); + + if (rv == KMF_OK && numcerts > 0) { + certlist = (KMF_X509_DER_CERT *)malloc(numcerts * + sizeof (KMF_X509_DER_CERT)); + if (certlist == NULL) + return (KMF_ERR_MEMORY); + + (void) memset(certlist, 0, numcerts * + sizeof (KMF_X509_DER_CERT)); + + kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR, + certlist, sizeof (KMF_X509_DER_CERT)); + i++; + + rv = kmf_find_cert(handle, i, fc_attrlist); + if (rv != KMF_OK) { + free(certlist); + return (rv); + } + } else { + return (rv); + } + + /* For each certificate, find the matching private key */ + numkeys = 0; + for (i = 0; i < numcerts; i++) { + KMF_ATTRIBUTE fk_attrlist[16]; + int j = 0; + KMF_KEY_HANDLE newkey; + KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY; + + kmf_set_attr_at_index(fk_attrlist, j, + KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); + j++; + + kmf_set_attr_at_index(fk_attrlist, j, + KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); + j++; + + kmf_set_attr_at_index(fk_attrlist, j, + KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); + j++; + + kmf_set_attr_at_index(fk_attrlist, j, + KMF_CERT_DATA_ATTR, &certlist[i].certificate, + sizeof (KMF_DATA)); + j++; + + kmf_set_attr_at_index(fk_attrlist, j, + KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE)); + j++; + + rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist); + if (rv == KMF_OK) { + numkeys++; + keylist = realloc(keylist, + numkeys * sizeof (KMF_KEY_HANDLE)); + if (keylist == NULL) { + rv = KMF_ERR_MEMORY; + goto out; + } + keylist[numkeys - 1] = newkey; + } else if (rv == KMF_ERR_KEY_NOT_FOUND) { + /* it is OK if a key is not found */ + rv = KMF_OK; + } + } + + if (rv != KMF_OK) + goto out; + + rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist, + p12cred, filename); + +out: + if (certlist != NULL) { + for (i = 0; i < numcerts; i++) + kmf_free_kmf_cert(handle, &certlist[i]); + free(certlist); + } + if (keylist != NULL) { + for (i = 0; i < numkeys; i++) + kmf_free_kmf_key(handle, &keylist[i]); + free(keylist); + } + + return (rv); +} |