diff --git a/Library/OcAppleDerLib/OcAppleDerLib.inf b/Library/OcAppleDerLib/OcAppleDerLib.inf new file mode 100644 index 00000000..d106ed37 --- /dev/null +++ b/Library/OcAppleDerLib/OcAppleDerLib.inf @@ -0,0 +1,45 @@ +## @file +# Component description file for OcAppleDerLib. +# +# Copyright (C) 2019, Download-Fritz. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = OcAppleDerLib + FILE_GUID = 3AFDED15-4E18-4FF1-9C5C-0D1F259DCF56 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcAppleDerLib + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseMemoryLib + +[Sources] + libDER/asn1Types.h + libDER/DER_CertCrl.c + libDER/DER_CertCrl.h + libDER/DER_Decode.c + libDER/DER_Decode.h + libDER/DER_Digest.c + libDER/DER_Digest.h + libDER/DER_Encode.c + libDER/DER_Encode.h + libDER/DER_Keys.c + libDER/DER_Keys.h + libDER/libDER.h + libDER_config.h + libDER/oids.c + libDER/oids.h diff --git a/Library/OcAppleDerLib/libDER/DER_CertCrl.c b/Library/OcAppleDerLib/libDER/DER_CertCrl.c new file mode 100644 index 00000000..53240fbe --- /dev/null +++ b/Library/OcAppleDerLib/libDER/DER_CertCrl.c @@ -0,0 +1,319 @@ +/* Copyright (c) 2005-2009 Apple Inc. All Rights Reserved. */ + +/* + * DER_Cert.c - support for decoding X509 certificates + * + * Created Nov. 4 2005 by Doug Mitchell. + */ + +#include "DER_Decode.h" +#include "DER_CertCrl.h" +#include "asn1Types.h" + +/* + * DERItemSpecs for X509 certificates. + */ + +/* top level cert with three components */ +const DERItemSpec DERSignedCertCrlItemSpecs[] = +{ + { DER_OFFSET(DERSignedCertCrl, tbs), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS | DER_DEC_SAVE_DER}, + { DER_OFFSET(DERSignedCertCrl, sigAlg), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERSignedCertCrl, sig), + ASN1_BIT_STRING, + DER_DEC_NO_OPTS } +}; + +const DERSize DERNumSignedCertCrlItemSpecs = + sizeof(DERSignedCertCrlItemSpecs) / sizeof(DERItemSpec); + +/* TBS cert */ +const DERItemSpec DERTBSCertItemSpecs[] = +{ + { DER_OFFSET(DERTBSCert, version), + ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 0, + DER_DEC_OPTIONAL }, /* version - EXPLICIT */ + { DER_OFFSET(DERTBSCert, serialNum), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCert, tbsSigAlg), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCert, issuer), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCert, validity), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCert, subject), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCert, subjectPubKey), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + /* libsecurity_asn1 has these two as CONSTRUCTED, but the ASN.1 spec + * doesn't look that way to me. I don't have any certs that have these + * fields.... */ + { DER_OFFSET(DERTBSCert, issuerID), + ASN1_CONTEXT_SPECIFIC | 1, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERTBSCert, subjectID), + ASN1_CONTEXT_SPECIFIC | 2, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERTBSCert, extensions), + ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 3, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumTBSCertItemSpecs = sizeof(DERTBSCertItemSpecs) / sizeof(DERItemSpec); + +/* DERValidity */ +const DERItemSpec DERValidityItemSpecs[] = +{ + { DER_OFFSET(DERValidity, notBefore), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, + { DER_OFFSET(DERValidity, notAfter), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } +}; +const DERSize DERNumValidityItemSpecs = + sizeof(DERValidityItemSpecs) / sizeof(DERItemSpec); + +/* DERAttributeTypeAndValue */ +const DERItemSpec DERAttributeTypeAndValueItemSpecs[] = { + { DER_OFFSET(DERAttributeTypeAndValue, type), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERAttributeTypeAndValue, value), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } +}; + +const DERSize DERNumAttributeTypeAndValueItemSpecs = + sizeof(DERAttributeTypeAndValueItemSpecs) / sizeof(DERItemSpec); + +/* DERExtension */ +const DERItemSpec DERExtensionItemSpecs[] = +{ + { DER_OFFSET(DERExtension, extnID), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERExtension, critical), + ASN1_BOOLEAN, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERExtension, extnValue), + ASN1_OCTET_STRING, + DER_DEC_NO_OPTS } +}; +const DERSize DERNumExtensionItemSpecs = + sizeof(DERExtensionItemSpecs) / sizeof(DERItemSpec); + +/* DERBasicConstraints */ +const DERItemSpec DERBasicConstraintsItemSpecs[] = +{ + { DER_OFFSET(DERBasicConstraints, cA), + ASN1_BOOLEAN, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERBasicConstraints, pathLenConstraint), + ASN1_INTEGER, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumBasicConstraintsItemSpecs = + sizeof(DERBasicConstraintsItemSpecs) / sizeof(DERItemSpec); + +/* DERPrivateKeyUsagePeriod. */ +const DERItemSpec DERPrivateKeyUsagePeriodItemSpecs[] = +{ + { DER_OFFSET(DERPrivateKeyUsagePeriod, notBefore), + ASN1_CONTEXT_SPECIFIC | 0, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERPrivateKeyUsagePeriod, notAfter), + ASN1_CONTEXT_SPECIFIC | 1, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumPrivateKeyUsagePeriodItemSpecs = + sizeof(DERPrivateKeyUsagePeriodItemSpecs) / sizeof(DERItemSpec); + +/* DERDistributionPoint. */ +const DERItemSpec DERDistributionPointItemSpecs[] = +{ + { DER_OFFSET(DERDistributionPoint, distributionPoint), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERDistributionPoint, reasons), + ASN1_CONTEXT_SPECIFIC | 1, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERDistributionPoint, cRLIssuer), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumDistributionPointItemSpecs = + sizeof(DERDistributionPointItemSpecs) / sizeof(DERItemSpec); + +/* DERPolicyInformation. */ +const DERItemSpec DERPolicyInformationItemSpecs[] = +{ + { DER_OFFSET(DERPolicyInformation, policyIdentifier), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERPolicyInformation, policyQualifiers), + ASN1_CONSTR_SEQUENCE, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumPolicyInformationItemSpecs = + sizeof(DERPolicyInformationItemSpecs) / sizeof(DERItemSpec); + +/* DERPolicyQualifierInfo. */ +const DERItemSpec DERPolicyQualifierInfoItemSpecs[] = +{ + { DER_OFFSET(DERPolicyQualifierInfo, policyQualifierID), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERPolicyQualifierInfo, qualifier), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } +}; +const DERSize DERNumPolicyQualifierInfoItemSpecs = + sizeof(DERPolicyQualifierInfoItemSpecs) / sizeof(DERItemSpec); + +/* DERUserNotice. */ +const DERItemSpec DERUserNoticeItemSpecs[] = +{ + { DER_OFFSET(DERUserNotice, noticeRef), + ASN1_CONSTR_SEQUENCE, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERUserNotice, explicitText), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_OPTIONAL | DER_DEC_SAVE_DER } +}; +const DERSize DERNumUserNoticeItemSpecs = + sizeof(DERUserNoticeItemSpecs) / sizeof(DERItemSpec); + +/* DERNoticeReference. */ +const DERItemSpec DERNoticeReferenceItemSpecs[] = +{ + { DER_OFFSET(DERNoticeReference, organization), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, + { DER_OFFSET(DERNoticeReference, noticeNumbers), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS } +}; +const DERSize DERNumNoticeReferenceItemSpecs = + sizeof(DERNoticeReferenceItemSpecs) / sizeof(DERItemSpec); + +/* DERPolicyMapping. */ +const DERItemSpec DERPolicyMappingItemSpecs[] = +{ + { DER_OFFSET(DERPolicyMapping, issuerDomainPolicy), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERPolicyMapping, subjectDomainPolicy), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS } +}; +const DERSize DERNumPolicyMappingItemSpecs = + sizeof(DERPolicyMappingItemSpecs) / sizeof(DERItemSpec); + +/* DERAccessDescription. */ +const DERItemSpec DERAccessDescriptionItemSpecs[] = +{ + { DER_OFFSET(DERAccessDescription, accessMethod), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERAccessDescription, accessLocation), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } +}; +const DERSize DERNumAccessDescriptionItemSpecs = + sizeof(DERAccessDescriptionItemSpecs) / sizeof(DERItemSpec); + +/* DERAuthorityKeyIdentifier. */ +const DERItemSpec DERAuthorityKeyIdentifierItemSpecs[] = +{ + { DER_OFFSET(DERAuthorityKeyIdentifier, keyIdentifier), + ASN1_CONTEXT_SPECIFIC | 0, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERAuthorityKeyIdentifier, authorityCertIssuer), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERAuthorityKeyIdentifier, authorityCertSerialNumber), + ASN1_CONTEXT_SPECIFIC | 2, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumAuthorityKeyIdentifierItemSpecs = + sizeof(DERAuthorityKeyIdentifierItemSpecs) / sizeof(DERItemSpec); + +/* DEROtherName. */ +const DERItemSpec DEROtherNameItemSpecs[] = +{ + { DER_OFFSET(DEROtherName, typeIdentifier), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DEROtherName, value), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0, + DER_DEC_NO_OPTS }, +}; +const DERSize DERNumOtherNameItemSpecs = + sizeof(DEROtherNameItemSpecs) / sizeof(DERItemSpec); + +/* DERPolicyConstraints. */ +const DERItemSpec DERPolicyConstraintsItemSpecs[] = +{ + { DER_OFFSET(DERPolicyConstraints, requireExplicitPolicy), + ASN1_CONTEXT_SPECIFIC | 0, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERPolicyConstraints, inhibitPolicyMapping), + ASN1_CONTEXT_SPECIFIC | 1, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumPolicyConstraintsItemSpecs = + sizeof(DERPolicyConstraintsItemSpecs) / sizeof(DERItemSpec); + +/* DERTBSCrl */ +const DERItemSpec DERTBSCrlItemSpecs[] = +{ + { DER_OFFSET(DERTBSCrl, version), + ASN1_INTEGER, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERTBSCrl, tbsSigAlg), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCrl, issuer), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCrl, thisUpdate), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, + { DER_OFFSET(DERTBSCrl, nextUpdate), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, + { DER_OFFSET(DERTBSCrl, revokedCerts), + ASN1_CONSTR_SEQUENCE, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERTBSCrl, extensions), + ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 0, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumTBSCrlItemSpecs = sizeof(DERTBSCrlItemSpecs) / sizeof(DERItemSpec); + +/* DERRevokedCert */ +const DERItemSpec DERRevokedCertItemSpecs[] = +{ + { DER_OFFSET(DERRevokedCert, serialNum), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERRevokedCert, revocationDate), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, + { DER_OFFSET(DERRevokedCert, extensions), + ASN1_CONSTR_SEQUENCE, + DER_DEC_OPTIONAL } +}; + +const DERSize DERNumRevokedCertItemSpecs = + sizeof(DERRevokedCertItemSpecs) / sizeof(DERItemSpec); diff --git a/Library/OcAppleDerLib/libDER/DER_CertCrl.h b/Library/OcAppleDerLib/libDER/DER_CertCrl.h new file mode 100644 index 00000000..4db1373a --- /dev/null +++ b/Library/OcAppleDerLib/libDER/DER_CertCrl.h @@ -0,0 +1,237 @@ +/* Copyright (c) 2005-2009 Apple Inc. All Rights Reserved. */ + +/* + * DER_CertCrl.h - support for decoding X509 certificates and CRLs + * + * Created Nov. 4 2005 by dmitch + */ + +#ifndef _DER_CERT_CRL_H_ +#define _DER_CERT_CRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libDER.h" +#include "DER_Decode.h" + +/* + * Top level cert or CRL - the two are identical at this level - three + * components. The tbs field is saved in full DER form for sig verify. + */ +typedef struct { + DERItem tbs; /* sequence, DERTBSCert, DER_DEC_SAVE_DER */ + DERItem sigAlg; /* sequence, DERAlgorithmId */ + DERItem sig; /* bit string */ +} DERSignedCertCrl; + +/* DERItemSpecs to decode into a DERSignedCertCrl */ +extern const DERItemSpec DERSignedCertCrlItemSpecs[]; +extern const DERSize DERNumSignedCertCrlItemSpecs; + +/* TBS cert components */ +typedef struct { + DERItem version; /* integer, optional, EXPLICIT */ + DERItem serialNum; /* integer */ + DERItem tbsSigAlg; /* sequence, DERAlgorithmId */ + DERItem issuer; /* sequence, TBD */ + DERItem validity; /* sequence, DERValidity */ + DERItem subject; /* sequence, TBD */ + DERItem subjectPubKey; /* sequence, DERSubjPubKeyInfo */ + DERItem issuerID; /* bit string, optional */ + DERItem subjectID; /* bit string, optional */ + DERItem extensions; /* sequence, optional, EXPLICIT */ +} DERTBSCert; + +/* DERItemSpecs to decode into a DERTBSCert */ +extern const DERItemSpec DERTBSCertItemSpecs[]; +extern const DERSize DERNumTBSCertItemSpecs; + +/* + * validity - components can be either UTC or generalized time. + * Both are ASN_ANY with DER_DEC_SAVE_DER. + */ +typedef struct { + DERItem notBefore; + DERItem notAfter; +} DERValidity; + +/* DERItemSpecs to decode into a DERValidity */ +extern const DERItemSpec DERValidityItemSpecs[]; +extern const DERSize DERNumValidityItemSpecs; + +/* AttributeTypeAndValue components. */ +typedef struct { + DERItem type; + DERItem value; +} DERAttributeTypeAndValue; + +/* DERItemSpecs to decode into DERAttributeTypeAndValue */ +extern const DERItemSpec DERAttributeTypeAndValueItemSpecs[]; +extern const DERSize DERNumAttributeTypeAndValueItemSpecs; + +/* Extension components */ +typedef struct { + DERItem extnID; + DERItem critical; + DERItem extnValue; +} DERExtension; + +/* DERItemSpecs to decode into DERExtension */ +extern const DERItemSpec DERExtensionItemSpecs[]; +extern const DERSize DERNumExtensionItemSpecs; + +/* BasicConstraints components. */ +typedef struct { + DERItem cA; + DERItem pathLenConstraint; +} DERBasicConstraints; + +/* DERItemSpecs to decode into DERBasicConstraints */ +extern const DERItemSpec DERBasicConstraintsItemSpecs[]; +extern const DERSize DERNumBasicConstraintsItemSpecs; + +/* PrivateKeyUsagePeriod components. */ +typedef struct { + DERItem notBefore; + DERItem notAfter; +} DERPrivateKeyUsagePeriod; + +/* DERItemSpecs to decode into a DERPrivateKeyUsagePeriod */ +extern const DERItemSpec DERPrivateKeyUsagePeriodItemSpecs[]; +extern const DERSize DERNumPrivateKeyUsagePeriodItemSpecs; + +/* DistributionPoint components. */ +typedef struct { + DERItem distributionPoint; + DERItem reasons; + DERItem cRLIssuer; +} DERDistributionPoint; + +/* DERItemSpecs to decode into a DERDistributionPoint */ +extern const DERItemSpec DERDistributionPointItemSpecs[]; +extern const DERSize DERNumDistributionPointItemSpecs; + +/* PolicyInformation components. */ +typedef struct { + DERItem policyIdentifier; + DERItem policyQualifiers; +} DERPolicyInformation; + +/* DERItemSpecs to decode into a DERPolicyInformation */ +extern const DERItemSpec DERPolicyInformationItemSpecs[]; +extern const DERSize DERNumPolicyInformationItemSpecs; + +/* PolicyQualifierInfo components. */ +typedef struct { + DERItem policyQualifierID; + DERItem qualifier; +} DERPolicyQualifierInfo; + +/* DERItemSpecs to decode into a DERPolicyQualifierInfo */ +extern const DERItemSpec DERPolicyQualifierInfoItemSpecs[]; +extern const DERSize DERNumPolicyQualifierInfoItemSpecs; + +/* UserNotice components. */ +typedef struct { + DERItem noticeRef; + DERItem explicitText; +} DERUserNotice; + +/* DERItemSpecs to decode into a DERUserNotice */ +extern const DERItemSpec DERUserNoticeItemSpecs[]; +extern const DERSize DERNumUserNoticeItemSpecs; + +/* NoticeReference components. */ +typedef struct { + DERItem organization; + DERItem noticeNumbers; +} DERNoticeReference; + +/* DERItemSpecs to decode into a DERNoticeReference */ +extern const DERItemSpec DERNoticeReferenceItemSpecs[]; +extern const DERSize DERNumNoticeReferenceItemSpecs; + +/* PolicyMapping components. */ +typedef struct { + DERItem issuerDomainPolicy; + DERItem subjectDomainPolicy; +} DERPolicyMapping; + +/* DERItemSpecs to decode into a DERPolicyMapping */ +extern const DERItemSpec DERPolicyMappingItemSpecs[]; +extern const DERSize DERNumPolicyMappingItemSpecs; + +/* AccessDescription components. */ +typedef struct { + DERItem accessMethod; + DERItem accessLocation; +} DERAccessDescription; + +/* DERItemSpecs to decode into a DERAccessDescription */ +extern const DERItemSpec DERAccessDescriptionItemSpecs[]; +extern const DERSize DERNumAccessDescriptionItemSpecs; + +/* AuthorityKeyIdentifier components. */ +typedef struct { + DERItem keyIdentifier; + DERItem authorityCertIssuer; + DERItem authorityCertSerialNumber; +} DERAuthorityKeyIdentifier; + +/* DERItemSpecs to decode into a DERAuthorityKeyIdentifier */ +extern const DERItemSpec DERAuthorityKeyIdentifierItemSpecs[]; +extern const DERSize DERNumAuthorityKeyIdentifierItemSpecs; + +/* OtherName components. */ +typedef struct { + DERItem typeIdentifier; + DERItem value; +} DEROtherName; + +/* DERItemSpecs to decode into a DEROtherName */ +extern const DERItemSpec DEROtherNameItemSpecs[]; +extern const DERSize DERNumOtherNameItemSpecs; + +/* PolicyConstraints components. */ +typedef struct { + DERItem requireExplicitPolicy; + DERItem inhibitPolicyMapping; +} DERPolicyConstraints; + +/* DERItemSpecs to decode into a DERPolicyConstraints */ +extern const DERItemSpec DERPolicyConstraintsItemSpecs[]; +extern const DERSize DERNumPolicyConstraintsItemSpecs; + +/* TBS CRL */ +typedef struct { + DERItem version; /* integer, optional */ + DERItem tbsSigAlg; /* sequence, DERAlgorithmId */ + DERItem issuer; /* sequence, TBD */ + DERItem thisUpdate; /* ASN_ANY, SAVE_DER */ + DERItem nextUpdate; /* ASN_ANY, SAVE_DER */ + DERItem revokedCerts; /* sequence of DERRevokedCert, optional */ + DERItem extensions; /* sequence, optional, EXPLICIT */ +} DERTBSCrl; + +/* DERItemSpecs to decode into a DERTBSCrl */ +extern const DERItemSpec DERTBSCrlItemSpecs[]; +extern const DERSize DERNumTBSCrlItemSpecs; + +typedef struct { + DERItem serialNum; /* integer */ + DERItem revocationDate; /* time - ASN_ANY, SAVE_DER */ + DERItem extensions; /* sequence, optional, EXPLICIT */ +} DERRevokedCert; + +/* DERItemSpecs to decode into a DERRevokedCert */ +extern const DERItemSpec DERRevokedCertItemSpecs[]; +extern const DERSize DERNumRevokedCertItemSpecs; + +#ifdef __cplusplus +} +#endif + +#endif /* _DER_CERT_CRL_H_ */ + diff --git a/Library/OcAppleDerLib/libDER/DER_Decode.c b/Library/OcAppleDerLib/libDER/DER_Decode.c new file mode 100644 index 00000000..98f3c5d1 --- /dev/null +++ b/Library/OcAppleDerLib/libDER/DER_Decode.c @@ -0,0 +1,584 @@ +/* + * Copyright (c) 2005-2010 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * DER_Decode.c - DER decoding routines + */ + +#include "DER_Decode.h" +#include "asn1Types.h" + +#include "libDER_config.h" + +#ifndef DER_DECODE_ENABLE +#error Please define DER_DECODE_ENABLE. +#endif + +#if DER_DECODE_ENABLE + +#define DER_DECODE_DEBUG 0 +#if DER_DECODE_DEBUG +#include +#define derDecDbg(a) printf(a) +#define derDecDbg1(a, b) printf(a, b) +#define derDecDbg2(a, b, c) printf(a, b, c) +#define derDecDbg3(a, b, c, d) printf(a, b, c, d) +#else +#define derDecDbg(a) +#define derDecDbg1(a, b) +#define derDecDbg2(a, b, c) +#define derDecDbg3(a, b, c, d) +#endif /* DER_DECODE_DEBUG */ + +/* + * Basic decoding primitive. Only works with: + * + * -- definite length encoding + * -- one-byte tags + * -- max content length fits in a DERSize + * + * No malloc or copy of the contents is performed; the returned + * content->content.data is a pointer into the incoming der data. + */ +DERReturn DERDecodeItem( + const DERItem *der, /* data to decode */ + DERDecodedInfo *decoded) /* RETURNED */ +{ + DERByte tag1; /* first tag byte */ + DERByte len1; /* first length byte */ + DERTag tagNumber; /* tag number without class and method bits */ + DERByte *derPtr = der->data; + DERSize derLen = der->length; + + /* The tag decoding below is fully BER complient. We support a max tag + value of 2 ^ ((sizeof(DERTag) * 8) - 3) - 1 so for tag size 1 byte we + support tag values from 0 - 0x1F. For tag size 2 tag values + from 0 - 0x1FFF and for tag size 4 values from 0 - 0x1FFFFFFF. */ + if(derLen < 2) { + return DR_DecodeError; + } + /* Grab the first byte of the tag. */ + tag1 = *derPtr++; + derLen--; + tagNumber = tag1 & 0x1F; + if(tagNumber == 0x1F) { +#ifdef DER_MULTIBYTE_TAGS + /* Long tag form: bit 8 of each octet shall be set to one unless it is + the last octet of the tag */ + const DERTag overflowMask = ((DERTag)0x7F << (sizeof(DERTag) * 8 - 7)); + DERByte tagByte; + tagNumber = 0; + do { + if(derLen < 2 || (tagNumber & overflowMask) != 0) { + return DR_DecodeError; + } + tagByte = *derPtr++; + derLen--; + tagNumber = (tagNumber << 7) | (tagByte & 0x7F); + } while((tagByte & 0x80) != 0); + + /* Check for any of the top 3 reserved bits being set. */ + if ((tagNumber & (overflowMask << 4)) != 0) +#endif + return DR_DecodeError; + } + /* Returned tag, top 3 bits are class/method remaining bits are number. */ + decoded->tag = ((DERTag)(tag1 & 0xE0) << ((sizeof(DERTag) - 1) * 8)) | tagNumber; + + /* Tag decoding above ensured we have at least one more input byte left. */ + len1 = *derPtr++; + derLen--; + if(len1 & 0x80) { + /* long length form - first byte is length of length */ + DERSize longLen = 0; /* long form length */ + unsigned dex; + + len1 &= 0x7f; + if((len1 > sizeof(DERSize)) || (len1 > derLen)) { + /* no can do */ + return DR_DecodeError; + } + for(dex=0; dex derLen) { + /* not enough data left for this encoding */ + return DR_DecodeError; + } + decoded->content.data = derPtr; + decoded->content.length = longLen; + } + else { + /* short length form, len1 is the length */ + if(len1 > derLen) { + /* not enough data left for this encoding */ + return DR_DecodeError; + } + decoded->content.data = derPtr; + decoded->content.length = len1; + } + + return DR_Success; +} + +/* + * Given a BIT_STRING, in the form of its raw content bytes, + * obtain the number of unused bits and the raw bit string bytes. + */ +DERReturn DERParseBitString( + const DERItem *contents, + DERItem *bitStringBytes, /* RETURNED */ + DERByte *numUnusedBits) /* RETURNED */ +{ + if(contents->length < 2) { + /* not enough room for actual bits after the unused bits field */ + *numUnusedBits = 0; + bitStringBytes->data = NULL; + bitStringBytes->length = 0; + return DR_Success; + } + *numUnusedBits = contents->data[0]; + bitStringBytes->data = contents->data + 1; + bitStringBytes->length = contents->length - 1; + return DR_Success; +} + +/* + * Given a BOOLEAN, in the form of its raw content bytes, + * obtain it's value. + */ +DERReturn DERParseBoolean( + const DERItem *contents, + bool defaultValue, + bool *value) { /* RETURNED */ + if (contents->length == 0) { + *value = defaultValue; + return DR_Success; + } + if (contents->length != 1 || + (contents->data[0] != 0 && contents->data[0] != 0xFF)) + return DR_DecodeError; + + *value = contents->data[0] != 0; + return DR_Success; +} + +DERReturn DERParseInteger( + const DERItem *contents, + uint32_t *result) { /* RETURNED */ + DERSize ix, length = contents->length; + if (length > 4) + return DR_BufOverflow; + uint32_t value = 0; + for (ix = 0; ix < length; ++ix) { + value <<= 8; + value += contents->data[ix]; + } + *result = value; + return DR_Success; +} + +/* Sequence/set support */ + +/* + * To decode a set or sequence, call DERDecodeSeqInit once, then + * call DERDecodeSeqNext to get each enclosed item. + * DERDecodeSeqNext returns DR_EndOfSequence when no more + * items are available. + */ +DERReturn DERDecodeSeqInit( + const DERItem *der, /* data to decode */ + DERTag *tag, /* RETURNED tag of sequence/set. This will be + * either ASN1_CONSTR_SEQUENCE or ASN1_CONSTR_SET. */ + DERSequence *derSeq) /* RETURNED, to use in DERDecodeSeqNext */ +{ + DERDecodedInfo decoded; + DERReturn drtn; + + drtn = DERDecodeItem(der, &decoded); + if(drtn) { + return drtn; + } + *tag = decoded.tag; + switch(decoded.tag) { + case ASN1_CONSTR_SEQUENCE: + case ASN1_CONSTR_SET: + break; + default: + return DR_UnexpectedTag; + } + derSeq->nextItem = decoded.content.data; + derSeq->end = decoded.content.data + decoded.content.length; + return DR_Success; +} + +/* + * Use this to start in on decoding a sequence's content, when + * the top-level tag and content have already been decoded. + */ +DERReturn DERDecodeSeqContentInit( + const DERItem *content, + DERSequence *derSeq) /* RETURNED, to use in DERDecodeSeqNext */ +{ + /* just prepare for decoding items in content */ + derSeq->nextItem = content->data; + derSeq->end = content->data + content->length; + return DR_Success; +} + +DERReturn DERDecodeSeqNext( + DERSequence *derSeq, + DERDecodedInfo *decoded) /* RETURNED */ +{ + DERReturn drtn; + DERItem item; + + if(derSeq->nextItem >= derSeq->end) { + /* normal termination, contents all used up */ + return DR_EndOfSequence; + } + + /* decode next item */ + item.data = derSeq->nextItem; + item.length = derSeq->end - derSeq->nextItem; + drtn = DERDecodeItem(&item, decoded); + if(drtn) { + return drtn; + } + + /* skip over the item we just decoded */ + derSeq->nextItem = decoded->content.data + decoded->content.length; + return DR_Success; +} + +/* + * High level sequence parse, starting with top-level tag and content. + * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's + * OK, use DERParseSequenceContent(). + */ +DERReturn DERParseSequence( + const DERItem *der, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize sizeToZero) /* optional */ +{ + DERReturn drtn; + DERDecodedInfo topDecode; + + drtn = DERDecodeItem(der, &topDecode); + if(drtn) { + return drtn; + } + if(topDecode.tag != ASN1_CONSTR_SEQUENCE) { + return DR_UnexpectedTag; + } + return DERParseSequenceContent(&topDecode.content, + numItems, itemSpecs, dest, sizeToZero); +} + +/* high level sequence parse, starting with sequence's content */ +DERReturn DERParseSequenceContent( + const DERItem *content, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize sizeToZero) /* optional */ +{ + DERSequence derSeq; + DERReturn drtn; + DERShort itemDex; + DERByte *currDER; /* full DER encoding of current item */ + + if(sizeToZero) { + DERMemset(dest, 0, sizeToZero); + } + + drtn = DERDecodeSeqContentInit(content, &derSeq); + if(drtn) { + return drtn; + } + + /* main loop */ + for(itemDex=0 ; itemDexoptions; + derDecDbg3("--- currItem %u expectTag 0x%x currOptions 0x%x\n", + i, currItemSpec->tag, currOptions); + + if((currOptions & DER_DEC_ASN_ANY) || + (foundTag == currItemSpec->tag)) { + /* + * We're good with this one. Cook up destination address + * as appropriate. + */ + if(!(currOptions & DER_DEC_SKIP)) { + derDecDbg1("--- MATCH at currItem %u\n", i); + DERByte *byteDst = (DERByte *)dest + currItemSpec->offset; + DERItem *dst = (DERItem *)byteDst; + *dst = currDecoded.content; + if(currOptions & DER_DEC_SAVE_DER) { + /* recreate full DER encoding of this item */ + derDecDbg1("--- SAVE_DER at currItem %u\n", i); + dst->data = currDER; + dst->length += (currDecoded.content.data - currDER); + } + } + + /* on to next item */ + itemDex = i + 1; + + /* is this the end? */ + if(itemDex == numItems) { + /* normal termination */ + return DR_Success; + } + else { + /* on to next item */ + foundMatch = 1; + break; + } + } /* ASN_ANY, or match */ + + /* + * If current itemSpec isn't optional, abort - else on to + * next item + */ + if(!(currOptions & DER_DEC_OPTIONAL)) { + derDecDbg1("--- MISMATCH at currItem %u, !OPTIONAL, abort\n", i); + return DR_UnexpectedTag; + } + + /* else this was optional, on to next item */ + } /* searching for tag match */ + + if(foundMatch == 0) { + /* + * Found an item we couldn't match to any tag spec and we're at + * the end. + */ + derDecDbg("--- TAG NOT FOUND, abort\n"); + return DR_UnexpectedTag; + } + + /* else on to next item */ + } /* main loop */ + + /* + * If we get here, there appears to be more to process, but we've + * given the caller everything they want. + */ + return DR_Success; +} + +#if 0 +/* + * High level sequence parse, starting with top-level tag and content. + * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's + * OK, use DERParseSequenceContent(). + */ +DERReturn DERParseSequenceOf( + const DERItem *der, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize *numDestItems) /* output */ +{ + DERReturn drtn; + DERDecodedInfo topDecode; + + drtn = DERDecodeItem(der, &topDecode); + if(drtn) { + return drtn; + } + if(topDecode.tag != ASN1_CONSTR_SEQUENCE) { + return DR_UnexpectedTag; + } + return DERParseSequenceContent(&topDecode.content, + numItems, itemSpecs, dest, sizeToZero); +} + +/* + * High level set of parse, starting with top-level tag and content. + * Top level tag must be ASN1_CONSTR_SET - if it's not, and that's + * OK, use DERParseSetOrSequenceOfContent(). + */ +DERReturn DERParseSetOf( + const DERItem *der, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize *numDestItems) /* output */ +{ + DERReturn drtn; + DERDecodedInfo topDecode; + + drtn = DERDecodeItem(der, &topDecode); + if(drtn) { + return drtn; + } + if(topDecode.tag != ASN1_CONSTR_SET) { + return DR_UnexpectedTag; + } + return DERParseSetOrSequenceOfContent(&topDecode.content, + numItems, itemSpecs, dest, numDestItems); +} + +/* High level set of or sequence of parse, starting with set or + sequence's content */ +DERReturn DERParseSetOrSequenceOfContent( + const DERItem *content, + void(*itemHandeler)(void *, const DERDecodedInfo *) + void *itemHandelerContext); +{ + DERSequence derSeq; + DERShort itemDex; + + drtn = DERDecodeSeqContentInit(content, &derSeq); + require_noerr_quiet(drtn, badCert); + + /* main loop */ + for (;;) { + DERDecodedInfo currDecoded; + DERShort i; + DERByte foundTag; + char foundMatch = 0; + + drtn = DERDecodeSeqNext(&derSeq, &currDecoded); + if(drtn) { + /* The only legal error here is DR_EndOfSequence. */ + if(drtn == DR_EndOfSequence) { + /* no more items left in the sequence; success */ + return DR_Success; + } + else { + /* any other error is fatal */ + require_noerr_quiet(drtn, badCert); + } + } /* decode error */ + + /* Each element can be anything. */ + foundTag = currDecoded.tag; + + /* + * We're good with this one. Cook up destination address + * as appropriate. + */ + DERByte *byteDst = (DERByte *)dest + currItemSpec->offset; + DERItem *dst = (DERItem *)byteDst; + *dst = currDecoded.content; + if(currOptions & DER_DEC_SAVE_DER) { + /* recreate full DER encoding of this item */ + derDecDbg1("--- SAVE_DER at currItem %u\n", i); + dst->data = currDER; + dst->length += (currDecoded.content.data - currDER); + } + + /* on to next item */ + itemDex = i + 1; + + /* is this the end? */ + if(itemDex == numItems) { + /* normal termination */ + return DR_Success; + } + else { + /* on to next item */ + foundMatch = 1; + break; + } + + /* + * If current itemSpec isn't optional, abort - else on to + * next item + */ + if(!(currOptions & DER_DEC_OPTIONAL)) { + derDecDbg1("--- MISMATCH at currItem %u, !OPTIONAL, abort\n", i); + return DR_UnexpectedTag; + } + + /* else this was optional, on to next item */ + } /* searching for tag match */ + + if(foundMatch == 0) { + /* + * Found an item we couldn't match to any tag spec and we're at + * the end. + */ + derDecDbg("--- TAG NOT FOUND, abort\n"); + return DR_UnexpectedTag; + } + + /* else on to next item */ + } /* main loop */ + + /* + * If we get here, there appears to be more to process, but we've + * given the caller everything they want. + */ + return DR_Success; + } +} +#endif + +#endif /* DER_DECODE_ENABLE */ diff --git a/Library/OcAppleDerLib/libDER/DER_Decode.h b/Library/OcAppleDerLib/libDER/DER_Decode.h new file mode 100644 index 00000000..82df34c0 --- /dev/null +++ b/Library/OcAppleDerLib/libDER/DER_Decode.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2005-2010 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * DER_Decode.h - DER decoding routines + */ + +#ifndef _DER_DECODE_H_ +#define _DER_DECODE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libDER.h" + +/* + * Decoding one item consists of extracting its tag, a pointer + * to the actual content, and the length of the content. Those + * three are represented by a DERDecodedInfo. + */ +typedef struct { + DERTag tag; + DERItem content; +} DERDecodedInfo; + +/* + * Basic decoding primitive. Only works with: + * + * -- definite length encoding + * -- one-byte tags + * -- max content length fits in a DERSize + * + * No malloc or copy of the contents is performed; the returned + * content->content.data is a pointer into the incoming der data. + */ +DERReturn DERDecodeItem( + const DERItem *der, /* data to decode */ + DERDecodedInfo *decoded); /* RETURNED */ + +/* + * Given a BIT_STRING, in the form of its raw content bytes, + * obtain the number of unused bits and the raw bit string bytes. + */ +DERReturn DERParseBitString( + const DERItem *contents, + DERItem *bitStringBytes, /* RETURNED */ + DERByte *numUnusedBits); /* RETURNED */ + +/* + * Given a BOOLEAN, in the form of its raw content bytes, + * obtain it's value. + */ +DERReturn DERParseBoolean( + const DERItem *contents, + bool defaultValue, + bool *value); /* RETURNED */ + +DERReturn DERParseInteger( + const DERItem *contents, + uint32_t *value); /* RETURNED */ + +/* + * Sequence/set decode support. + */ + +/* state representing a sequence or set being decoded */ +typedef struct { + DERByte *nextItem; + DERByte *end; +} DERSequence; + +/* + * To decode a set or sequence, call DERDecodeSeqInit or + * DERDecodeSeqContentInit once, then call DERDecodeSeqNext to + * get each enclosed item. + * + * DERDecodeSeqNext returns DR_EndOfSequence when no more + * items are available. + */ + +/* + * Use this to parse the top level sequence's tag and content length. + */ +DERReturn DERDecodeSeqInit( + const DERItem *der, /* data to decode */ + DERTag *tag, /* RETURNED tag of sequence/set. This will be + * either ASN1_CONSTR_SEQUENCE or + * ASN1_CONSTR_SET. */ + DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */ + +/* + * Use this to start in on decoding a sequence's content, when + * the top-level tag and content have already been decoded. + */ +DERReturn DERDecodeSeqContentInit( + const DERItem *content, + DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */ + +/* obtain the next decoded item in a sequence or set */ +DERReturn DERDecodeSeqNext( + DERSequence *derSeq, + DERDecodedInfo *decoded); /* RETURNED */ + +/* + * High level sequence decode. + */ + +/* + * Per-item decode options. + */ + +/* Explicit default, no options */ +#define DER_DEC_NO_OPTS 0x0000 + +/* This item optional, can be skipped during decode */ +#define DER_DEC_OPTIONAL 0x0001 + +/* Skip the tag check; accept anything. */ +#define DER_DEC_ASN_ANY 0x0002 + +/* Skip item, no write to DERDecodedInfo (but tag check still performed) */ +#define DER_DEC_SKIP 0x0004 + +/* Save full DER encoding in DERDecodedInfo, including tag and length. Normally + * only the content is saved. */ +#define DER_DEC_SAVE_DER 0x0008 + +/* + * High level sequence parse, starting with top-level tag and content. + * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's + * OK, use DERParseSequenceContent(). + * + * These never return DR_EndOfSequence - if an *unexpected* end of sequence + * occurs, return DR_IncompleteSeq. + * + * Results of the decoding of one item are placed in a DERItem whose address + * is the dest arg plus the offset value in the associated DERItemSpec. + * + * Items which are optional (DER_DEC_OPTIONAL) and which are not found, + * leave their associated DERDecodedInfos unmodified. + * + * Processing of a sequence ends on detection of any error or after the + * last DERItemSpec is processed. + * + * The sizeToZero argument, if nonzero, indicates the number of bytes + * starting at dest to zero before processing the sequence. This is + * generally desirable, particularly if there are any DER_DEC_OPTIONAL + * items in the sequence; skipped optional items are detected by the + * caller via a NULL DERDecodedInfo.content.data; if this hasn't been + * explicitly zeroed (generally, by passing a nonzero value of sizeToZero), + * skipped items can't be detected. + */ +DERReturn DERParseSequence( + const DERItem *der, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize sizeToZero); /* optional */ + +/* high level sequence parse, starting with sequence's content */ +DERReturn DERParseSequenceContent( + const DERItem *content, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize sizeToZero); /* optional */ + +#ifdef __cplusplus +} +#endif + +#endif /* _DER_DECODE_H_ */ + diff --git a/Library/OcAppleDerLib/libDER/DER_Digest.c b/Library/OcAppleDerLib/libDER/DER_Digest.c new file mode 100644 index 00000000..4ad643c1 --- /dev/null +++ b/Library/OcAppleDerLib/libDER/DER_Digest.c @@ -0,0 +1,162 @@ +/* Copyright (c) 2005-2008,2010 Apple Inc. All Rights Reserved. */ + +/* + * DER_Digest.h - DER encode a DigestInfo + * + * Created Nov. 9 2005 by dmitch + */ + +#include "DER_Digest.h" + +/* + * Create an encoded DigestInfo based on the specified SHA1 digest. + * The digest must be 20 bytes long. + * + * Result is placed in caller's buffer, which must be at least of + * length DER_DIGEST_INFO_LEN bytes. + * + * The *resultLen parameter is the available size in the result + * buffer on input, and the actual length of the encoded DigestInfo + * on output. + * + * In the interest of saving code space, this just drops the caller's + * digest into an otherwise hard-coded, fixed, encoded SHA1 DigestInfo. + * Nothing is variable so we know the whole thing. It looks like this: + * + * SEQUENCE OF <33> { + * SEQUENCE OF <9> { + * OID <5>: OID : < 06 05 2B 0E 03 02 1A > + * NULL + * } + * OCTET STRING <20>: + * 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 + * 55 55 55 55 + * } + * + * + * tower.local:digestInfo> hexdump -x /tmp/encodedDigest + * 0000000 3021 3009 0605 2b0e 0302 1a05 0004 1455 + * 0000010 5555 5555 5555 5555 5555 5555 5555 5555 + * * + * 0000020 + */ + +static const unsigned char encodedSha1Digest[] = +{ + 0x30, 0x21, /* top level sequence length 33 */ + 0x30, 0x09, /* algorithm ID, sequence length 9 */ + 0x06, 0x05, /* alg OID, length 5, SHA1 */ + 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x05, 0x00, /* NULL parameters */ + 0x04, 0x14 /* integer length 20 */ + /* digest follows */ +}; + +DERReturn DEREncodeSHA1DigestInfo( + const DERByte *sha1Digest, + DERSize sha1DigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen) /* IN/OUT */ +{ + DERSize totalLen = sizeof(encodedSha1Digest) + DER_SHA1_DIGEST_LEN; + + if((sha1Digest == NULL) || (sha1DigestLen != DER_SHA1_DIGEST_LEN) || + (result == NULL) || (resultLen == NULL)) { + return DR_ParamErr; + } + if(*resultLen < DER_SHA1_DIGEST_INFO_LEN) { + return DR_BufOverflow; + } + DERMemmove(result, encodedSha1Digest, sizeof(encodedSha1Digest)); + DERMemmove(result + sizeof(encodedSha1Digest), sha1Digest, DER_SHA1_DIGEST_LEN); + *resultLen = totalLen; + return DR_Success; +} + +/* + joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) + csor(3) nistalgorithm(4) hashAlgs(2) sha256(1) + + future ones to add: sha384(2) sha512(3) sha224(4) +*/ +static const unsigned char encodedSha256Digest[] = +{ + 0x30, 0x31, /* top level sequence length 49 */ + 0x30, 0x0d, /* algorithm ID, sequence length 13 */ + 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, + 0x05, 0x00, /* NULL parameters */ + 0x04, 0x20 /* integer length 32 */ + /* digest follows */ +}; + +DERReturn DEREncodeSHA256DigestInfo( + const DERByte *sha256Digest, + DERSize sha256DigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen) /* IN/OUT */ +{ + DERSize totalLen = sizeof(encodedSha256Digest) + DER_SHA256_DIGEST_LEN; + + if((sha256Digest == NULL) || (sha256DigestLen != DER_SHA256_DIGEST_LEN) || + (result == NULL) || (resultLen == NULL)) { + return DR_ParamErr; + } + if(*resultLen < DER_SHA256_DIGEST_INFO_LEN) { + return DR_BufOverflow; + } + DERMemmove(result, encodedSha256Digest, sizeof(encodedSha256Digest)); + DERMemmove(result + sizeof(encodedSha256Digest), sha256Digest, DER_SHA256_DIGEST_LEN); + *resultLen = totalLen; + return DR_Success; +} + + +/* Same thing, MD5/MD2 */ +static const unsigned char encodedMdDigest[] = +{ + 0x30, 0x20, /* top level sequence length 32 */ + 0x30, 0x0c, /* algorithm ID, sequence length 12 */ + 0x06, 0x08, /* alg OID, length 8, MD2/MD5 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, + 0x05, /* 5 = MD5, 2 = MD2 */ + 0x05, 0x00, /* NULL parameters */ + 0x04, 0x10 /* integer length 16 */ + /* digest follows */ +}; + +#define WHICH_DIGEST_INDEX 13 +#define WHICH_DIGEST_MD2 2 +#define WHICH_DIGEST_MD5 5 + +DERReturn DEREncodeMDDigestInfo( + WhichDigest whichDigest, + const DERByte *mdDigest, + DERSize mdDigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen) /* IN/OUT */ +{ + DERSize totalLen = sizeof(encodedMdDigest) + DER_MD_DIGEST_LEN; + + if((mdDigest == NULL) || (mdDigestLen != DER_MD_DIGEST_LEN) || + (result == NULL) || (resultLen == NULL)) { + return DR_ParamErr; + } + if(*resultLen < totalLen) { + return DR_BufOverflow; + } + DERMemmove(result, encodedMdDigest, sizeof(encodedMdDigest)); + DERMemmove(result + sizeof(encodedMdDigest), mdDigest, DER_MD_DIGEST_LEN); + switch(whichDigest) { + case WD_MD2: + result[WHICH_DIGEST_INDEX] = WHICH_DIGEST_MD2; + break; + case WD_MD5: + result[WHICH_DIGEST_INDEX] = WHICH_DIGEST_MD5; + break; + default: + return DR_ParamErr; + } + *resultLen = totalLen; + return DR_Success; +} diff --git a/Library/OcAppleDerLib/libDER/DER_Digest.h b/Library/OcAppleDerLib/libDER/DER_Digest.h new file mode 100644 index 00000000..3eac40b1 --- /dev/null +++ b/Library/OcAppleDerLib/libDER/DER_Digest.h @@ -0,0 +1,74 @@ +/* Copyright (c) 2005-2008,2010 Apple Inc. All Rights Reserved. */ + +/* + * DER_Digest.h - DER encode a DigestInfo + * + * Created Nov. 9 2005 by dmitch + */ + +#ifndef _DER_DIGEST_H_ +#define _DER_DIGEST_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libDER.h" + +/* + * Create an encoded DigestInfo based on the specified SHA1 digest. + * The incoming digest must be 20 bytes long. + * + * Result is placed in caller's buffer, which must be at least of + * length DER_SHA1_DIGEST_INFO_LEN bytes. + * + * The *resultLen parameter is the available size in the result + * buffer on input, and the actual length of the encoded DigestInfo + * on output. + */ +#define DER_SHA1_DIGEST_LEN 20 +#define DER_SHA1_DIGEST_INFO_LEN 35 + +DERReturn DEREncodeSHA1DigestInfo( + const DERByte *sha1Digest, + DERSize sha1DigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen); /* IN/OUT */ + +#define DER_SHA256_DIGEST_LEN 32 +#define DER_SHA256_DIGEST_INFO_LEN 51 + +DERReturn DEREncodeSHA256DigestInfo( + const DERByte *sha256Digest, + DERSize sha256DigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen); /* IN/OUT */ + +/* + * Likewise, create an encoded DIgestInfo for specified MD5 or MD2 digest. + */ +#define DER_MD_DIGEST_LEN 16 +#define DER_MD_DIGEST_INFO_LEN 34 + +typedef enum { + WD_MD2 = 1, + WD_MD5 = 2 +} WhichDigest; + +DERReturn DEREncodeMDDigestInfo( + WhichDigest whichDigest, + const DERByte *mdDigest, + DERSize mdDigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen); /* IN/OUT */ + +/* max sizes you'll need in the general cases */ +#define DER_MAX_DIGEST_LEN DER_SHA256_DIGEST_LEN +#define DER_MAX_ENCODED_INFO_LEN DER_SHA256_DIGEST_INFO_LEN + +#ifdef __cplusplus +} +#endif + +#endif /* _DER_DIGEST_H_ */ + diff --git a/Library/OcAppleDerLib/libDER/DER_Encode.c b/Library/OcAppleDerLib/libDER/DER_Encode.c new file mode 100644 index 00000000..88d1c90d --- /dev/null +++ b/Library/OcAppleDerLib/libDER/DER_Encode.c @@ -0,0 +1,342 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * DER_Encode.h - DER encoding routines + * + * Created Dec. 2 2005 by dmitch + */ + +#include "DER_Encode.h" +#include "asn1Types.h" +#include "libDER_config.h" +#include "DER_Decode.h" + +#ifndef DER_ENCODE_ENABLE +#error Please define DER_ENCODE_ENABLE. +#endif + +#if DER_ENCODE_ENABLE + +/* calculate size of encoded tag */ +static DERSize DERLengthOfTag( + DERTag tag) +{ + DERSize rtn = 1; + + tag &= ASN1_TAGNUM_MASK; + if (tag >= 0x1F) { + /* Shift 7-bit digits out of the tag integer until it's zero. */ + while(tag != 0) { + rtn++; + tag >>= 7; + } + } + + return rtn; +} + +/* encode tag */ +static DERReturn DEREncodeTag( + DERTag tag, + DERByte *buf, /* encoded length goes here */ + DERSize *inOutLen) /* IN/OUT */ +{ + DERSize outLen = DERLengthOfTag(tag); + DERTag tagNumber = tag & ASN1_TAGNUM_MASK; + DERByte tag1 = (tag >> (sizeof(DERTag) * 8 - 8)) & 0xE0; + + if(outLen > *inOutLen) { + return DR_BufOverflow; + } + + if(outLen == 1) { + /* short form */ + *buf = tag1 | tagNumber; + } + else { + /* long form */ + DERByte *tagBytes = buf + outLen; // l.s. digit of tag + *buf = tag1 | 0x1F; // tag class / method indicator + *--tagBytes = tagNumber & 0x7F; + tagNumber >>= 7; + while(tagNumber != 0) { + *--tagBytes = (tagNumber & 0x7F) | 0x80; + tagNumber >>= 7; + } + } + *inOutLen = outLen; + return DR_Success; +} + +/* calculate size of encoded length */ +DERSize DERLengthOfLength( + DERSize length) +{ + DERSize rtn; + + if(length < 0x80) { + /* short form length */ + return 1; + } + + /* long form - one length-of-length byte plus length bytes */ + rtn = 1; + while(length != 0) { + rtn++; + length >>= 8; + } + return rtn; +} + +/* encode length */ +DERReturn DEREncodeLength( + DERSize length, + DERByte *buf, /* encoded length goes here */ + DERSize *inOutLen) /* IN/OUT */ +{ + DERByte *lenBytes; + DERSize outLen = DERLengthOfLength(length); + + if(outLen > *inOutLen) { + return DR_BufOverflow; + } + + if(length < 0x80) { + /* short form */ + *buf = (DERByte)length; + *inOutLen = 1; + return DR_Success; + } + + /* long form */ + *buf = (outLen - 1) | 0x80; // length of length, long form indicator + lenBytes = buf + outLen - 1; // l.s. digit of length + while(length != 0) { + *lenBytes-- = (DERByte)length; + length >>= 8; + } + *inOutLen = outLen; + return DR_Success; +} + +DERSize DERLengthOfItem( + DERTag tag, + DERSize length) +{ + return DERLengthOfTag(tag) + DERLengthOfLength(length) + length; +} + +DERReturn DEREncodeItem( + DERTag tag, + DERSize length, + const DERByte *src, + DERByte *derOut, /* encoded item goes here */ + DERSize *inOutLen) /* IN/OUT */ +{ + DERReturn drtn; + DERSize itemLen; + DERByte *currPtr = derOut; + DERSize bytesLeft = DERLengthOfItem(tag, length); + if(bytesLeft > *inOutLen) { + return DR_BufOverflow; + } + *inOutLen = bytesLeft; + + /* top level tag */ + itemLen = bytesLeft; + drtn = DEREncodeTag(tag, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + itemLen = bytesLeft; + drtn = DEREncodeLength(length, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + DERMemmove(currPtr, src, length); + + return DR_Success; +} + +static /* calculate the content length of an encoded sequence */ +DERSize DERContentLengthOfEncodedSequence( + const void *src, /* generally a ptr to a struct full of + * DERItems */ + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs) +{ + DERSize contentLen = 0; + unsigned dex; + DERSize thisContentLen; + + /* find length of each item */ + for(dex=0; dexoptions; + const DERByte *byteSrc = (const DERByte *)src + currItemSpec->offset; + const DERItem *itemSrc = (const DERItem *)byteSrc; + + if(currOptions & DER_ENC_WRITE_DER) { + /* easy case - no encode */ + contentLen += itemSrc->length; + continue; + } + + if ((currOptions & DER_DEC_OPTIONAL) && itemSrc->length == 0) { + /* If an optional item isn't present we don't encode a + tag and len. */ + continue; + } + + /* + * length of this item = + * tag (one byte) + + * length of length + + * content length + + * optional zero byte for signed integer + */ + contentLen += DERLengthOfTag(currItemSpec->tag); + + /* check need for pad byte before calculating lengthOfLength... */ + thisContentLen = itemSrc->length; + if((currOptions & DER_ENC_SIGNED_INT) && + (itemSrc->length != 0)) { + if(itemSrc->data[0] & 0x80) { + /* insert zero keep it positive */ + thisContentLen++; + } + } + contentLen += DERLengthOfLength(thisContentLen); + contentLen += thisContentLen; + } + return contentLen; +} + +DERReturn DEREncodeSequence( + DERTag topTag, /* ASN1_CONSTR_SEQUENCE, ASN1_CONSTR_SET */ + const void *src, /* generally a ptr to a struct full of + * DERItems */ + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + DERByte *derOut, /* encoded data written here */ + DERSize *inOutLen) /* IN/OUT */ +{ + const DERByte *endPtr = derOut + *inOutLen; + DERByte *currPtr = derOut; + DERSize bytesLeft = *inOutLen; + DERSize contentLen; + DERReturn drtn; + DERSize itemLen; + unsigned dex; + + /* top level tag */ + itemLen = bytesLeft; + drtn = DEREncodeTag(topTag, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + if(currPtr >= endPtr) { + return DR_BufOverflow; + } + + /* content length */ + contentLen = DERContentLengthOfEncodedSequence(src, numItems, itemSpecs); + itemLen = bytesLeft; + drtn = DEREncodeLength(contentLen, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + if(currPtr + contentLen > endPtr) { + return DR_BufOverflow; + } + /* we don't have to check for overflow any more */ + + /* grind thru the items */ + for(dex=0; dexoptions; + const DERByte *byteSrc = (const DERByte *)src + currItemSpec->offset; + const DERItem *itemSrc = (const DERItem *)byteSrc; + int prependZero = 0; + + if(currOptions & DER_ENC_WRITE_DER) { + /* easy case */ + DERMemmove(currPtr, itemSrc->data, itemSrc->length); + currPtr += itemSrc->length; + bytesLeft -= itemSrc->length; + continue; + } + + if ((currOptions & DER_DEC_OPTIONAL) && itemSrc->length == 0) { + /* If an optional item isn't present we skip it. */ + continue; + } + + /* encode one item: first the tag */ + itemLen = bytesLeft; + drtn = DEREncodeTag(currItemSpec->tag, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + + /* do we need to prepend a zero to content? */ + contentLen = itemSrc->length; + if((currOptions & DER_ENC_SIGNED_INT) && + (itemSrc->length != 0)) { + if(itemSrc->data[0] & 0x80) { + /* insert zero keep it positive */ + contentLen++; + prependZero = 1; + } + } + + /* encode content length */ + itemLen = bytesLeft; + drtn = DEREncodeLength(contentLen, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + + /* now the content, with possible leading zero added */ + if(prependZero) { + *currPtr++ = 0; + bytesLeft--; + } + DERMemmove(currPtr, itemSrc->data, itemSrc->length); + currPtr += itemSrc->length; + bytesLeft -= itemSrc->length; + } + *inOutLen = (currPtr - derOut); + return DR_Success; +} + +/* calculate the length of an encoded sequence. */ +DERSize DERLengthOfEncodedSequence( + DERTag topTag, + const void *src, /* generally a ptr to a struct full of + * DERItems */ + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs) +{ + DERSize contentLen = DERContentLengthOfEncodedSequence( + src, numItems, itemSpecs); + + return DERLengthOfTag(topTag) + + DERLengthOfLength(contentLen) + + contentLen; +} + +#endif /* DER_ENCODE_ENABLE */ + diff --git a/Library/OcAppleDerLib/libDER/DER_Encode.h b/Library/OcAppleDerLib/libDER/DER_Encode.h new file mode 100644 index 00000000..171747e1 --- /dev/null +++ b/Library/OcAppleDerLib/libDER/DER_Encode.h @@ -0,0 +1,103 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * DER_Encode.h - DER encoding routines + * + * Created Dec. 2 2005 by dmitch + */ + +#ifndef _DER_ENCODE_H_ +#define _DER_ENCODE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libDER.h" + +/* + * Max size of an encoded item given its length. + * This includes a possible leading zero prepended to a signed integer + * (see DER_ENC_SIGNED_INT below). + */ +#define DER_MAX_ENCODED_SIZE(len) \ + ( 1 + /* tag */ \ + 5 + /* max length */ \ + 1 + /* possible prepended zero */ \ + len) + +/* calculate size of encoded length */ +DERSize DERLengthOfLength( + DERSize length); + +/* encode length */ +DERReturn DEREncodeLength( + DERSize length, + DERByte *buf, /* encoded length goes here */ + DERSize *inOutLen); /* IN/OUT */ + +/* calculate size of encoded length */ +DERSize DERLengthOfItem( + DERTag tag, + DERSize length); + +/* encode item */ +DERReturn DEREncodeItem( + DERTag tag, + DERSize length, + const DERByte *src, + DERByte *derOut, /* encoded item goes here */ + DERSize *inOutLen); /* IN/OUT */ + +/* + * Per-item encode options. + */ + +/* explicit default, no options */ +#define DER_ENC_NO_OPTS 0x0000 + +/* signed integer check: if incoming m.s. bit is 1, prepend a zero */ +#define DER_ENC_SIGNED_INT 0x0100 + +/* DERItem contains fully encoded item - copy, don't encode */ +#define DER_ENC_WRITE_DER 0x0200 + + +/* + * High-level sequence or set encode support. + * + * The outgoing sequence is expressed as an array of DERItemSpecs, each + * of which corresponds to one item in the encoded sequence. + * + * Normally the tag of the encoded item comes from the associated + * DERItemSpec, and the content comes from the DERItem whose address is + * the src arg plus the offset value in the associated DERItemSpec. + * + * If the DER_ENC_WRITE_DER option is true for a given DERItemSpec then + * no per-item encoding is done; the DER - with tag, length, and content - + * is taken en masse from the associated DERItem. + */ +DERReturn DEREncodeSequence( + DERTag topTag, /* ASN1_CONSTR_SEQUENCE, ASN1_CONSTR_SET */ + const void *src, /* generally a ptr to a struct full of + * DERItems */ + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + DERByte *derOut, /* encoded data written here */ + DERSize *inOutLen); /* IN/OUT */ + +/* precalculate the length of an encoded sequence. */ +DERSize DERLengthOfEncodedSequence( + DERTag topTag, /* ASN1_CONSTR_SEQUENCE, ASN1_CONSTR_SET */ + const void *src, /* generally a ptr to a struct full of + * DERItems */ + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs); + + +#ifdef __cplusplus +} +#endif + +#endif /* _DER_DECODE_H_ */ + diff --git a/Library/OcAppleDerLib/libDER/DER_Keys.c b/Library/OcAppleDerLib/libDER/DER_Keys.c new file mode 100644 index 00000000..c74fb02b --- /dev/null +++ b/Library/OcAppleDerLib/libDER/DER_Keys.c @@ -0,0 +1,167 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * DER_Cert.c - support for decoding RSA keys + * + * Created Nov. 8 2005 by Doug Mitchell. + */ + +#include "DER_Decode.h" +#include "DER_Encode.h" +#include "DER_Keys.h" +#include "asn1Types.h" +#include "libDER_config.h" + +#ifndef DER_DECODE_ENABLE +#error Please define DER_DECODE_ENABLE. +#endif +#if DER_DECODE_ENABLE + +/* + * DERItemSpecs for decoding RSA keys. + */ + +/* Algorithm Identifier */ +const DERItemSpec DERAlgorithmIdItemSpecs[] = +{ + { DER_OFFSET(DERAlgorithmId, oid), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERAlgorithmId, params), + 0, /* no tag - any */ + DER_DEC_ASN_ANY | DER_DEC_OPTIONAL | DER_DEC_SAVE_DER } +}; +const DERSize DERNumAlgorithmIdItemSpecs = + sizeof(DERAlgorithmIdItemSpecs) / sizeof(DERItemSpec); + +/* X509 SubjectPublicKeyInfo */ +const DERItemSpec DERSubjPubKeyInfoItemSpecs[] = +{ + { DER_OFFSET(DERSubjPubKeyInfo, algId), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERSubjPubKeyInfo, pubKey), + ASN1_BIT_STRING, + DER_DEC_NO_OPTS }, + +}; +const DERSize DERNumSubjPubKeyInfoItemSpecs = + sizeof(DERSubjPubKeyInfoItemSpecs) / sizeof(DERItemSpec); + +/* + * RSA private key in CRT format + */ +const DERItemSpec DERRSAPrivKeyCRTItemSpecs[] = +{ + /* version, n, e, d - skip */ + { 0, + ASN1_INTEGER, + DER_DEC_SKIP }, + { 0, + ASN1_INTEGER, + DER_DEC_SKIP }, + { 0, + ASN1_INTEGER, + DER_DEC_SKIP }, + { 0, + ASN1_INTEGER, + DER_DEC_SKIP }, + { DER_OFFSET(DERRSAPrivKeyCRT, p), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERRSAPrivKeyCRT, q), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERRSAPrivKeyCRT, dp), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERRSAPrivKeyCRT, dq), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERRSAPrivKeyCRT, qInv), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + /* ignore the (optional) rest */ +}; +const DERSize DERNumRSAPrivKeyCRTItemSpecs = + sizeof(DERRSAPrivKeyCRTItemSpecs) / sizeof(DERItemSpec); + +#endif /* DER_DECODE_ENABLE */ + +#if DER_DECODE_ENABLE || DER_ENCODE_ENABLE + +/* RSA public key in PKCS1 format - encode and decode */ +const DERItemSpec DERRSAPubKeyPKCS1ItemSpecs[] = +{ + { DER_OFFSET(DERRSAPubKeyPKCS1, modulus), + ASN1_INTEGER, + DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAPubKeyPKCS1, pubExponent), + ASN1_INTEGER, + DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, +}; +const DERSize DERNumRSAPubKeyPKCS1ItemSpecs = + sizeof(DERRSAPubKeyPKCS1ItemSpecs) / sizeof(DERItemSpec); + +/* RSA public key in Apple custome format with reciprocal - encode and decode */ +const DERItemSpec DERRSAPubKeyAppleItemSpecs[] = +{ + { DER_OFFSET(DERRSAPubKeyApple, modulus), + ASN1_INTEGER, + DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAPubKeyApple, reciprocal), + ASN1_INTEGER, + DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAPubKeyApple, pubExponent), + ASN1_INTEGER, + DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, +}; +const DERSize DERNumRSAPubKeyAppleItemSpecs = + sizeof(DERRSAPubKeyAppleItemSpecs) / sizeof(DERItemSpec); + + +#endif /* DER_DECODE_ENABLE || DER_ENCODE_ENABLE */ + +#ifndef DER_ENCODE_ENABLE +#error Please define DER_ENCODE_ENABLE. +#endif + +#if DER_ENCODE_ENABLE + +/* RSA Key Pair, encode only */ +const DERItemSpec DERRSAKeyPairItemSpecs[] = +{ + { DER_OFFSET(DERRSAKeyPair, version), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, n), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, e), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, d), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, p), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, q), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, dp), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, dq), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, qInv), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, +}; + +const DERSize DERNumRSAKeyPairItemSpecs = + sizeof(DERRSAKeyPairItemSpecs) / sizeof(DERItemSpec); + +#endif /* DER_ENCODE_ENABLE */ + diff --git a/Library/OcAppleDerLib/libDER/DER_Keys.h b/Library/OcAppleDerLib/libDER/DER_Keys.h new file mode 100644 index 00000000..a2a5f27f --- /dev/null +++ b/Library/OcAppleDerLib/libDER/DER_Keys.h @@ -0,0 +1,104 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * DER_Keys.h - support for decoding RSA keys + * + * Created Nov. 8 2005 by dmitch + */ + +#ifndef _DER_KEYS_H_ +#define _DER_KEYS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libDER.h" +#include "DER_Decode.h" + +/* Algorithm Identifier components */ +typedef struct { + DERItem oid; /* OID */ + DERItem params; /* ASN_ANY, optional, DER_DEC_SAVE_DER */ +} DERAlgorithmId; + +/* DERItemSpecs to decode into a DERAlgorithmId */ +extern const DERItemSpec DERAlgorithmIdItemSpecs[]; +extern const DERSize DERNumAlgorithmIdItemSpecs; + +/* X509 SubjectPublicKeyInfo */ +typedef struct { + DERItem algId; /* sequence, DERAlgorithmId */ + DERItem pubKey; /* BIT STRING */ +} DERSubjPubKeyInfo; + +/* DERItemSpecs to decode into a DERSubjPubKeyInfo */ +extern const DERItemSpec DERSubjPubKeyInfoItemSpecs[]; +extern const DERSize DERNumSubjPubKeyInfoItemSpecs; + +/* + * RSA public key in PKCS1 format; this is inside the BIT_STRING in + * DERSubjPubKeyInfo.pubKey. + */ +typedef struct { + DERItem modulus; /* n - INTEGER */ + DERItem pubExponent; /* e - INTEGER */ +} DERRSAPubKeyPKCS1; + +/* DERItemSpecs to decode/encode into/from a DERRSAPubKeyPKCS1 */ +extern const DERItemSpec DERRSAPubKeyPKCS1ItemSpecs[]; +extern const DERSize DERNumRSAPubKeyPKCS1ItemSpecs; + +/* + * RSA public key in custom (to this library) format, including + * the reciprocal. All fields are integers. + */ +typedef struct { + DERItem modulus; /* n */ + DERItem reciprocal; /* reciprocal of modulus */ + DERItem pubExponent; /* e */ +} DERRSAPubKeyApple; + +/* DERItemSpecs to decode/encode into/from a DERRSAPubKeyApple */ +extern const DERItemSpec DERRSAPubKeyAppleItemSpecs[]; +extern const DERSize DERNumRSAPubKeyAppleItemSpecs; + +/* + * RSA Private key, PKCS1 format, CRT option. + * All fields are integers. + */ +typedef struct { + DERItem p; /* p * q = n */ + DERItem q; + DERItem dp; /* d mod (p-1) */ + DERItem dq; /* d mod (q-1) */ + DERItem qInv; +} DERRSAPrivKeyCRT; + +/* DERItemSpecs to decode into a DERRSAPrivKeyCRT */ +extern const DERItemSpec DERRSAPrivKeyCRTItemSpecs[]; +extern const DERSize DERNumRSAPrivKeyCRTItemSpecs; + +/* Fully formed RSA key pair, for generating a PKCS1 private key */ +typedef struct { + DERItem version; + DERItem n; /* modulus */ + DERItem e; /* public exponent */ + DERItem d; /* private exponent */ + DERItem p; /* n = p*q */ + DERItem q; + DERItem dp; /* d mod (p-1) */ + DERItem dq; /* d mod (q-1) */ + DERItem qInv; /* q^(-1) mod p */ +} DERRSAKeyPair; + +/* DERItemSpecs to encode a DERRSAKeyPair */ +extern const DERItemSpec DERRSAKeyPairItemSpecs[]; +extern const DERSize DERNumRSAKeyPairItemSpecs; + +#ifdef __cplusplus +} +#endif + +#endif /* _DER_KEYS_H_ */ + diff --git a/Library/OcAppleDerLib/libDER/asn1Types.h b/Library/OcAppleDerLib/libDER/asn1Types.h new file mode 100644 index 00000000..1bf25983 --- /dev/null +++ b/Library/OcAppleDerLib/libDER/asn1Types.h @@ -0,0 +1,91 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * asn1Types.h - ASN.1/DER #defines - strictly hard coded per the real world + * + * Created Nov. 4 2005 by dmitch + */ + +#ifndef _ASN1_TYPES_H_ +#define _ASN1_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* copied from libsecurity_asn1 project */ + +#define ASN1_BOOLEAN 0x01 +#define ASN1_INTEGER 0x02 +#define ASN1_BIT_STRING 0x03 +#define ASN1_OCTET_STRING 0x04 +#define ASN1_NULL 0x05 +#define ASN1_OBJECT_ID 0x06 +#define ASN1_OBJECT_DESCRIPTOR 0x07 +/* External type and instance-of type 0x08 */ +#define ASN1_REAL 0x09 +#define ASN1_ENUMERATED 0x0a +#define ASN1_EMBEDDED_PDV 0x0b +#define ASN1_UTF8_STRING 0x0c +/* 0x0d */ +/* 0x0e */ +/* 0x0f */ +#define ASN1_SEQUENCE 0x10 +#define ASN1_SET 0x11 +#define ASN1_NUMERIC_STRING 0x12 +#define ASN1_PRINTABLE_STRING 0x13 +#define ASN1_T61_STRING 0x14 +#define ASN1_VIDEOTEX_STRING 0x15 +#define ASN1_IA5_STRING 0x16 +#define ASN1_UTC_TIME 0x17 +#define ASN1_GENERALIZED_TIME 0x18 +#define ASN1_GRAPHIC_STRING 0x19 +#define ASN1_VISIBLE_STRING 0x1a +#define ASN1_GENERAL_STRING 0x1b +#define ASN1_UNIVERSAL_STRING 0x1c +/* 0x1d */ +#define ASN1_BMP_STRING 0x1e +#define ASN1_HIGH_TAG_NUMBER 0x1f +#define ASN1_TELETEX_STRING ASN1_T61_STRING + +#ifdef DER_MULTIBYTE_TAGS + +#define ASN1_TAG_MASK ((DERTag)~0) +#define ASN1_TAGNUM_MASK ((DERTag)~((DERTag)7 << (sizeof(DERTag) * 8 - 3))) + +#define ASN1_METHOD_MASK ((DERTag)1 << (sizeof(DERTag) * 8 - 3)) +#define ASN1_PRIMITIVE ((DERTag)0 << (sizeof(DERTag) * 8 - 3)) +#define ASN1_CONSTRUCTED ((DERTag)1 << (sizeof(DERTag) * 8 - 3)) + +#define ASN1_CLASS_MASK ((DERTag)3 << (sizeof(DERTag) * 8 - 2)) +#define ASN1_UNIVERSAL ((DERTag)0 << (sizeof(DERTag) * 8 - 2)) +#define ASN1_APPLICATION ((DERTag)1 << (sizeof(DERTag) * 8 - 2)) +#define ASN1_CONTEXT_SPECIFIC ((DERTag)2 << (sizeof(DERTag) * 8 - 2)) +#define ASN1_PRIVATE ((DERTag)3 << (sizeof(DERTag) * 8 - 2)) + +#else /* DER_MULTIBYTE_TAGS */ + +#define ASN1_TAG_MASK 0xff +#define ASN1_TAGNUM_MASK 0x1f +#define ASN1_METHOD_MASK 0x20 +#define ASN1_PRIMITIVE 0x00 +#define ASN1_CONSTRUCTED 0x20 + +#define ASN1_CLASS_MASK 0xc0 +#define ASN1_UNIVERSAL 0x00 +#define ASN1_APPLICATION 0x40 +#define ASN1_CONTEXT_SPECIFIC 0x80 +#define ASN1_PRIVATE 0xc0 + +#endif /* !DER_MULTIBYTE_TAGS */ + +/* sequence and set appear as the following */ +#define ASN1_CONSTR_SEQUENCE (ASN1_CONSTRUCTED | ASN1_SEQUENCE) +#define ASN1_CONSTR_SET (ASN1_CONSTRUCTED | ASN1_SET) + +#ifdef __cplusplus +} +#endif + +#endif /* _ASN1_TYPES_H_ */ + diff --git a/Library/OcAppleDerLib/libDER/libDER.h b/Library/OcAppleDerLib/libDER/libDER.h new file mode 100644 index 00000000..dd1fd732 --- /dev/null +++ b/Library/OcAppleDerLib/libDER/libDER.h @@ -0,0 +1,65 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * libDER.h - main header for libDER, a ROM-capable DER decoding library. + * + * Created Nov. 4 2005 by dmitch + */ + +#ifndef _LIB_DER_H_ +#define _LIB_DER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libDER_config.h" +/* + * Error returns generated by this library. + */ +typedef enum { + DR_Success, + DR_EndOfSequence, /* end of sequence or set */ + DR_UnexpectedTag, /* unexpected tag found while decoding */ + DR_DecodeError, /* misc. decoding error (badly formatted DER) */ + DR_Unimplemented, /* function not implemented in this configuration */ + DR_IncompleteSeq, /* incomplete sequence */ + DR_ParamErr, /* incoming parameter error */ + DR_BufOverflow /* buffer overflow */ + /* etc. */ +} DERReturn; + +/* + * Primary representation of a block of memory. + */ +typedef struct { + DERByte *data; + DERSize length; +} DERItem; + +/* + * The structure of a sequence during decode or encode is expressed as + * an array of DERItemSpecs. While decoding or encoding a sequence, + * each item in the sequence corresponds to one DERItemSpec. + */ +typedef struct { + DERSize offset; /* offset of destination DERItem */ + DERTag tag; /* DER tag */ + DERShort options; /* DER_DEC_xxx or DER_ENC_xxx */ +} DERItemSpec; + +/* + * Macro to obtain offset of a DERDecodedInfo within a struct. + * FIXME this is going to need reworking to avoid compiler warnings + * on 64-bit compiles. It'll work OK as long as an offset can't be larger + * than a DERSize, but the cast from a pointer to a DERSize may + * provoke compiler warnings. + */ +#define DER_OFFSET(type, field) ((DERSize)(&((type *)0)->field)) + +#ifdef __cplusplus +} +#endif + +#endif /* _LIB_DER_H_ */ + diff --git a/Library/OcAppleDerLib/libDER/oids.c b/Library/OcAppleDerLib/libDER/oids.c new file mode 100644 index 00000000..569ee0b5 --- /dev/null +++ b/Library/OcAppleDerLib/libDER/oids.c @@ -0,0 +1,466 @@ +/* Copyright (c) 2005-2009 Apple Inc. All Rights Reserved. */ + +/* + * oids.c - OID consts + * + * Created Nov. 11 2005 by dmitch + */ + +#include "libDER.h" +#include "oids.h" + +#define OID_ISO_CCITT_DIR_SERVICE 85 +#define OID_DS OID_ISO_CCITT_DIR_SERVICE +#define OID_ATTR_TYPE OID_DS, 4 +#define OID_EXTENSION OID_DS, 29 +#define OID_ISO_STANDARD 40 +#define OID_ISO_MEMBER 42 +#define OID_US OID_ISO_MEMBER, 134, 72 + +#define OID_ISO_IDENTIFIED_ORG 43 +#define OID_OSINET OID_ISO_IDENTIFIED_ORG, 4 +#define OID_GOSIP OID_ISO_IDENTIFIED_ORG, 5 +#define OID_DOD OID_ISO_IDENTIFIED_ORG, 6 +#define OID_OIW OID_ISO_IDENTIFIED_ORG, 14 + +/* From the PKCS Standards */ +#define OID_RSA OID_US, 134, 247, 13 +#define OID_RSA_HASH OID_RSA, 2 +#define OID_RSA_ENCRYPT OID_RSA, 3 +#define OID_PKCS OID_RSA, 1 +#define OID_PKCS_1 OID_PKCS, 1 +#define OID_PKCS_2 OID_PKCS, 2 +#define OID_PKCS_3 OID_PKCS, 3 +#define OID_PKCS_4 OID_PKCS, 4 +#define OID_PKCS_5 OID_PKCS, 5 +#define OID_PKCS_6 OID_PKCS, 6 +#define OID_PKCS_7 OID_PKCS, 7 +#define OID_PKCS_8 OID_PKCS, 8 +#define OID_PKCS_9 OID_PKCS, 9 +#define OID_PKCS_10 OID_PKCS, 10 +#define OID_PKCS_11 OID_PKCS, 11 +#define OID_PKCS_12 OID_PKCS, 12 + +/* ANSI X9.62 */ +#define OID_ANSI_X9_62 OID_US, 206, 61 +#define OID_PUBLIC_KEY_TYPE OID_ANSI_X9_62, 2 +#define OID_EC_SIG_TYPE OID_ANSI_X9_62, 4 +#define OID_ECDSA_WITH_SHA2 OID_EC_SIG_TYPE, 3 + +/* ANSI X9.42 */ +#define OID_ANSI_X9_42 OID_US, 206, 62, 2 +#define OID_ANSI_X9_42_SCHEME OID_ANSI_X9_42, 3 +#define OID_ANSI_X9_42_NAMED_SCHEME OID_ANSI_X9_42, 4 + +/* DOD IANA Security releated objects. */ +#define OID_IANA OID_DOD, 1, 5 + +/* Kerberos PKINIT */ +#define OID_KERBv5 OID_IANA, 2 +#define OID_KERBv5_PKINIT OID_KERBv5, 3 + +/* DOD IANA Mechanisms. */ +#define OID_MECHANISMS OID_IANA, 5 + +/* PKIX */ +#define OID_PKIX OID_MECHANISMS, 7 +#define OID_PE OID_PKIX, 1 +#define OID_QT OID_PKIX, 2 +#define OID_KP OID_PKIX, 3 +#define OID_OTHER_NAME OID_PKIX, 8 +#define OID_PDA OID_PKIX, 9 +#define OID_QCS OID_PKIX, 11 +#define OID_AD OID_PKIX, 48 +#define OID_AD_OCSP OID_AD, 1 +#define OID_AD_CAISSUERS OID_AD, 2 + +/* ISAKMP */ +#define OID_ISAKMP OID_MECHANISMS, 8 + +/* ETSI */ +#define OID_ETSI 0x04, 0x00 +#define OID_ETSI_QCS 0x04, 0x00, 0x8E, 0x46, 0x01 + +#define OID_OIW_SECSIG OID_OIW, 3 + +#define OID_OIW_ALGORITHM OID_OIW_SECSIG, 2 + +/* NIST defined digest algorithm arc (2, 16, 840, 1, 101, 3, 4, 2) */ +#define OID_NIST_HASHALG 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02 + +/* + * Apple-specific OID bases + */ + +/* + * apple OBJECT IDENTIFIER ::= + * { iso(1) member-body(2) US(840) 113635 } + * + * BER = 06 06 2A 86 48 86 F7 63 + */ +#define APPLE_OID OID_US, 0x86, 0xf7, 0x63 + +/* appleDataSecurity OBJECT IDENTIFIER ::= + * { apple 100 } + * { 1 2 840 113635 100 } + * + * BER = 06 07 2A 86 48 86 F7 63 64 + */ +#define APPLE_ADS_OID APPLE_OID, 0x64 + +/* + * appleTrustPolicy OBJECT IDENTIFIER ::= + * { appleDataSecurity 1 } + * { 1 2 840 113635 100 1 } + * + * BER = 06 08 2A 86 48 86 F7 63 64 01 + */ +#define APPLE_TP_OID APPLE_ADS_OID, 1 + +/* + * appleSecurityAlgorithm OBJECT IDENTIFIER ::= + * { appleDataSecurity 2 } + * { 1 2 840 113635 100 2 } + * + * BER = 06 08 2A 86 48 86 F7 63 64 02 + */ +#define APPLE_ALG_OID APPLE_ADS_OID, 2 + +/* + * appleDotMacCertificate OBJECT IDENTIFIER ::= + * { appleDataSecurity 3 } + * { 1 2 840 113635 100 3 } + */ +#define APPLE_DOTMAC_CERT_OID APPLE_ADS_OID, 3 + +/* + * Basis of Policy OIDs for .mac TP requests + * + * dotMacCertificateRequest OBJECT IDENTIFIER ::= + * { appleDotMacCertificate 1 } + * { 1 2 840 113635 100 3 1 } + */ +#define APPLE_DOTMAC_CERT_REQ_OID APPLE_DOTMAC_CERT_OID, 1 + +/* + * Basis of .mac Certificate Extensions + * + * dotMacCertificateExtension OBJECT IDENTIFIER ::= + * { appleDotMacCertificate 2 } + * { 1 2 840 113635 100 3 2 } + */ +#define APPLE_DOTMAC_CERT_EXTEN_OID APPLE_DOTMAC_CERT_OID, 2 + +/* + * Basis of .mac Certificate request OID/value identitifiers + * + * dotMacCertificateRequestValues OBJECT IDENTIFIER ::= + * { appleDotMacCertificate 3 } + * { 1 2 840 113635 100 3 3 } + */ +#define APPLE_DOTMAC_CERT_REQ_VALUE_OID APPLE_DOTMAC_CERT_OID, 3 + +/* + * Basis of Apple-specific extended key usages + * + * appleExtendedKeyUsage OBJECT IDENTIFIER ::= + * { appleDataSecurity 4 } + * { 1 2 840 113635 100 4 } + */ +#define APPLE_EKU_OID APPLE_ADS_OID, 4 + +/* + * Basis of Apple Code Signing extended key usages + * appleCodeSigning OBJECT IDENTIFIER ::= + * { appleExtendedKeyUsage 1 } + * { 1 2 840 113635 100 4 1} + */ +#define APPLE_EKU_CODE_SIGNING APPLE_EKU_OID, 1 +#define APPLE_EKU_APPLE_ID APPLE_EKU_OID, 7 + +/* + * Basis of Apple-specific Certific Policy IDs. + * appleCertificatePolicies OBJECT IDENTIFIER ::= + * { appleDataSecurity 5 } + * { 1 2 840 113635 100 5 } + */ +#define APPLE_CERT_POLICIES APPLE_ADS_OID, 5 + +/* + * Basis of Apple-specific Signing extensions + * { appleDataSecurity 6 } + */ +#define APPLE_CERT_EXT APPLE_ADS_OID, 6 +/* Apple Intermediate Marker OIDs */ +#define APPLE_CERT_EXT_INTERMEDIATE_MARKER APPLE_CERT_EXT, 2 +/* Apple Apple ID Intermediate Marker */ +#define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID APPLE_CERT_EXT_INTERMEDIATE_MARKER, 3 + +/* Secure Boot Embedded Image3 value, + co-opted by desktop for "Apple Released Code Signature", without value */ +#define APPLE_SBOOT_CERT_EXTEN_SBOOT_SPEC_OID APPLE_ADS_OID, 6, 1, 1 +/* iPhone Provisioning Profile Signing leaf */ +#define APPLE_PROVISIONING_PROFILE_OID APPLE_ADS_OID, 6, 2, 2, 1 +/* iPhone Application Signing leaf */ +#define APPLE_APP_SIGINING_OID APPLE_ADS_OID, 6, 1, 3 + +/* + * Netscape OIDs. + */ +#define NETSCAPE_BASE_OID 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42 + +/* + * Netscape cert extension. + * + * netscape-cert-extension OBJECT IDENTIFIER ::= + * { 2 16 840 1 113730 1 } + * + * BER = 06 08 60 86 48 01 86 F8 42 01 + */ +#define NETSCAPE_CERT_EXTEN NETSCAPE_BASE_OID, 0x01 + +#define NETSCAPE_CERT_POLICY NETSCAPE_BASE_OID, 0x04 + +/* Entrust OIDs. */ +#define ENTRUST_BASE_OID OID_US, 0x86, 0xf6, 0x7d + +/* + * Entrust cert extension. + * + * entrust-cert-extension OBJECT IDENTIFIER ::= + * { 1 2 840 113533 7 65 } + * + * BER = 06 08 2A 86 48 86 F6 7D 07 41 + */ +#define ENTRUST_CERT_EXTEN ENTRUST_BASE_OID, 0x07, 0x41 + +/* Microsfot OIDs. */ +#define MICROSOFT_BASE_OID OID_DOD, 0x01, 0x04, 0x01, 0x82, 0x37 +#define MICROSOFT_ENROLLMENT_OID MICROSOFT_BASE_OID, 0x14 + +/* Algorithm OIDs. */ +static const DERByte + _oidRsa[] = { OID_PKCS_1, 1 }, + _oidMd2Rsa[] = { OID_PKCS_1, 2 }, + _oidMd5Rsa[] = { OID_PKCS_1, 4 }, + _oidSha1Rsa[] = { OID_PKCS_1, 5 }, + _oidSha256Rsa[] = { OID_PKCS_1, 11 }, + _oidEcPubKey[] = { OID_PUBLIC_KEY_TYPE, 1 }, + _oidSha1Ecdsa[] = { OID_EC_SIG_TYPE, 1 }, /* rfc3279 */ + _oidSha224Ecdsa[] = { OID_ECDSA_WITH_SHA2, 1 }, /* rfc5758 */ + _oidSha256Ecdsa[] = { OID_ECDSA_WITH_SHA2, 2 }, /* rfc5758 */ + _oidSha384Ecdsa[] = { OID_ECDSA_WITH_SHA2, 3 }, /* rfc5758 */ + _oidSha512Ecdsa[] = { OID_ECDSA_WITH_SHA2, 4 }, /* rfc5758 */ + _oidMd2[] = { OID_RSA_HASH, 2 }, + _oidMd4[] = { OID_RSA_HASH, 4 }, + _oidMd5[] = { OID_RSA_HASH, 5 }, + _oidSha1[] = { OID_OIW_ALGORITHM, 26 }, + _oidSha256[] = { OID_NIST_HASHALG, 1 }, + _oidSha384[] = { OID_NIST_HASHALG, 2 }, + _oidSha512[] = { OID_NIST_HASHALG, 3 }, + _oidSha224[] = { OID_NIST_HASHALG, 4 }; + +const DERItem + oidRsa = { (DERByte *)_oidRsa, + sizeof(_oidRsa) }, + oidMd2Rsa = { (DERByte *)_oidMd2Rsa, + sizeof(_oidMd2Rsa) }, + oidMd5Rsa = { (DERByte *)_oidMd5Rsa, + sizeof(_oidMd5Rsa) }, + oidSha1Rsa = { (DERByte *)_oidSha1Rsa, + sizeof(_oidSha1Rsa) }, + oidSha256Rsa = { (DERByte *)_oidSha256Rsa, + sizeof(_oidSha256Rsa) }, + oidEcPubKey = { (DERByte *)_oidEcPubKey, + sizeof(_oidEcPubKey) }, + oidSha1Ecdsa = { (DERByte *)_oidSha1Ecdsa, + sizeof(_oidSha1Ecdsa) }, + oidSha224Ecdsa = { (DERByte *)_oidSha224Ecdsa, + sizeof(_oidSha224Ecdsa) }, + oidSha256Ecdsa = { (DERByte *)_oidSha256Ecdsa, + sizeof(_oidSha256Ecdsa) }, + oidSha384Ecdsa = { (DERByte *)_oidSha384Ecdsa, + sizeof(_oidSha384Ecdsa) }, + oidSha512Ecdsa = { (DERByte *)_oidSha512Ecdsa, + sizeof(_oidSha512Ecdsa) }, + oidMd2 = { (DERByte *)_oidMd2, + sizeof(_oidMd2) }, + oidMd4 = { (DERByte *)_oidMd4, + sizeof(_oidMd4) }, + oidMd5 = { (DERByte *)_oidMd5, + sizeof(_oidMd5) }, + oidSha1 = { (DERByte *)_oidSha1, + sizeof(_oidSha1) }, + oidSha256 = { (DERByte *)_oidSha256, + sizeof(_oidSha256) }, + oidSha384 = { (DERByte *)_oidSha384, + sizeof(_oidSha384) }, + oidSha512 = { (DERByte *)_oidSha512, + sizeof(_oidSha512) }, + oidSha224 = { (DERByte *)_oidSha224, + sizeof(_oidSha224) }; + +/* Extension OIDs. */ +static const DERByte + _oidSubjectKeyIdentifier[] = { OID_EXTENSION, 14 }, + _oidKeyUsage[] = { OID_EXTENSION, 15 }, + _oidPrivateKeyUsagePeriod[] = { OID_EXTENSION, 16 }, + _oidSubjectAltName[] = { OID_EXTENSION, 17 }, + _oidIssuerAltName[] = { OID_EXTENSION, 18 }, + _oidBasicConstraints[] = { OID_EXTENSION, 19 }, + _oidCrlDistributionPoints[] = { OID_EXTENSION, 31 }, + _oidCertificatePolicies[] = { OID_EXTENSION, 32 }, + _oidAnyPolicy[] = { OID_EXTENSION, 32, 0 }, + _oidPolicyMappings[] = { OID_EXTENSION, 33 }, + _oidAuthorityKeyIdentifier[] = { OID_EXTENSION, 35 }, + _oidPolicyConstraints[] = { OID_EXTENSION, 36 }, + _oidExtendedKeyUsage[] = { OID_EXTENSION, 37 }, + _oidAnyExtendedKeyUsage[] = { OID_EXTENSION, 37, 0 }, + _oidInhibitAnyPolicy[] = { OID_EXTENSION, 54 }, + _oidAuthorityInfoAccess[] = { OID_PE, 1 }, + _oidSubjectInfoAccess[] = { OID_PE, 11 }, + _oidAdOCSP[] = { OID_AD_OCSP }, + _oidAdCAIssuer[] = { OID_AD_CAISSUERS }, + _oidNetscapeCertType[] = { NETSCAPE_CERT_EXTEN, 1 }, + _oidEntrustVersInfo[] = { ENTRUST_CERT_EXTEN, 0 }, + _oidMSNTPrincipalName[] = { MICROSOFT_ENROLLMENT_OID, 2, 3 }, + /* Policy Qualifier IDs for Internet policy qualifiers. */ + _oidQtCps[] = { OID_QT, 1 }, + _oidQtUNotice[] = { OID_QT, 2 }, + /* X.501 Name IDs. */ + _oidCommonName[] = { OID_ATTR_TYPE, 3 }, + _oidCountryName[] = { OID_ATTR_TYPE, 6 }, + _oidLocalityName[] = { OID_ATTR_TYPE, 7 }, + _oidStateOrProvinceName[] = { OID_ATTR_TYPE, 8 }, + _oidOrganizationName[] = { OID_ATTR_TYPE, 10 }, + _oidOrganizationalUnitName[] = { OID_ATTR_TYPE, 11 }, + _oidDescription[] = { OID_ATTR_TYPE, 13 }, + _oidEmailAddress[] = { OID_PKCS_9, 1 }, + _oidFriendlyName[] = { OID_PKCS_9, 20 }, + _oidLocalKeyId[] = { OID_PKCS_9, 21 }, + _oidExtendedKeyUsageServerAuth[] = { OID_KP, 1 }, + _oidExtendedKeyUsageClientAuth[] = { OID_KP, 2 }, + _oidExtendedKeyUsageCodeSigning[] = { OID_KP, 3 }, + _oidExtendedKeyUsageEmailProtection[] = { OID_KP, 4 }, + _oidExtendedKeyUsageOCSPSigning[] = { OID_KP, 9 }, + _oidExtendedKeyUsageIPSec[] = { OID_ISAKMP, 2, 2 }, + _oidExtendedKeyUsageMicrosoftSGC[] = { MICROSOFT_BASE_OID, 10, 3, 3 }, + _oidExtendedKeyUsageNetscapeSGC[] = { NETSCAPE_CERT_POLICY, 1 }, + _oidAppleSecureBootCertSpec[] = { APPLE_SBOOT_CERT_EXTEN_SBOOT_SPEC_OID }, + _oidAppleProvisioningProfile[] = {APPLE_PROVISIONING_PROFILE_OID }, + _oidAppleApplicationSigning[] = { APPLE_APP_SIGINING_OID }, + _oidAppleExtendedKeyUsageAppleID[] = { APPLE_EKU_APPLE_ID }, + _oidAppleIntmMarkerAppleID[] = { APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID }; + +const DERItem + oidSubjectKeyIdentifier = { (DERByte *)_oidSubjectKeyIdentifier, + sizeof(_oidSubjectKeyIdentifier) }, + oidKeyUsage = { (DERByte *)_oidKeyUsage, + sizeof(_oidKeyUsage) }, + oidPrivateKeyUsagePeriod = { (DERByte *)_oidPrivateKeyUsagePeriod, + sizeof(_oidPrivateKeyUsagePeriod) }, + oidSubjectAltName = { (DERByte *)_oidSubjectAltName, + sizeof(_oidSubjectAltName) }, + oidIssuerAltName = { (DERByte *)_oidIssuerAltName, + sizeof(_oidIssuerAltName) }, + oidBasicConstraints = { (DERByte *)_oidBasicConstraints, + sizeof(_oidBasicConstraints) }, + oidCrlDistributionPoints = { (DERByte *)_oidCrlDistributionPoints, + sizeof(_oidCrlDistributionPoints) }, + oidCertificatePolicies = { (DERByte *)_oidCertificatePolicies, + sizeof(_oidCertificatePolicies) }, + oidAnyPolicy = { (DERByte *)_oidAnyPolicy, + sizeof(_oidAnyPolicy) }, + oidPolicyMappings = { (DERByte *)_oidPolicyMappings, + sizeof(_oidPolicyMappings) }, + oidAuthorityKeyIdentifier = { (DERByte *)_oidAuthorityKeyIdentifier, + sizeof(_oidAuthorityKeyIdentifier) }, + oidPolicyConstraints = { (DERByte *)_oidPolicyConstraints, + sizeof(_oidPolicyConstraints) }, + oidExtendedKeyUsage = { (DERByte *)_oidExtendedKeyUsage, + sizeof(_oidExtendedKeyUsage) }, + oidAnyExtendedKeyUsage = { (DERByte *)_oidAnyExtendedKeyUsage, + sizeof(_oidAnyExtendedKeyUsage) }, + oidInhibitAnyPolicy = { (DERByte *)_oidInhibitAnyPolicy, + sizeof(_oidInhibitAnyPolicy) }, + oidAuthorityInfoAccess = { (DERByte *)_oidAuthorityInfoAccess, + sizeof(_oidAuthorityInfoAccess) }, + oidSubjectInfoAccess = { (DERByte *)_oidSubjectInfoAccess, + sizeof(_oidSubjectInfoAccess) }, + oidAdOCSP = { (DERByte *)_oidAdOCSP, + sizeof(_oidAdOCSP) }, + oidAdCAIssuer = { (DERByte *)_oidAdCAIssuer, + sizeof(_oidAdCAIssuer) }, + oidNetscapeCertType = { (DERByte *)_oidNetscapeCertType, + sizeof(_oidNetscapeCertType) }, + oidEntrustVersInfo = { (DERByte *)_oidEntrustVersInfo, + sizeof(_oidEntrustVersInfo) }, + oidMSNTPrincipalName = { (DERByte *)_oidMSNTPrincipalName, + sizeof(_oidMSNTPrincipalName) }, + /* Policy Qualifier IDs for Internet policy qualifiers. */ + oidQtCps = { (DERByte *)_oidQtCps, + sizeof(_oidQtCps) }, + oidQtUNotice = { (DERByte *)_oidQtUNotice, + sizeof(_oidQtUNotice) }, + /* X.501 Name IDs. */ + oidCommonName = { (DERByte *)_oidCommonName, + sizeof(_oidCommonName) }, + oidCountryName = { (DERByte *)_oidCountryName, + sizeof(_oidCountryName) }, + oidLocalityName = { (DERByte *)_oidLocalityName, + sizeof(_oidLocalityName) }, + oidStateOrProvinceName = { (DERByte *)_oidStateOrProvinceName, + sizeof(_oidStateOrProvinceName) }, + oidOrganizationName = { (DERByte *)_oidOrganizationName, + sizeof(_oidOrganizationName) }, + oidOrganizationalUnitName = { (DERByte *)_oidOrganizationalUnitName, + sizeof(_oidOrganizationalUnitName) }, + oidDescription = { (DERByte *)_oidDescription, + sizeof(_oidDescription) }, + oidEmailAddress = { (DERByte *)_oidEmailAddress, + sizeof(_oidEmailAddress) }, + oidFriendlyName = { (DERByte *)_oidFriendlyName, + sizeof(_oidFriendlyName) }, + oidLocalKeyId = { (DERByte *)_oidLocalKeyId, + sizeof(_oidLocalKeyId) }, + oidExtendedKeyUsageServerAuth = { (DERByte *)_oidExtendedKeyUsageServerAuth, + sizeof(_oidExtendedKeyUsageServerAuth) }, + oidExtendedKeyUsageClientAuth = { (DERByte *)_oidExtendedKeyUsageClientAuth, + sizeof(_oidExtendedKeyUsageClientAuth) }, + oidExtendedKeyUsageCodeSigning = { (DERByte *)_oidExtendedKeyUsageCodeSigning, + sizeof(_oidExtendedKeyUsageCodeSigning) }, + oidExtendedKeyUsageEmailProtection = { (DERByte *)_oidExtendedKeyUsageEmailProtection, + sizeof(_oidExtendedKeyUsageEmailProtection) }, + oidExtendedKeyUsageOCSPSigning = { (DERByte *)_oidExtendedKeyUsageOCSPSigning, + sizeof(_oidExtendedKeyUsageOCSPSigning) }, + oidExtendedKeyUsageIPSec = { (DERByte *)_oidExtendedKeyUsageIPSec, + sizeof(_oidExtendedKeyUsageIPSec) }, + oidExtendedKeyUsageMicrosoftSGC = { (DERByte *)_oidExtendedKeyUsageMicrosoftSGC, + sizeof(_oidExtendedKeyUsageMicrosoftSGC) }, + oidExtendedKeyUsageNetscapeSGC = { (DERByte *)_oidExtendedKeyUsageNetscapeSGC, + sizeof(_oidExtendedKeyUsageNetscapeSGC) }, + oidAppleSecureBootCertSpec = { (DERByte *)_oidAppleSecureBootCertSpec, + sizeof(_oidAppleSecureBootCertSpec) }, + oidAppleProvisioningProfile = { (DERByte *)_oidAppleProvisioningProfile, + sizeof(_oidAppleProvisioningProfile) }, + oidAppleApplicationSigning = { (DERByte *)_oidAppleApplicationSigning, + sizeof(_oidAppleApplicationSigning) }, + oidAppleExtendedKeyUsageAppleID = { (DERByte *)_oidAppleExtendedKeyUsageAppleID, + sizeof(_oidAppleExtendedKeyUsageAppleID) }, + oidAppleIntmMarkerAppleID = { (DERByte *)_oidAppleIntmMarkerAppleID, + sizeof(_oidAppleIntmMarkerAppleID) }; + + +bool DEROidCompare(const DERItem *oid1, const DERItem *oid2) { + if ((oid1 == NULL) || (oid2 == NULL)) { + return false; + } + if (oid1->length != oid2->length) { + return false; + } + if (!DERMemcmp(oid1->data, oid2->data, oid1->length)) { + return true; + } else { + return false; + } +} diff --git a/Library/OcAppleDerLib/libDER/oids.h b/Library/OcAppleDerLib/libDER/oids.h new file mode 100644 index 00000000..c7048778 --- /dev/null +++ b/Library/OcAppleDerLib/libDER/oids.h @@ -0,0 +1,101 @@ +/* Copyright (c) 2005-2009 Apple Inc. All Rights Reserved. */ + +/* + * oids.h - declaration of OID consts + * + * Created Nov. 11 2005 by dmitch + */ + +#ifndef _LIB_DER_OIDS_H_ +#define _LIB_DER_OIDS_H_ + +#include "libDER.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Algorithm oids. */ +extern const DERItem + oidRsa, /* PKCS1 RSA encryption, used to identify RSA keys */ + oidMd2Rsa, /* PKCS1 md2withRSAEncryption signature alg */ + oidMd5Rsa, /* PKCS1 md5withRSAEncryption signature alg */ + oidSha1Rsa, /* PKCS1 sha1withRSAEncryption signature alg */ + oidSha256Rsa, /* PKCS1 sha256WithRSAEncryption signature alg */ + oidEcPubKey, /* ECDH or ECDSA public key in a certificate */ + oidSha1Ecdsa, /* ECDSA with SHA1 signature alg */ + oidSha224Ecdsa, /* ECDSA with SHA224 signature alg */ + oidSha256Ecdsa, /* ECDSA with SHA256 signature alg */ + oidSha384Ecdsa, /* ECDSA with SHA384 signature alg */ + oidSha512Ecdsa, /* ECDSA with SHA512 signature alg */ + oidMd2, /* OID_RSA_HASH 2 */ + oidMd4, /* OID_RSA_HASH 4 */ + oidMd5, /* OID_RSA_HASH 5 */ + oidSha1, /* OID_OIW_ALGORITHM 26 */ + oidSha256, /* OID_NIST_HASHALG 1 */ + oidSha384, /* OID_NIST_HASHALG 2 */ + oidSha512, /* OID_NIST_HASHALG 3 */ + oidSha224; /* OID_NIST_HASHALG 4 */ + +/* Standard X.509 Cert and CRL extensions. */ +extern const DERItem + oidSubjectKeyIdentifier, + oidKeyUsage, + oidPrivateKeyUsagePeriod, + oidSubjectAltName, + oidIssuerAltName, + oidBasicConstraints, + oidCrlDistributionPoints, + oidCertificatePolicies, + oidAnyPolicy, + oidPolicyMappings, + oidAuthorityKeyIdentifier, + oidPolicyConstraints, + oidExtendedKeyUsage, + oidAnyExtendedKeyUsage, + oidInhibitAnyPolicy, + oidAuthorityInfoAccess, + oidSubjectInfoAccess, + oidAdOCSP, + oidAdCAIssuer, + oidNetscapeCertType, + oidEntrustVersInfo, + oidMSNTPrincipalName, + /* Policy Qualifier IDs for Internet policy qualifiers. */ + oidQtCps, + oidQtUNotice, + /* X.501 Name IDs. */ + oidCommonName, + oidCountryName, + oidLocalityName, + oidStateOrProvinceName, + oidOrganizationName, + oidOrganizationalUnitName, + oidDescription, + oidEmailAddress, + oidFriendlyName, + oidLocalKeyId, + oidExtendedKeyUsageServerAuth, + oidExtendedKeyUsageClientAuth, + oidExtendedKeyUsageCodeSigning, + oidExtendedKeyUsageEmailProtection, + oidExtendedKeyUsageOCSPSigning, + oidExtendedKeyUsageIPSec, + oidExtendedKeyUsageMicrosoftSGC, + oidExtendedKeyUsageNetscapeSGC, + /* Secure Boot Spec oid */ + oidAppleSecureBootCertSpec, + oidAppleProvisioningProfile, + oidAppleApplicationSigning, + oidAppleExtendedKeyUsageAppleID, + oidAppleIntmMarkerAppleID; + +/* Compare two decoded OIDs. Returns true iff they are equivalent. */ +bool DEROidCompare(const DERItem *oid1, const DERItem *oid2); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIB_DER_UTILS_H_ */ diff --git a/Library/OcAppleDerLib/libDER_config.h b/Library/OcAppleDerLib/libDER_config.h new file mode 100644 index 00000000..04ad5cbf --- /dev/null +++ b/Library/OcAppleDerLib/libDER_config.h @@ -0,0 +1,111 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * libDER_config.h - platform dependent #defines and typedefs for libDER + * + * Created Nov. 4 2005 by dmitch + */ + +#ifndef _LIB_DER_CONFIG_H_ +#define _LIB_DER_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// +// edk2 porting - start +// +#include +#include + +typedef UINT8 uint8_t; +typedef UINT16 uint16_t; +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; +typedef UINTN size_t; +typedef BOOLEAN bool; + +#define memset(ptr, c, len) SetMem(ptr, len, c) +#define memmove(dst, src, len) CopyMem(dst, src, len) +#define memcmp(b1, b2, len) CompareMem(b1, b2, len) + +#define DER_TAG_SIZE 8 +// +// edk2 porting - end +// + +/* + * Basic data types: unsigned 8-bit integer, unsigned 32-bit integer + */ +typedef uint8_t DERByte; +typedef uint16_t DERShort; +typedef size_t DERSize; + +/* + * Use these #defines of you have memset, memmove, and memcmp; else + * write your own equivalents. + */ + +#define DERMemset(ptr, c, len) memset(ptr, c, len) +#define DERMemmove(dst, src, len) memmove(dst, src, len) +#define DERMemcmp(b1, b2, len) memcmp(b1, b2, len) + + +/*** + *** Compile time options to trim size of the library. + ***/ + +/* enable general DER encode */ +#define DER_ENCODE_ENABLE 1 + +/* enable general DER decode */ +#define DER_DECODE_ENABLE 1 + +#ifndef DER_MULTIBYTE_TAGS +/* enable multibyte tag support. */ +#define DER_MULTIBYTE_TAGS 1 +#endif + +#ifndef DER_TAG_SIZE +/* Iff DER_MULTIBYTE_TAGS is 1 this is the sizeof(DERTag) in bytes. Note that + tags are still encoded and decoded from a minimally encoded DER + represantation. This value determines how big each DERItemSpecs is, we + choose 2 since that makes DERItemSpecs 8 bytes wide. */ +#define DER_TAG_SIZE 2 +#endif + + +/* ---------------------- Do not edit below this line ---------------------- */ + +/* + * Logical representation of a tag (the encoded representation is always in + * the minimal number of bytes). The top 3 bits encode class and method + * The remaining bits encode the tag value. To obtain smaller DERItemSpecs + * sizes, choose the smallest type that fits your needs. Most standard ASN.1 + * usage only needs single byte tags, but ocasionally custom applications + * require a larger tag namespace. + */ +#if DER_MULTIBYTE_TAGS + +#if DER_TAG_SIZE == 1 +typedef uint8_t DERTag; +#elif DER_TAG_SIZE == 2 +typedef uint16_t DERTag; +#elif DER_TAG_SIZE == 4 +typedef uint32_t DERTag; +#elif DER_TAG_SIZE == 8 +typedef uint64_t DERTag; +#else +#error DER_TAG_SIZE invalid +#endif + +#else /* DER_MULTIBYTE_TAGS */ +typedef DERByte DERTag; +#endif /* !DER_MULTIBYTE_TAGS */ + +#ifdef __cplusplus +} +#endif + +#endif /* _LIB_DER_CONFIG_H_ */ diff --git a/OcSupportPkg.dsc b/OcSupportPkg.dsc index d69ffb4e..0f33a0c7 100644 --- a/OcSupportPkg.dsc +++ b/OcSupportPkg.dsc @@ -54,6 +54,7 @@ OcAppleBootCompatLib|OcSupportPkg/Library/OcAppleBootCompatLib/OcAppleBootCompatLib.inf OcAppleBootPolicyLib|OcSupportPkg/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf OcAppleChunklistLib|OcSupportPkg/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf + OcAppleDerLib|OcSupportPkg/Library/OcAppleDerLib/OcAppleDerLib.inf OcAppleDiskImageLib|OcSupportPkg/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf OcAppleImageVerificationLib|OcSupportPkg/Library/OcAppleImageVerificationLib/OcAppleImageVerificationLib.inf OcAppleKernelLib|OcSupportPkg/Library/OcAppleKernelLib/OcAppleKernelLib.inf @@ -91,6 +92,7 @@ OcSupportPkg/Library/OcAppleBootCompatLib/OcAppleBootCompatLib.inf OcSupportPkg/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf OcSupportPkg/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf + OcSupportPkg/Library/OcAppleDerLib/OcAppleDerLib.inf OcSupportPkg/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf OcSupportPkg/Library/OcAppleImageVerificationLib/OcAppleImageVerificationLib.inf OcSupportPkg/Library/OcAppleKernelLib/OcAppleKernelLib.inf