]>
git.saurik.com Git - apple/security.git/blob - Security/libsecurity_cdsa_utils/lib/cuPem.cpp
2 * Copyright (c) 2003,2011-2012,2014 Apple Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please
7 * obtain a copy of the License at http://www.apple.com/publicsource and
8 * read it before using this file.
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
12 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
13 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
15 * Please see the License for the specific language governing rights and
16 * limitations under the License.
22 Description: PEM encode/decode routines
35 #define PEM_SCAN_LEN 8192
38 * Determine if specified blob appears to be PEM format.
39 * Returns 1 if so, 0 if not.
42 const unsigned char *inData
,
46 * 1. The entire blob must be printable ASCII.
48 const unsigned char *cp
= inData
;
49 for(unsigned dex
=0; dex
<inDataLen
; dex
++, cp
++) {
50 if(!isprint(*cp
) && !isspace(*cp
)) {
56 * Search for "-----BEGIN " and "-----END".
57 * No strnstr() on X, so copy and NULL terminate to use strstr.
58 * First, get the first PEM_SCAN_LEN chars or inDataLen, whichever
61 unsigned char buf
[PEM_SCAN_LEN
+ 1];
62 unsigned len
= inDataLen
;
63 if(len
> PEM_SCAN_LEN
) {
66 memcpy(buf
, inData
, len
);
68 const char *p
= strstr((const char *)buf
, "-----BEGIN ");
74 * Now the last PEM_SCAN_LEN chars or inDataLen, whichever is less.
76 if(inDataLen
> PEM_SCAN_LEN
) {
77 memcpy(buf
, inData
+ inDataLen
- PEM_SCAN_LEN
, PEM_SCAN_LEN
);
78 buf
[PEM_SCAN_LEN
] = '\0';
80 /* else we already have whole blob in buf[] */
81 p
= strstr((const char *)buf
, "-----END ");
90 const unsigned char *inData
,
92 unsigned char **outData
,
94 const char *headerString
)
99 /* First base64 encode */
100 enc
= cuEnc64WithLines(inData
, inDataLen
, 64, &encLen
);
102 /* malloc error is actually the only known failure */
103 printf("***pemEncode: Error encoding file. Aborting.\n");
107 /* estimate outsize - just be sloppy, way conservative */
108 size_t outSize
= encLen
+ (2 * strlen(headerString
)) + 200;
109 *outData
= (unsigned char *)malloc(outSize
);
110 sprintf((char *)*outData
, "-----BEGIN %s-----\n%s-----END %s-----\n",
111 headerString
, (char *)enc
, headerString
);
112 *outDataLen
= (unsigned int)strlen((char *)*outData
);
114 if((*outData
)[*outDataLen
- 1] == '\0') {
122 const unsigned char *inData
,
124 unsigned char **outData
,
125 unsigned *outDataLen
)
129 char *startPem
= NULL
;
136 /* make the whole thing a NULL-terminated string */
137 if(inData
[inDataLen
- 1] != '\0') {
138 cp
= freeCp
= (char *)malloc(inDataLen
+ 1);
139 memmove(cp
, inData
, inDataLen
);
140 cp
[inDataLen
] = '\0';
148 /* cp is start of NULL-terminated buffer, size inDataLen */
149 /* skip over everything until "-----" */
150 curr1
= strstr(cp
, "-----");
152 printf("***pemDecode: no terminator found\n");
157 /* find end of separator line, handling both flavors of terminator */
159 curr1
= strchr(cp
, '\n');
160 curr2
= strchr(cp
, '\r');
161 if((curr1
== NULL
) & (curr2
== NULL
)) {
162 printf("***pemDecode: Bad PEM format (1)\n");
173 /* startPem points to end of separator line */
174 /* locate ending terminator and lop it off */
175 curr1
= strstr(startPem
, "-----");
177 printf("***pemDecode: Bad PEM format (2)\n");
182 /* endPem points to last PEM data plus one */
184 out
= cuDec64((unsigned char *)startPem
, (unsigned int)(endPem
-startPem
), &outLen
);
186 printf("Bad PEM format (3)\n");
191 *outDataLen
= outLen
;