2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A /* Get the algorithm info from the signer certificate */ 2N/A * Name: kmf_find_prikey_by_cert 2N/A * This function finds the corresponding private key in keystore 2N/A * First, get the key algorithm info from the certificate and saves it 2N/A * in the returned key handle. 2N/A /* Call the plugin to do the work. */ 2N/A * If absent or error, the cert is assumed to be invalid 2N/A * for all key usage checking. 2N/A * The keyCertSign bit is asserted when the subject 2N/A * public key is used for verifying a signature on 2N/A * public key certificates. If the keyCertSign bit 2N/A * is asserted, then the cA bit in the basic constraints 2N/A * extension (section 4.2.1.10) MUST also be asserted. 2N/A * The basic constraints extension MUST appear as a 2N/A * critical extension in all CA certificates that 2N/A * contain public keys used to validate digital 2N/A * signatures on certificates. 2N/A * The digitalSignature bit is asserted when the subject 2N/A * public key is used with a digital signature mechanism 2N/A * to support security services other than certificate 2N/A * signing(bit 5), or CRL signing(bit 6). 2N/A * The dataEncipherment bit is asserted when the subject 2N/A * public key is used for enciphering user data, other than 2N/A * cryptographic keys. 2N/A * Validate that all required fields are present. 2N/A /* Pack the new certificate */ 2N/A * This function is used to setup the attribute list before calling 2N/A * kmf_find_prikey_by_cert(). This function is used by 2N/A * kmf_decrypt_with_cert 2N/A * The attribute list in these callers contain all the attributes 2N/A * needed by kmf_find_prikey_by_cert(), except the 2N/A * KMF_KEY_HANDLE attribute and the KMF_CERT_DATA_ATTR attribute. 2N/A * These 2 attributes need to be added or reset. 2N/A * The caller should free the new_attrlist after use it. 2N/A /* Create a new attribute list with 2 more elements */ 2N/A /* Copy the src_attrlist to the new list */ 2N/A /* Add or reset the key handle attribute */ 2N/A /* not found; add it */ 2N/A /* found; just reset it */ 2N/A /* add or reset the cert data attribute */ 2N/A /* not found; add it */ 2N/A /* found; just reset it */ 2N/A * Determine a default signature type to use based on 2N/A * the key algorithm. 2N/A /* NSS doesn't support DSA-SHA2 hashes yet */ 2N/A * This is to check to see if a certificate being signed has 2N/A * the keyCertSign KeyUsage bit set, and if so, make sure the 2N/A * "BasicConstraints" extension is also set accordingly. 2N/A /* If keyCertSign is set, look for basicConstraints */ 2N/A * If we got KMF_OK (or an error), then return 2N/A * because the extension is already present. We 2N/A * only want to continue with this function if 2N/A * the extension is NOT found. 2N/A * Don't limit the pathLen (for now). 2N/A * This should probably be a policy setting in the 2N/A * Decode the DER cert data into the internal 2N/A * X.509 structure we need to set extensions. 2N/A * Add the missing basic constraint. 2N/A /* Free the old cert data record */ 2N/A /* Re-encode the cert with the extension */ 2N/A * Name: kmf_sign_cert 2N/A * This function signs a certificate using the signer cert and 2N/A * returns a signed and DER-encoded certificate. 2N/A * The following types of certificate data can be submitted to be signed: 2N/A * KMF_TBS_CERT_DATA_ATTR - a KMF_DATA ptr is provided in the attrlist 2N/A * and is signed directly. 2N/A * KMF_X509_CERTIFICATE_ATTR - a KMF_X509_CERTIFICATE record is provided 2N/A * in the attribute list. This is converted to raw KMF_DATA 2N/A * The key for the signing operation can be provided as a KMF_KEY_HANDLE_ATTR 2N/A * or the caller may choose to provide a KMF_SIGNER_CERT_ATTR (KMF_DATA *). 2N/A * If the latter, this function will then attempt to find the private key 2N/A * associated with the certificate. The private key must be stored in 2N/A * the same keystore as the signer certificate. 2N/A /* Get the signer cert and check its keyUsage */ 2N/A * Only accept 1 or the other, not both. 2N/A * If the signature OID was not given, check 2N/A * for an algorithm index identifier instead. 2N/A * Find the private key from the signer certificate by calling 2N/A * kmf_find_prikey_by_cert(). 2N/A * Check for the keyCertSign bit in the KeyUsage extn. If it is set, 2N/A * then the basicConstraints must also be present and be 2N/A * If OID is not known yet, use a default value 2N/A * based on the signers key type. 2N/A /* If we had to find the key, free it here. */ 2N/A * Name: kmf_sign_data 2N/A * This function signs a block of data using the signer cert and 2N/A * returns the the signature in output 2N/A /* Get the signer cert and check its keyUsage. */ 2N/A * If a signer cert was given, use it to find the private key 2N/A * to use for signing the data. 2N/A * Signing generic data does not require the 2N/A * KeyUsage extension. 2N/A * Find the private key from the signer certificate. 2N/A /* Get the tbs_data and signed_data attributes now */ 2N/A * Get the algorithm index attribute and its oid. If this attribute 2N/A * is not provided, then we use a default value. 2N/A /* If there was no Algorithm ID, use default based on key */ 2N/A /* Now call the plugin function to sign it */ 2N/A * For DSA, NSS returns an encoded signature. Decode the 2N/A * signature and expect a 40-byte DSA signature. 2N/A * This routine will try to verify a block of data using 2N/A * either a public key or a certificate as the source 2N/A * of the verification (the key). 2N/A * The caller may provider either a KMF_KEY_HANDLE_ATTR or 2N/A * a KMF_SIGNER_CERT_DATA_ATTR (with a KMF_DATA record) to 2N/A * use for the key to the verification step. If a certificate 2N/A * is used and that certificate has the KeyUsage extension, 2N/A * the SIGN-DATA bit must be set. Also, if a certificate 2N/A * is used, the verification will be done in a specific 2N/A * keystore mechanism. 2N/A * If a KMF_KEY_HANDLE is given in the attribute list, the 2N/A * verification will occur in the framework itself using 2N/A * PKCS#11 C_Verify functions. 2N/A /* kstype is only needed if the signer cert is not present */ 2N/A /* We only need the algorithm index if we don't have a signer cert. */ 2N/A /* If the caller passed a signer cert instead of a key use it. */ 2N/A /* Decode the signer cert so we can get the SPKI data */ 2N/A /* If no algorithm specified, use the certs signature alg */ 2N/A * Verify the data locally (i.e. using PKCS#11). 2N/A * The verify operation uses a public key and does not 2N/A * require access to a specific keystore. Save time 2N/A * (and code) by just using the frameworks implementation 2N/A * of the verify operation using crypto framework 2N/A /* Retrieve public key data from keystore */ 2N/A * Name: kmf_verify_cert 2N/A * This function verifies that the a certificate was signed 2N/A * using a specific private key and that the certificate has not 2N/A * been altered since it was signed using that private key 2N/A * The public key used for verification may be given in the 2N/A * attribute list as a KMF_KEY_HANDLE or the caller may give 2N/A * just the signing certificate (as KMF_SIGNER_CERT_DATA_ATTR) 2N/A * from which the public key needed for verification can be 2N/A * handle(input) - opaque handle for KMF session 2N/A * numattr - number of attributes in the list 2N/A * attrlist - KMF_ATTRIBUTES 2N/A * A KMF_RETURN value indicating success or specifying a particular 2N/A * error condition. The value KMF_OK indicates success. All other 2N/A * values represent an error condition. 2N/A * Caller must provide at least a key handle or a cert to use 2N/A * as the "key" for verification. 2N/A * The keystore must extract the pubkey data because 2N/A * the framework doesn't have access to the raw key bytes 2N/A * that are needed to construct the DER encoded public 2N/A * key information needed for the verify operation. 2N/A * Uses the public key from the cert to encrypt the plaintext 2N/A * into the ciphertext. 2N/A * handle(input) - opaque handle for KMF session 2N/A * cert(input) - pointer to a DER encoded certificate for encryption 2N/A * by using its public key 2N/A * plaintext(input) - pointer to the plaintext to be encrypted 2N/A * ciphertext(output) - pointer to the ciphertext contains 2N/A * A KMF_RETURN value indicating success or specifying a particular 2N/A * The value KMF_OK indicates success. All other values represent 2N/A * an error condition. 2N/A /* check the keyUsage of the certificate */ 2N/A /* Decode the cert so we can get the SPKI data */ 2N/A /* Get the public key info from the certificate */ 2N/A /* Use the algorithm in SPKI to encrypt data */ 2N/A /* [EC]DSA does not support encrypt */ 2N/A * Encrypt using the crypto framework (not the KMF plugin mechanism). 2N/A * Uses the private key associated with the cert to decrypt 2N/A * the ciphertext into the plaintext. 2N/A /* Get the cert and check its keyUsage */ 2N/A /* check the keyUsage of the certificate */ 2N/A /* Get the ciphertext and plaintext attributes */ 2N/A * Retrieve the private key from the keystore based on 2N/A /* Decode the cert so we can get the alogorithm */ 2N/A /* [EC]DSA does not support decrypt */ 2N/A * This function gets the CRL URI entries from the certificate's Distribution 2N/A * points extension, and downloads the CRL file. The function also returns 2N/A * the URI string and the format of the CRL file. The caller should free 2N/A * the space allocated for the returned URI string. 2N/A /* Get the proxy info */ 2N/A * Get the CRL URI from the certificate's CRL Distribution 2N/A * Points extension and download the CRL file. There maybe more than 2N/A * one CRL URI entries in the DP extension, so we will continue 2N/A * the process until a CRL file is successfully downloaded or we 2N/A * are running out the CRL URI's. 2N/A * NSS CRL is not file based, and its signature 2N/A * has been verified during CRL import. 2N/A * We only check CRL validity for file-based CRLs, 2N/A * NSS handles these checks internally. 2N/A * Check the CRL signature if needed. 2N/A * Check the CRL validity if needed. 2N/A * If the get-crl-uri policy is TRUE, then download the CRL 2N/A * file first. The newly downloaded file will be stored in the 2N/A * NSS internal database for NSS keystore, and stored in a file for 2N/A * the File-based CRL plugins (OpenSSL and PKCS11). 2N/A * For file-based plugins, if the get-crl-uri policy is FALSE, 2N/A * then the caller should provide a CRL file in the policy. 2N/A * Also, after this step is done, the "crlfilename" variable should 2N/A * contain the proper CRL file to be used for the rest of CRL 2N/A * validation process. 2N/A * Check to see if we already have this CRL. 2N/A * If this file already exists and is valid, we don't need to 2N/A * download a new one. 2N/A * Create a temporary file to hold the new CRL file initially. 2N/A * Get the URI entry from the certificate's CRL distribution 2N/A * points extension and download the CRL file. 2N/A * If we just downloaded one, make sure it is OK. 2N/A /* Cache the CRL file. */ 2N/A * For NSS keystore, import this CRL file into th 2N/A * internal database. 2N/A * If the get_crl_uri policy is FALSE, for File-based CRL 2N/A * plugins, get the input CRL file from the policy. 2N/A * Make sure this CRL is still valid. 2N/A * Check the CRL revocation for the certificate. 2N/A * Create temporary file to hold the user certificate. 2N/A * Get the response lifetime from policy. 2N/A * Get the ignore_response_sign policy. 2N/A * If ignore_response_sign is FALSE, we need to verify the response. 2N/A * Find the OCSP Responder certificate if it is specified in the OCSP 2N/A * If the caller provides an OCSP response, we will use it directly. 2N/A * Otherwise, we will try to fetch an OCSP response for the given 2N/A * Process the OCSP response and retrieve the certificate status. 2N/A /* keyusage is not set in cert but is set in policy */ 2N/A /* no keyusage set in both cert and policy */ 2N/A * Rule: if the KU bit is set in policy, the corresponding KU bit 2N/A * must be set in the certificate (but not vice versa). 2N/A * If the policy does not have any EKU, then there is 2N/A * nothing further to check. 2N/A * Build the EKU bitmap based on the certificate 2N/A * Build the EKU bitmap based on the policy 2N/A * Rule: if the EKU OID is set in policy, the corresponding EKU OID 2N/A * must be set in the certificate (but not vice versa). 2N/A /* only one issuer cert is found */ 2N/A * More than one issuer certs are found. We will 2N/A * pick the latest one. 2N/A /* Get the TA name and serial number from the policy */ 2N/A * Use name and serial from policy. 2N/A /* set up fc_attrlist for kmf_find_cert */ 2N/A * The found TA's name must be matching with issuer name in 2N/A * subscriber's certificate. 2N/A /* Make sure the TA cert has the correct extensions */ 2N/A /* Get the attribute values */ 2N/A /* Initialize the returned result */ 2N/A * Get the issuer information from the input certificate first. 2N/A * Check if the certificate is a self-signed cert. 2N/A * this is a self-signed cert 2N/A * Check KeyUsage extension of the subscriber's certificate 2N/A * Validate Extended KeyUsage extension 2N/A * Check the certificate's validity period 2N/A * This step is needed when "ignore_date" in policy is set 2N/A * Validate expiration date 2N/A * When "ignore_trust_anchor" in policy is set to FALSE, 2N/A * we will try to find the TA cert based on the TA policy 2N/A * TA's subject name (ta_name) and serial number (ta_serial) 2N/A * are defined as optional attributes in policy dtd, but they 2N/A * should exist in policy when "ignore_trust_anchor" is set 2N/A * to FALSE. The policy verification code has enforced that. 2N/A * The serial number may be NULL if the ta_name == "search" 2N/A * which indicates that KMF should try to locate the issuer 2N/A * of the subject cert instead of using a specific TA name. 2N/A * Verify the signature of subscriber's certificate using 2N/A * If we didnt find the user_issuer string, we 2N/A * won't have a "user_issuerDN" either. 2N/A /* Only verify if we got the TA without an error. */ 2N/A /* No issuer was found, so we cannot find a trust anchor */ 2N/A * Check certificate revocation 2N/A /* skip revocation checking */ 2N/A * When CRL or OCSP revocation method is set in the policy, 2N/A * we will try to find the issuer of the subscriber certificate 2N/A * using the issuer name of the subscriber certificate. The 2N/A * issuer certificate will be used to do the CRL checking 2N/A * and OCSP checking. 2N/A * If we did not find the issuer cert earlier 2N/A * (when policy->ta_name == "search"), get it here. 2N/A * We need the issuer cert if the revocation method is 2N/A * If we did not copy ta_cert to issuer_cert, free it. 2N/A * If we got an error flag from any of the checks, 2N/A * remap the return code to a generic "CERT_VALIDATION" 2N/A * error so the caller knows to check the individual flags. 2N/A * Determine if a KMF_DATA buffer contains an encoded X.509 certificate. 2N/A * KMF_OK if it is a certificate 2N/A * KMF_ERR_ENCODING (or other error) if not. 2N/A /* Convert to ASN.1 DER first */ 2N/A * This function checks the validity period of a der-encoded certificate. 2N/A * Get the current time. The time returned from time() is local which 2N/A * cannot be used directly. It must be converted to UTC/GMT first. 2N/A * Adjust the validity time 2N/A "openssl_build_pk12");
2N/A * Use the Keypair reader from the OpenSSL plugin. 2N/A "openssl_import_objects");
2N/A /* Use OpenSSL interfaces to get raw key and cert data */ 2N/A * Shortcut - just extract the already encoded TBS cert data from 2N/A * the original data buffer. Since we haven't changed anything, 2N/A * there is no need to re-encode it. 2N/A /* Estimate the signed data length generously */ 2N/A * If we got here OK, decode into a structure and then re-encode 2N/A * the complete certificate. 2N/A /* We are re-signing this cert, so clear out old signature data */ 2N/A /* Free the previous "data to be signed" block */ 2N/A * We changed the cert (updated the signature OID), so we 2N/A * need to re-encode it so the correct data gets signed. 2N/A /* ASN.1 encode ECDSA signature */ 2N/A * For DSA, kmf_sign_data() returns a 40-byte 2N/A * signature. We must encode the signature correctly. 2N/A /* Now, re-encode the cert with the new signature */ 2N/A /* Cleanup & return */ 2N/A /* check the caller and do other setup for this SPI call */ 2N/A /* Decode the signer cert so we can get the Algorithm data */ 2N/A * Use a signer cert to verify another certificate's signature. 2N/A * This code forces the use of the PKCS11 mechanism for the verify 2N/A * operation for the Cryptographic Framework's FIPS-140 boundary. 2N/A /* Make sure the signer has proper key usage bits */ 2N/A /* Decode the cert into parts for verification */ 2N/A /* Decode the to-be-verified cert so we know what algorithm to use */ 2N/A * required for the Cryptographic Framework's FIPS-140 boundary.