2 * Copyright (c) 2005-2008,2010-2011,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 * DER_Digest.h - DER encode a DigestInfo
30 #include <libDER/DER_Digest.h>
33 * Create an encoded DigestInfo based on the specified SHA1 digest.
34 * The digest must be 20 bytes long.
36 * Result is placed in caller's buffer, which must be at least of
37 * length DER_DIGEST_INFO_LEN bytes.
39 * The *resultLen parameter is the available size in the result
40 * buffer on input, and the actual length of the encoded DigestInfo
43 * In the interest of saving code space, this just drops the caller's
44 * digest into an otherwise hard-coded, fixed, encoded SHA1 DigestInfo.
45 * Nothing is variable so we know the whole thing. It looks like this:
49 * OID <5>: OID : < 06 05 2B 0E 03 02 1A >
53 * 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
58 * tower.local:digestInfo> hexdump -x /tmp/encodedDigest
59 * 0000000 3021 3009 0605 2b0e 0302 1a05 0004 1455
60 * 0000010 5555 5555 5555 5555 5555 5555 5555 5555
65 static const unsigned char encodedSha1Digest
[] =
67 0x30, 0x21, /* top level sequence length 33 */
68 0x30, 0x09, /* algorithm ID, sequence length 9 */
69 0x06, 0x05, /* alg OID, length 5, SHA1 */
70 0x2b, 0x0e, 0x03, 0x02, 0x1a,
71 0x05, 0x00, /* NULL parameters */
72 0x04, 0x14 /* integer length 20 */
76 DERReturn
DEREncodeSHA1DigestInfo(
77 const DERByte
*sha1Digest
,
78 DERSize sha1DigestLen
,
79 DERByte
*result
, /* encoded result RETURNED here */
80 DERSize
*resultLen
) /* IN/OUT */
82 DERSize totalLen
= sizeof(encodedSha1Digest
) + DER_SHA1_DIGEST_LEN
;
84 if((sha1Digest
== NULL
) || (sha1DigestLen
!= DER_SHA1_DIGEST_LEN
) ||
85 (result
== NULL
) || (resultLen
== NULL
)) {
88 if(*resultLen
< DER_SHA1_DIGEST_INFO_LEN
) {
89 return DR_BufOverflow
;
91 DERMemmove(result
, encodedSha1Digest
, sizeof(encodedSha1Digest
));
92 DERMemmove(result
+ sizeof(encodedSha1Digest
), sha1Digest
, DER_SHA1_DIGEST_LEN
);
93 *resultLen
= totalLen
;
98 joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
99 csor(3) nistalgorithm(4) hashAlgs(2) sha256(1)
101 future ones to add: sha384(2) sha512(3) sha224(4)
103 static const unsigned char encodedSha256Digest
[] =
105 0x30, 0x31, /* top level sequence length 49 */
106 0x30, 0x0d, /* algorithm ID, sequence length 13 */
108 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
109 0x05, 0x00, /* NULL parameters */
110 0x04, 0x20 /* integer length 32 */
114 DERReturn
DEREncodeSHA256DigestInfo(
115 const DERByte
*sha256Digest
,
116 DERSize sha256DigestLen
,
117 DERByte
*result
, /* encoded result RETURNED here */
118 DERSize
*resultLen
) /* IN/OUT */
120 DERSize totalLen
= sizeof(encodedSha256Digest
) + DER_SHA256_DIGEST_LEN
;
122 if((sha256Digest
== NULL
) || (sha256DigestLen
!= DER_SHA256_DIGEST_LEN
) ||
123 (result
== NULL
) || (resultLen
== NULL
)) {
126 if(*resultLen
< DER_SHA256_DIGEST_INFO_LEN
) {
127 return DR_BufOverflow
;
129 DERMemmove(result
, encodedSha256Digest
, sizeof(encodedSha256Digest
));
130 DERMemmove(result
+ sizeof(encodedSha256Digest
), sha256Digest
, DER_SHA256_DIGEST_LEN
);
131 *resultLen
= totalLen
;
136 /* Same thing, MD5/MD2 */
137 static const unsigned char encodedMdDigest
[] =
139 0x30, 0x20, /* top level sequence length 32 */
140 0x30, 0x0c, /* algorithm ID, sequence length 12 */
141 0x06, 0x08, /* alg OID, length 8, MD2/MD5 */
142 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02,
143 0x05, /* 5 = MD5, 2 = MD2 */
144 0x05, 0x00, /* NULL parameters */
145 0x04, 0x10 /* integer length 16 */
149 #define WHICH_DIGEST_INDEX 13
150 #define WHICH_DIGEST_MD2 2
151 #define WHICH_DIGEST_MD5 5
153 DERReturn
DEREncodeMDDigestInfo(
154 WhichDigest whichDigest
,
155 const DERByte
*mdDigest
,
157 DERByte
*result
, /* encoded result RETURNED here */
158 DERSize
*resultLen
) /* IN/OUT */
160 DERSize totalLen
= sizeof(encodedMdDigest
) + DER_MD_DIGEST_LEN
;
162 if((mdDigest
== NULL
) || (mdDigestLen
!= DER_MD_DIGEST_LEN
) ||
163 (result
== NULL
) || (resultLen
== NULL
)) {
166 if(*resultLen
< totalLen
) {
167 return DR_BufOverflow
;
169 DERMemmove(result
, encodedMdDigest
, sizeof(encodedMdDigest
));
170 DERMemmove(result
+ sizeof(encodedMdDigest
), mdDigest
, DER_MD_DIGEST_LEN
);
171 switch(whichDigest
) {
173 result
[WHICH_DIGEST_INDEX
] = WHICH_DIGEST_MD2
;
176 result
[WHICH_DIGEST_INDEX
] = WHICH_DIGEST_MD5
;
181 *resultLen
= totalLen
;