certgetsetop.c revision 2
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) 2008, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A * Given a block of DER encoded X.509 certificate data and 2N/A * an OID for the desired extension, this routine will 2N/A * parse the cert data and return the data associated with 2N/A * the extension if it is found. 2N/A * KMF_OK - if extension found and copied OK. 2N/A * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. 2N/A * parsing and memory allocation errors are also possible. 2N/A * Given a block of DER encoded X.509 certificate data and 2N/A * return the OIDs for critical, non-critical or all extensions. 2N/A * KMF_OK - if extension found and copied OK. 2N/A * parsing and memory allocation errors are also possible. 2N/A * OIDlist - array of KMF_OID records, allocated 2N/A * NumOIDs - number of critical extensions found. 2N/A * If the flag is not all, then it is possible that we did not find 2N/A * any critical or non_critical extensions. When that happened, 2N/A * return KMF_ERR_EXTENSION_NOT_FOUND. 2N/A * If the given certificate data (X.509 DER encoded data) 2N/A * contains the Key Usage extension, parse that 2N/A * data and return it in the KMF_X509EXT_BASICCONSTRAINTS 2N/A * KMF_ERR_BAD_PARAMETER - input data was bad. 2N/A * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. 2N/A * Check standard KeyUsage bits 2N/A * Decode the ASN.1 data for the extension. 2N/A * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation 2N/A * Count the number of EKU OIDs and store in 2N/A /* Skip over the CONSTRUCTED SET tag */ 2N/A * If the given certificate data (X.509 DER encoded data) 2N/A * contains the Basic Constraints extension, parse that 2N/A * data and return it in the KMF_X509EXT_BASICCONSTRAINTS 2N/A * KMF_ERR_BAD_PARAMETER - input data was bad. 2N/A * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. 2N/A * Policy Qualifiers may be a list of sequences. 2N/A * PolicyInformation ::= SEQUENCE { 2N/A * policyIdentifier CertPolicyId, 2N/A * policyQualifiers SEQUENCE SIZE (1..MAX) OF 2N/A * PolicyQualifierInfo OPTIONAL 2N/A * PolicyQualifierInfo ::= SEQUENCE { 2N/A * policyQualifierId PolicyQualifierId, 2N/A * qualifier ANY DEFINED BY policyQualifierId 2N/A * We already got the CertPolicyId, we just need to 2N/A * find all of the policyQualifiers in the set. 2N/A * Mark the first element of the SEQUENCE and reset the end ptr 2N/A * so the ber/der code knows when to stop looking. 2N/A /* We found a sequence, loop until done */ 2N/A /* Skip over the CONSTRUCTED SET tag */ 2N/A * Allocate memory for the Policy Qualifier Info 2N/A * Read the PolicyQualifier OID 2N/A * The OID of the policyQualifierId determines what 2N/A * sort of data comes next. 2N/A * CPS uri must be an IA5STRING 2N/A * For now, just copy the while UserNotice ASN.1 2N/A * blob into the pqinfo data record. 2N/A * TBD - parse it into individual fields. 2N/A * If the given certificate data (X.509 DER encoded data) 2N/A * contains the Certificate Policies extension, parse that 2N/A * data and return it in the KMF_X509EXT_CERT_POLICIES 2N/A * KMF_ERR_BAD_PARAMETER - input data was bad. 2N/A * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. 2N/A * parsing and memory allocation errors are also possible. 2N/A * Decode the ASN.1 data for the extension. 2N/A * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation 2N/A * Collect all of the PolicyInformation SEQUENCES 2N/A * PolicyInformation ::= SEQUENCE { 2N/A * policyIdentifier CertPolicyId, 2N/A * policyQualifiers SEQUENCE SIZE (1..MAX) OF 2N/A * PolicyQualifierInfo OPTIONAL 2N/A * Loop over the SEQUENCES of PolicyInfo 2N/A /* Skip over the CONSTRUCTED SET tag */ 2N/A * Decode the PolicyInformation SEQUENCE 2N/A * Gather all of the associated PolicyQualifierInfo recs 2N/A * If the given certificate data (X.509 DER encoded data) 2N/A * contains the Authority Information Access extension, parse that 2N/A * data and return it in the KMF_X509EXT_AUTHINFOACCESS 2N/A * KMF_ERR_BAD_PARAMETER - input data was bad. 2N/A * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. 2N/A * Decode the ASN.1 data for the extension. 2N/A * AuthorityInfoAccessSyntax ::= 2N/A * SEQUENCE SIZE (1..MAX) OF AccessDescription 2N/A * AccessDescription ::= SEQUENCE { 2N/A * accessMethod OBJECT IDENTIFIER, 2N/A * accessLocation GeneralName } 2N/A /* Skip over the CONSTRUCTED SET tag */ 2N/A * Read the AccessMethod OID 2N/A * The OID of the AccessMethod determines what 2N/A * sort of data comes next. 2N/A * OCSP uri must be an IA5STRING or a GENNAME_URI 2N/A * with an implicit tag. 2N/A /* will be supported later with PKIX */ 2N/A * This function parses the name portion of a der-encoded distribution point 2N/A * returns it in the KMF_CRL_DIST_POINT record. 2N/A * The "DistributionPointName" syntax is 2N/A * DistributionPointName ::= CHOICE { 2N/A * fullName [0] GeneralNames, 2N/A * nameRelativeToCRLIssuer [1] RelativeDistinguishedName } 2N/A * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GerneralName 2N/A * Note: for phase 1, we support fullName only. 2N/A if (
tag ==
0xA0) {
/* fullName */ 2N/A /* Skip over the explicit tag and size */ 2N/A /* For phase 1, we are interested in a URI name only */ 2N/A /* Skip type and len, then read url and save it. */ 2N/A /* "nameRelativeToCRLIssuer" is not supported at phase 1. */ 2N/A * This function retrieves the CRL Distribution Points extension data from 2N/A * a DER encoded certificate if it contains this extension, parses the 2N/A * extension data, and returns it in the KMF_X509EXT_CRLDISTPOINTS record. 2N/A /* Get the ASN.1 data for this extension. */ 2N/A * Decode the CRLDistributionPoints ASN.1 data. The Syntax for 2N/A * CRLDistributionPoints is 2N/A * CRLDistributionPoints ::= 2N/A * SEQUENCE SIZE (1..MAX) OF DistributionPoint 2N/A * DistributionPoint ::= SEQUENCE { 2N/A * distributionPoint [0] DistributionPointName OPTIONAL, 2N/A * reasons [1] ReasonFlags OPTIONAL, 2N/A * cRLIssuer [2] GeneralNames OPTIONAL } 2N/A /* Skip over the CONSTRUCTED SET tag */ 2N/A if (
tag ==
0xA0) {
/* distributionPoint Name */ 2N/A if (
tag ==
0XA1) {
/* reasons */ 2N/A if (
tag ==
0XA2) {
/* cRLIssuer */ 2N/A /* For cRLIssuer, read the data only at phase 1 */ 2N/A /* A distribution point cannot have a "reasons" field only. */ 2N/A * Although it is legal that a distribution point contains 2N/A * a cRLIssuer field only, with or without "reasons", we will 2N/A * skip it if the name field is not presented for phase 1. 2N/A /* free the dp itself since we just used its contents */ 2N/A * This framework function is actually implemented in the openssl 2N/A * plugin library, so we find the function address and call it. 2N/A "OpenSSL_CertGetPrintable");
2N/A * Given a certificate (DER Encoded data) and a KMF 2N/A * extension identifier constant (e.g. KMF_X509_EXT_*), 2N/A * return a human readable interpretation of the 2N/A * The string will be a maximum of KMF_CERT_PRINTABLE_LEN 2N/A * bytes long. The string is allocated locally and 2N/A * must be freed by the caller. 2N/A * This function gets the time_t values of the notbefore and notafter dates 2N/A * from a der-encoded certificate. 2N/A /* The keystore must extract the pubkey data */ 2N/A for (i =
7; i <=
15 && !(
kubits & (
1 << i)); i++)
2N/A /* Set up validity fields */ 2N/A /* Build the format in 2 parts so SCCS doesn't get confused */ 2N/A /* Build the format in 2 parts so SCCS doesn't get confused */ 2N/A * Utility routine to set Integer values in the Certificate template 2N/A * for things like serialNumber and Version. The data structure 2N/A * expects pointers, not literal values, so we must allocate 2N/A * and copy here. Don't use memory from the stack since this data 2N/A * is freed later and that would be bad. 2N/A * Version ::= INTEGER { v1(0), v2(1), v3(2) } 2N/A * If the EKU is already in the cert, then just return OK. 2N/A /* Write the old extension data first */ 2N/A /* Append this EKU OID and close the sequence */ 2N/A * If we are just adding to an existing list of EKU OIDs, 2N/A * just replace the BER data associated with the found extension. 2N/A /* Write the pathLenConstraint value */ 2N/A * Phase 1 APIs still needed to maintain compat with elfsign.