OcAppleDerLib: Initial import of libDER

This commit is contained in:
Download-Fritz 2019-08-17 08:53:35 +02:00
parent 0410d97604
commit 8a56495a88
17 changed files with 3167 additions and 0 deletions

View File

@ -0,0 +1,45 @@
## @file
# Component description file for OcAppleDerLib.
#
# Copyright (C) 2019, Download-Fritz. All rights reserved.<BR>
#
# 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

View File

@ -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);

View File

@ -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_ */

View File

@ -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 <stdio.h>
#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<len1; dex++) {
longLen <<= 8;
longLen |= *derPtr++;
derLen--;
}
if(longLen > 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 ; itemDex<numItems; ) {
DERDecodedInfo currDecoded;
DERShort i;
DERTag foundTag;
char foundMatch = 0;
/* save this in case of DER_DEC_SAVE_DER */
currDER = derSeq.nextItem;
drtn = DERDecodeSeqNext(&derSeq, &currDecoded);
if(drtn) {
/*
* One legal error here is DR_EndOfSequence when
* all remaining DERSequenceItems are optional.
*/
if(drtn == DR_EndOfSequence) {
for(i=itemDex; i<numItems; i++) {
if(!(itemSpecs[i].options & DER_DEC_OPTIONAL)) {
/* unexpected end of sequence */
return DR_IncompleteSeq;
}
}
/* the rest are optional; success */
return DR_Success;
}
else {
/* any other error is fatal */
return drtn;
}
} /* decode error */
/*
* Seek matching tag or ASN_ANY in itemSpecs, skipping
* over optional items.
*/
foundTag = currDecoded.tag;
derDecDbg1("--- foundTag 0x%x\n", foundTag);
for(i=itemDex; i<numItems; i++) {
const DERItemSpec *currItemSpec = &itemSpecs[i];
DERShort currOptions = currItemSpec->options;
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 */

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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; dex<numItems; dex++) {
const DERItemSpec *currItemSpec = &itemSpecs[dex];
DERShort currOptions = currItemSpec->options;
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; dex<numItems; dex++) {
const DERItemSpec *currItemSpec = &itemSpecs[dex];
DERShort currOptions = currItemSpec->options;
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 */

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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;
}
}

View File

@ -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 <stdbool.h>
#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_ */

View File

@ -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 <Base.h>
#include <Library/BaseMemoryLib.h>
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_ */

View File

@ -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