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