]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/libDER/libDER/DER_Digest.c
86e67c1869da27783626b069dd59d7537f357a31
[apple/security.git] / OSX / libsecurity_keychain / libDER / libDER / DER_Digest.c
1 /*
2 * Copyright (c) 2005-2008,2010-2011,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 /*
26 * DER_Digest.h - DER encode a DigestInfo
27 *
28 */
29
30 #include <libDER/DER_Digest.h>
31
32 /*
33 * Create an encoded DigestInfo based on the specified SHA1 digest.
34 * The digest must be 20 bytes long.
35 *
36 * Result is placed in caller's buffer, which must be at least of
37 * length DER_DIGEST_INFO_LEN bytes.
38 *
39 * The *resultLen parameter is the available size in the result
40 * buffer on input, and the actual length of the encoded DigestInfo
41 * on output.
42 *
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:
46 *
47 * SEQUENCE OF <33> {
48 * SEQUENCE OF <9> {
49 * OID <5>: OID : < 06 05 2B 0E 03 02 1A >
50 * NULL
51 * }
52 * OCTET STRING <20>:
53 * 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
54 * 55 55 55 55
55 * }
56 *
57 *
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
61 * *
62 * 0000020
63 */
64
65 static const unsigned char encodedSha1Digest[] =
66 {
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 */
73 /* digest follows */
74 };
75
76 DERReturn DEREncodeSHA1DigestInfo(
77 const DERByte *sha1Digest,
78 DERSize sha1DigestLen,
79 DERByte *result, /* encoded result RETURNED here */
80 DERSize *resultLen) /* IN/OUT */
81 {
82 DERSize totalLen = sizeof(encodedSha1Digest) + DER_SHA1_DIGEST_LEN;
83
84 if((sha1Digest == NULL) || (sha1DigestLen != DER_SHA1_DIGEST_LEN) ||
85 (result == NULL) || (resultLen == NULL)) {
86 return DR_ParamErr;
87 }
88 if(*resultLen < DER_SHA1_DIGEST_INFO_LEN) {
89 return DR_BufOverflow;
90 }
91 DERMemmove(result, encodedSha1Digest, sizeof(encodedSha1Digest));
92 DERMemmove(result + sizeof(encodedSha1Digest), sha1Digest, DER_SHA1_DIGEST_LEN);
93 *resultLen = totalLen;
94 return DR_Success;
95 }
96
97 /*
98 joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
99 csor(3) nistalgorithm(4) hashAlgs(2) sha256(1)
100
101 future ones to add: sha384(2) sha512(3) sha224(4)
102 */
103 static const unsigned char encodedSha256Digest[] =
104 {
105 0x30, 0x31, /* top level sequence length 49 */
106 0x30, 0x0d, /* algorithm ID, sequence length 13 */
107 0x06, 0x09,
108 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
109 0x05, 0x00, /* NULL parameters */
110 0x04, 0x20 /* integer length 32 */
111 /* digest follows */
112 };
113
114 DERReturn DEREncodeSHA256DigestInfo(
115 const DERByte *sha256Digest,
116 DERSize sha256DigestLen,
117 DERByte *result, /* encoded result RETURNED here */
118 DERSize *resultLen) /* IN/OUT */
119 {
120 DERSize totalLen = sizeof(encodedSha256Digest) + DER_SHA256_DIGEST_LEN;
121
122 if((sha256Digest == NULL) || (sha256DigestLen != DER_SHA256_DIGEST_LEN) ||
123 (result == NULL) || (resultLen == NULL)) {
124 return DR_ParamErr;
125 }
126 if(*resultLen < DER_SHA256_DIGEST_INFO_LEN) {
127 return DR_BufOverflow;
128 }
129 DERMemmove(result, encodedSha256Digest, sizeof(encodedSha256Digest));
130 DERMemmove(result + sizeof(encodedSha256Digest), sha256Digest, DER_SHA256_DIGEST_LEN);
131 *resultLen = totalLen;
132 return DR_Success;
133 }
134
135
136 /* Same thing, MD5/MD2 */
137 static const unsigned char encodedMdDigest[] =
138 {
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 */
146 /* digest follows */
147 };
148
149 #define WHICH_DIGEST_INDEX 13
150 #define WHICH_DIGEST_MD2 2
151 #define WHICH_DIGEST_MD5 5
152
153 DERReturn DEREncodeMDDigestInfo(
154 WhichDigest whichDigest,
155 const DERByte *mdDigest,
156 DERSize mdDigestLen,
157 DERByte *result, /* encoded result RETURNED here */
158 DERSize *resultLen) /* IN/OUT */
159 {
160 DERSize totalLen = sizeof(encodedMdDigest) + DER_MD_DIGEST_LEN;
161
162 if((mdDigest == NULL) || (mdDigestLen != DER_MD_DIGEST_LEN) ||
163 (result == NULL) || (resultLen == NULL)) {
164 return DR_ParamErr;
165 }
166 if(*resultLen < totalLen) {
167 return DR_BufOverflow;
168 }
169 DERMemmove(result, encodedMdDigest, sizeof(encodedMdDigest));
170 DERMemmove(result + sizeof(encodedMdDigest), mdDigest, DER_MD_DIGEST_LEN);
171 switch(whichDigest) {
172 case WD_MD2:
173 result[WHICH_DIGEST_INDEX] = WHICH_DIGEST_MD2;
174 break;
175 case WD_MD5:
176 result[WHICH_DIGEST_INDEX] = WHICH_DIGEST_MD5;
177 break;
178 default:
179 return DR_ParamErr;
180 }
181 *resultLen = totalLen;
182 return DR_Success;
183 }