mbedtls error/verify code decode
[iotivity.git] / resource / csdk / security / src / occertutility.c
1 /* *****************************************************************
2  *
3  * Copyright 2017 Microsoft. All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * *****************************************************************/
20
21 #if defined(__WITH_TLS__) || defined(__WITH_DTLS__)
22
23 #include "iotivity_config.h"
24
25 #include "experimental/logger.h"
26 #include <stddef.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <inttypes.h>
30 #include "oic_malloc.h"
31 #include "oic_string.h"
32 #include "cacommon.h"
33 #include "experimental/ocrandom.h"
34 #include "cacommonutil.h"
35
36 #include "ocpayload.h"
37 #include "experimental/payload_logging.h"
38 #include "pmutility.h"
39 #include "srmutility.h"
40 #include "srmresourcestrings.h"
41 #include "mbedtls_messages.h"
42
43 // headers required for mbed TLS
44 #include "mbedtls/config.h"
45 #include "mbedtls/platform.h"
46 #include "mbedtls/error.h"
47 #include "mbedtls/entropy.h"
48 #include "mbedtls/ctr_drbg.h"
49 #include "mbedtls/x509_csr.h"
50 #include "mbedtls/oid.h"
51 #include "mbedtls/x509_crt.h"
52 #include "mbedtls/oid.h"
53 #include "mbedtls/pem.h"
54 #include "mbedtls/base64.h"
55 #include "mbedtls/asn1write.h"
56
57 #ifndef NDEBUG
58 #include "mbedtls/debug.h"
59 #include "mbedtls/version.h"
60 #endif
61
62 #ifdef HAVE_UNISTD_H
63 #include <unistd.h>
64 #endif
65 #include <fcntl.h>
66
67 #include "certhelpers.h"
68 #include "occertutility.h"
69
70 #define TAG "OIC_OCCERTUTILITY"
71
72 /**
73  * @def PERSONALIZATION_STRING
74  * @brief Personalization string for the mbedtls RNG
75  */
76 #define PERSONALIZATION_STRING "IOTIVITY_RND"
77
78 #define MAX_URI_QUERY MAX_URI_LENGTH + MAX_QUERY_LENGTH
79
80 #define MAX_STRING_LEN 254
81
82 /* ASN.1 DER encoding of the EKU for identity certificates */
83 static const unsigned char s_ekuIdentity[] = {
84     0x30, 0x20,
85     0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, // serverAuth (1.3.6.1.5.5.7.3.1)
86     0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, // clientAuth (1.3.6.1.5.5.7.3.2)
87     0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDE, 0x7C, 0x01, 0x06 // OCF ID OID (1.3.6.1.4.1.44924.1.6)
88 };
89
90 /* ASN.1 DER encoding of the EKU for role certificates (1.3.6.1.4.1.44924.1.7) */
91 static const unsigned char s_ekuRole[] = { 0x30, 0x0C, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDE, 0x7C, 0x01, 0x07 };
92
93 /* ASN.1 DER encoding of the EKU for both identity and roles (for use by CAs) */
94 static const unsigned char s_ekuCA[] = { 0x30, 0x18, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDE, 0x7C, 0x01, 0x06, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDE, 0x7C, 0x01, 0x07 };
95
96 static const char s_ComplianceExtOid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x04\x01\x83\x91\x56\x01\x00"; // 1.3.6.1.4.1.51414.1.0
97 static const uint8_t s_ComplianceExtBytes[] = {
98
99   0x30, 0x81, 0x94, // compliance extension sequence
100
101   0x30, 0x09, // version sequence (9 bytes)
102   0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, // [2, 0, 0]
103
104   0x30, 0x6C, // security profile sequence (108 bytes)
105
106     0x0C, 0x19, // utf8_string, 25 bytes long, '1.3.6.1.4.1.51414.0.0.1.0' (baseline)
107     0x31, 0x2E, 0x33, 0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E,
108     0x31, 0x2E, 0x35, 0x31, 0x34, 0x31, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x31, 0x2E, 0x30,
109
110     0x0C, 0x19, // utf8_string, 25 bytes long, '1.3.6.1.4.1.51414.0.0.2.0' (black)
111     0x31, 0x2E, 0x33, 0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E,
112     0x31, 0x2E, 0x35, 0x31, 0x34, 0x31, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x32, 0x2E, 0x30,
113
114     0x0C, 0x19, // utf8_string, 25 bytes long, '1.3.6.1.4.1.51414.0.0.3.0' (blue)
115     0x31, 0x2E, 0x33, 0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E,
116     0x31, 0x2E, 0x35, 0x31, 0x34, 0x31, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x33, 0x2E, 0x30,
117
118     0x0C, 0x19, // utf8_string, 25 bytes long, '1.3.6.1.4.1.51414.0.0.4.0' (purple)
119     0x31, 0x2E, 0x33, 0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E,
120     0x31, 0x2E, 0x35, 0x31, 0x34, 0x31, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x34, 0x2E, 0x30,
121
122   0x0C, 0x0F, // urf8_string 15 bytes long (device name)
123   0x49, 0x6F, 0x54, 0x69, 0x76, 0x69, 0x74, 0x79, 0x20, 0x53, // 'IoTivity Server'
124   0x65, 0x72, 0x76, 0x65, 0x72,
125
126   0x0C, 0x08, // urf8_string 8 bytes long (device manufacturer)
127   0x49, 0x6F, 0x54, 0x69, 0x76, 0x69, 0x74, 0x79 // 'IoTivity'
128 };
129
130
131 static const char s_cplSecurityClaimsExtOid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x04\x01\x83\x91\x56\x01\x01"; // 1.3.6.1.4.1.51414.1.1
132 static const uint8_t s_cplSecurityClaimsExtBytes[] = {
133     0x30, 0x1A, // sequence of length 26
134     0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x91, 0x56, 0x01, 0x01, 0x00, // OID 1.3.6.1.4.1.51414.1.1.0 (claim secure boot)
135     0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x91, 0x56, 0x01, 0x01, 0x01  // OID 1.3.6.1.4.1.51414.1.1.1 (claim hw backed credential)
136 };
137
138 static const char s_cplAttributesExtOid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x04\x01\x83\x91\x56\x01\x02"; // 1.3.6.1.4.1.51414.1.2
139 static const uint8_t s_cplAttributesExtBytes[] = {
140     0x30, 0x20, // sequence of length 32
141
142     0x0C, 0x0E, // utf8_string, 14 bytes long
143     0X31, 0X2E, 0X33, 0X2E, 0X36, 0X2E, 0X31, 0X2E, 0X34, 0X2E, 0X31, 0X2E, 0X37, 0X31,  // '1.3.6.1.4.1.71'
144
145     0x0C, 0x09, // utf8_string, 9 bytes long
146     0X44, 0X69, 0X73, 0X63, 0X6F, 0X76, 0X65, 0X72, 0X79, // 'Discovery'
147
148     0x0C, 0x03, // utf8_string, 3 bytes long
149     0X31, 0X2E, 0X30 // '1.0'
150 };
151
152
153 OCStackResult OC_CALL OCGenerateRandomSerialNumber(char **serial, size_t *serialLen)
154 {
155     int ret = 0;
156     OCStackResult res = OC_STACK_ERROR;
157     unsigned char random[20]; /* Per RFC 5280, 20 octets is the maximum length of a serial number. */
158     mbedtls_mpi serialMpi;
159
160     VERIFY_NOT_NULL_RETURN(TAG, serial, ERROR, OC_STACK_INVALID_PARAM);
161     VERIFY_NOT_NULL_RETURN(TAG, serialLen, ERROR, OC_STACK_INVALID_PARAM);
162
163     mbedtls_mpi_init(&serialMpi);
164     memset(serial, 0, sizeof(*serial));
165
166     VERIFY_SUCCESS(TAG, OCGetRandomBytes(random, sizeof(random)), ERROR);
167
168     /* Per RFC 5280, 20 octets is the maximum length of a serial number. In ASN.1, if the highest-order
169      * bit is set it causes a padding octet to be written, which would be 21 and non-compliant.
170      * Therefore, always clear the highest-order bit. Integers in ASN.1 are always big-Endian.
171      */
172     random[0] &= 0x7F;
173
174     /* Import into a large integer object and then output as a string. */
175     ret = mbedtls_mpi_read_binary(&serialMpi, random, sizeof(random));
176     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
177
178     /* Get the needed string length and allocate. */
179     ret = mbedtls_mpi_write_string(&serialMpi, 10, NULL, 0, serialLen);
180     VERIFY_SUCCESS(TAG, ret == MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL, ERROR);
181     *serial = (char*)OICCalloc(1, *serialLen);
182     VERIFY_NOT_NULL(TAG, *serial, ERROR);
183
184     /* Do the write for real. */
185     ret = mbedtls_mpi_write_string(&serialMpi, 10, *serial, *serialLen, serialLen);
186     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
187
188     res = OC_STACK_OK;
189
190 exit:
191
192     if (OC_STACK_OK != res)
193     {
194         OICFree(*serial);
195         *serial = NULL;
196         *serialLen = 0;
197     }
198     mbedtls_mpi_free(&serialMpi);
199
200     return res;
201 }
202
203 OCStackResult OC_CALL OCGenerateKeyPair(char **publicKey, size_t *publicKeyLen,
204                                         char **privateKey, size_t *privateKeyLen)
205 {
206     int ret = 0;
207     mbedtls_pk_context keyPair;
208     unsigned char buf[2048];
209
210     mbedtls_pk_init(&keyPair);
211
212     VERIFY_NOT_NULL_RETURN(TAG, publicKey, ERROR, OC_STACK_INVALID_PARAM);
213     VERIFY_NOT_NULL_RETURN(TAG, publicKeyLen, ERROR, OC_STACK_INVALID_PARAM);
214     VERIFY_NOT_NULL_RETURN(TAG, privateKey, ERROR, OC_STACK_INVALID_PARAM);
215     VERIFY_NOT_NULL_RETURN(TAG, privateKeyLen, ERROR, OC_STACK_INVALID_PARAM);
216
217     *publicKey = NULL;
218     *publicKeyLen = 0;
219     *privateKey = NULL;
220     *privateKeyLen = 0;
221
222     ret = OCInternalGenerateKeyPair(&keyPair);
223     if (ret != 0)
224     {
225         OIC_LOG_V(ERROR, TAG, "Failed to generate key pair: %d", ret);
226         goto exit;
227     }
228
229     ret = mbedtls_pk_write_pubkey_pem(&keyPair, buf, sizeof(buf));
230     if (ret != 0)
231     {
232         OIC_LOG_V(ERROR, TAG, "Failed to export public key as PEM: %d", ret);
233         goto exit;
234     }
235
236     *publicKeyLen = strlen((char *)buf) + 1;
237     *publicKey = (char*)OICCalloc(1, *publicKeyLen);
238     if (NULL == *publicKey)
239     {
240         OIC_LOG(ERROR, TAG, "Could not allocate memory for public key");
241         ret = -1;
242         goto exit;
243     }
244     memcpy(*publicKey, buf, *publicKeyLen);
245
246     ret = mbedtls_pk_write_key_pem(&keyPair, buf, sizeof(buf));
247     if (ret != 0)
248     {
249         OIC_LOG_V(ERROR, TAG, "Failed to export private key as PEM: %d", ret);
250         goto exit;
251     }
252
253     *privateKeyLen = strlen((char *)buf) + 1;
254     *privateKey = (char*)OICCalloc(1, *privateKeyLen);
255     if (NULL == *privateKey)
256     {
257         OIC_LOG(ERROR, TAG, "Could not allocate memory for private key");
258         ret = -1;
259         goto exit;
260     }
261     memcpy(*privateKey, buf, *privateKeyLen);
262
263 exit:
264
265     mbedtls_pk_free(&keyPair);
266
267     OICClearMemory(buf, sizeof(buf));
268
269     if (ret != 0)
270     {
271         OICFree(*publicKey);
272         OICClearMemory(*privateKey, *privateKeyLen);
273         OICFree(*privateKey);
274
275         *publicKey = NULL;
276         *publicKeyLen = 0;
277         *privateKey = NULL;
278         *privateKeyLen = 0;
279
280         return OC_STACK_ERROR;
281     }
282     else
283     {
284         return OC_STACK_OK;
285     }
286 }
287
288 typedef enum {
289     CERT_TYPE_ROOT_CA,
290     CERT_TYPE_INTERMEDIATE_CA,
291     CERT_TYPE_IDENTITY,
292     CERT_TYPE_ROLE
293 } CertificateType_t;
294
295
296 // write basic constraints to a cert
297 // Same as mbedtls_x509write_crt_set_basic_constraints, with the added ability to set `critical` flag
298 static int writeBasicConstraints(mbedtls_x509write_cert *ctx, int is_ca, int max_pathlen, int critical)
299 {
300     int ret = 0;
301     char mbedErrorBuf[256];
302     unsigned char buf[9];
303     unsigned char *c = buf + sizeof(buf);
304     size_t len = 0;
305
306     memset(buf, 0, sizeof(buf));
307
308     if( is_ca )
309     {
310         if(max_pathlen > 127)
311         {
312             OIC_LOG_V(ERROR, TAG, "%s: mbedtls error: X509: bad input data: %d", __func__, max_pathlen);
313             return(OC_STACK_INVALID_PARAM);
314         }
315         else if(max_pathlen >= 0)
316         {
317             MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, max_pathlen ) );
318         }
319         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) );
320     }
321
322     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
323     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
324                                                        MBEDTLS_ASN1_SEQUENCE ) );
325
326     ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS,
327                                                    MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ),
328                                                    critical, buf + sizeof(buf) - len, len );
329     LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(ret), ERROR);
330     return ret;
331 }
332
333 static OCStackResult OCWriteBasicConstraints(mbedtls_x509write_cert *ctx, int is_ca, int max_pathlen, int critical)
334 {
335     return (0 == writeBasicConstraints(ctx, is_ca, max_pathlen, critical)) ? OC_STACK_OK : OC_STACK_ERROR;
336 }
337
338 static OCStackResult GenerateCertificate(
339     CertificateType_t certType,
340     const char *subject,
341     const char *subjectPublicKey,
342     const char *issuerCert,
343     const char *issuerPrivateKey,
344     const char *serial,
345     const char *notValidBefore,
346     const char *notValidAfter,
347     const char *role,
348     const char *authority,
349     OCByteString *certificate)
350 {
351     OCStackResult res = OC_STACK_INVALID_PARAM;
352     int ret = 0;
353     mbedtls_x509write_cert outCertCtx;
354     mbedtls_pk_context subjKeyCtx;
355     mbedtls_pk_context issKeyCtx;
356     mbedtls_x509_crt issCertCtx;
357     mbedtls_mpi serialMpi;
358     mbedtls_x509_general_names names;
359     mbedtls_entropy_context entropy;
360     mbedtls_ctr_drbg_context ctr_drbg;
361
362     char buf[2048];
363     char mbedErrorBuf[256];
364
365
366     if (NULL == subjectPublicKey || NULL == issuerPrivateKey || NULL == subject || NULL == serial ||
367         NULL == notValidBefore || NULL == notValidAfter)
368     {
369         OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", __func__, !subjectPublicKey ? "subjectPublicKey" : !issuerPrivateKey ? "issuerPrivateKey" : !subject ? "subject" : !serial ? "serial" : !notValidBefore ? "not validBefore" : "notValidAfter");
370         return OC_STACK_INVALID_PARAM;
371     }
372
373     mbedtls_x509write_crt_init(&outCertCtx);
374     mbedtls_pk_init(&subjKeyCtx);
375     mbedtls_pk_init(&issKeyCtx);
376     mbedtls_x509_crt_init(&issCertCtx);
377     mbedtls_mpi_init(&serialMpi);
378     memset(&names, 0, sizeof(names));
379     mbedtls_ctr_drbg_init(&ctr_drbg);
380     mbedtls_entropy_init(&entropy);
381     memset(certificate, 0, sizeof(*certificate));
382
383     ret = mbedtls_mpi_read_string(&serialMpi, 10, serial);
384     LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
385     VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not parse serial number for internal cert generation", ERROR);
386
387     ret = mbedtls_pk_parse_public_key(&subjKeyCtx, (const uint8_t *)subjectPublicKey, strlen(subjectPublicKey) + 1);
388     LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
389     VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not parse public key for internal cert generation",  ERROR);
390
391     ret = mbedtls_pk_parse_key(&issKeyCtx, (const uint8_t *)issuerPrivateKey, strlen(issuerPrivateKey) + 1, NULL, 0);
392     LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
393     VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not parse private key for internal cert generation",  ERROR);
394
395     /* If issuerCert is NULL, then the cert will be self-signed. */
396     if (NULL != issuerCert)
397     {
398         ret = mbedtls_x509_crt_parse(&issCertCtx, (const uint8_t *)issuerCert, strlen(issuerCert) + 1);
399         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
400         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not parse issuer cert for internal cert generation",  ERROR);
401     }
402
403     ret = mbedtls_x509write_crt_set_validity(&outCertCtx, notValidBefore, notValidAfter);
404     LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
405     VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not write validity time for internal cert generation",  ERROR);
406
407     mbedtls_x509write_crt_set_version(&outCertCtx, MBEDTLS_X509_CRT_VERSION_3);
408     mbedtls_x509write_crt_set_md_alg(&outCertCtx, MBEDTLS_MD_SHA256);
409
410     res = OC_STACK_ERROR;
411
412     ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
413         &entropy, (const uint8_t *)PERSONALIZATION_STRING, sizeof(PERSONALIZATION_STRING));
414     LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
415     VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not generate seed for internal cert generation",  ERROR);
416     mbedtls_ctr_drbg_set_prediction_resistance(&ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON);
417
418     ret = mbedtls_x509write_crt_set_serial(&outCertCtx, &serialMpi);
419     LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
420     VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not write serial number for internal cert generation",  ERROR);
421
422     ret = mbedtls_x509write_crt_set_subject_name(&outCertCtx, subject);
423     LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
424     VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not write subject name for internal cert generation",  ERROR);
425
426     if (NULL != issuerCert)
427     {
428         // mbedtls_x509_dn_gets returns the number of bytes written to buf.
429         ret = mbedtls_x509_dn_gets(buf, sizeof(buf), &issCertCtx.subject);
430         VERIFY_OR_LOG_AND_EXIT(TAG, 0 < ret,  "Could not parse subject name from issuer for internal cert generation", ERROR);
431         ret = mbedtls_x509write_crt_set_issuer_name(&outCertCtx, buf);
432     }
433     else
434     {
435         /* If self-signed, use the same contents of subject for the issuer name. */
436         ret = mbedtls_x509write_crt_set_issuer_name(&outCertCtx, subject);
437     }
438     LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
439     VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not write issuer name for internal cert generation",  ERROR);
440
441     mbedtls_x509write_crt_set_subject_key(&outCertCtx, &subjKeyCtx);
442
443     mbedtls_x509write_crt_set_issuer_key(&outCertCtx, &issKeyCtx);
444
445     /*
446      * mbedtls max_pathlen behaviour
447      * CA Cert: Expects RFC5280_val as encoding input
448      *          Provides RFC5280_val+1 as decoding output, where 0 = not present
449      * EE Cert: Does not encode
450      *          Provides 0 as decoding output
451     */
452
453     if (CERT_TYPE_ROOT_CA == certType)
454     {
455         res = OCWriteBasicConstraints(&outCertCtx, 1, -1, 1);
456         VERIFY_OR_LOG_AND_EXIT(TAG, OC_STACK_OK == res, "Could not write basic constraints for internal root ca cert generation",  ERROR);
457         ret = mbedtls_x509write_crt_set_key_usage(&outCertCtx,
458             MBEDTLS_X509_KU_KEY_CERT_SIGN | MBEDTLS_X509_KU_CRL_SIGN);
459         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
460         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not write key usage for internal root ca cert generation",  ERROR);
461     }
462     else if (CERT_TYPE_INTERMEDIATE_CA == certType)
463     {
464         res = OCWriteBasicConstraints(&outCertCtx, 1, 0, 1);
465         VERIFY_OR_LOG_AND_EXIT(TAG, OC_STACK_OK == res, "Could not write basic constraints for internal intermediate ca cert generation",  ERROR);
466         ret = mbedtls_x509write_crt_set_key_usage(&outCertCtx,
467             MBEDTLS_X509_KU_KEY_CERT_SIGN | MBEDTLS_X509_KU_CRL_SIGN);
468         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
469         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not write key usage for internal intermediate ca cert generation",  ERROR);
470     }
471     else
472     {
473         res = OCWriteBasicConstraints(&outCertCtx, 0, -1, 0);
474         VERIFY_OR_LOG_AND_EXIT(TAG, OC_STACK_OK == res, "Could not write basic constraints for internal root ee cert generation",  ERROR);
475         ret = mbedtls_x509write_crt_set_key_usage(&outCertCtx,
476             MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_AGREEMENT);
477         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
478         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not write key usage for internal ee cert generation",  ERROR);
479     }
480
481     switch (certType)
482     {
483     case CERT_TYPE_ROLE:
484         ret = mbedtls_x509write_crt_set_extension(&outCertCtx,
485             MBEDTLS_OID_EXTENDED_KEY_USAGE, MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
486             0,
487             s_ekuRole, sizeof(s_ekuRole));
488         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
489         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret,  "Could not write eku for internal role cert generation", ERROR);
490         ret = snprintf(buf, sizeof(buf), "CN=%s%s%s", role, (NULL != authority) ? ",OU=" : "", (NULL != authority) ? authority : "");
491         // To prevent sign-compare warning sizeof(buf) is cast to int. This is safe because the max size of buf fits into int.
492         // Note ret value from snprintf may be negative if there was an error so it should not be cast to size_t.
493         VERIFY_OR_LOG_AND_EXIT(TAG, ret < (int)sizeof(buf),  "snprintf error during internal cert generation", ERROR);
494         names.next = NULL;
495         names.general_name.name_type = MBEDTLS_X509_GENERALNAME_DIRECTORYNAME;
496         ret = mbedtls_x509_string_to_names(&names.general_name.directory_name, buf);
497         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
498         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret,  "Could not parse direcotry name for internal role cert generation", ERROR);
499
500         ret = mbedtls_x509write_crt_set_subject_alt_names(&outCertCtx, &names);
501         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
502         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret,  "Could not write subject alt names for internal role cert generation", ERROR);
503         break;
504
505     case CERT_TYPE_IDENTITY:
506         ret = mbedtls_x509write_crt_set_extension(&outCertCtx,
507             MBEDTLS_OID_EXTENDED_KEY_USAGE, MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
508             0,
509             s_ekuIdentity, sizeof(s_ekuIdentity));
510         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
511         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret,  "Could not write eku for internal ee cert generation", ERROR);
512
513         // optional extensions
514
515         // FILE *fp = fopen("./cpl-ext.der", "wb");
516         // fwrite(s_cplAttributesExtBytes, sizeof(s_cplAttributesExtBytes), 1, fp );
517         // fclose(fp);
518
519         ret = mbedtls_x509write_crt_set_extension(
520                     &outCertCtx,
521                     s_cplAttributesExtOid,
522                     MBEDTLS_OID_SIZE(s_cplAttributesExtOid), 0,
523                     (const unsigned char*)s_cplAttributesExtBytes, sizeof(s_cplAttributesExtBytes));
524         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
525         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Problem writing certified product list extension", ERROR);
526
527         // fp = fopen("./claims-ext.der", "wb");
528         // fwrite(s_cplSecurityClaimsExtBytes, sizeof(s_cplSecurityClaimsExtBytes), 1, fp );
529         // fclose(fp);
530
531         ret = mbedtls_x509write_crt_set_extension(
532                     &outCertCtx,
533                     s_cplSecurityClaimsExtOid,
534                     MBEDTLS_OID_SIZE(s_cplSecurityClaimsExtOid), 0,
535                     (const unsigned char*)s_cplSecurityClaimsExtBytes, sizeof(s_cplSecurityClaimsExtBytes));
536         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
537         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Problem writing certified product list extension", ERROR);
538
539         // fp = fopen("./compliance-ext.der", "wb");
540         // fwrite(s_ComplianceExtBytes, sizeof(s_ComplianceExtBytes), 1, fp );
541         // fclose(fp);
542
543         ret = mbedtls_x509write_crt_set_extension(
544                     &outCertCtx,
545                     s_ComplianceExtOid,
546                     MBEDTLS_OID_SIZE(s_ComplianceExtOid), 0,
547                     (const unsigned char*)s_ComplianceExtBytes, sizeof(s_ComplianceExtBytes));
548         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
549         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Problem writing certified product list extension", ERROR);
550         break;
551
552
553     case CERT_TYPE_ROOT_CA:
554     case CERT_TYPE_INTERMEDIATE_CA:
555         ret = mbedtls_x509write_crt_set_extension(&outCertCtx,
556             MBEDTLS_OID_EXTENDED_KEY_USAGE, MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
557             0,
558             s_ekuCA, sizeof(s_ekuCA));
559         LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
560         VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not write eku for internal root/int ca cert generation",  ERROR);
561         break;
562
563     default:
564         assert(false);
565         VERIFY_OR_LOG_AND_EXIT(TAG, false, "Unkown cert type during internal cert generation", ERROR);
566     }
567
568     ret = mbedtls_x509write_crt_pem(&outCertCtx, (uint8_t *)buf, sizeof(buf), mbedtls_ctr_drbg_random, &ctr_drbg);
569     LOG_MBED_ERROR(TAG, ret, mbedErrorBuf, sizeof(mbedErrorBuf), ERROR);
570     VERIFY_OR_LOG_AND_EXIT(TAG, 0 == ret, "Could not generate pem buffer for internal cert generation",  ERROR);
571
572     certificate->len = strlen(buf) + 1;
573     certificate->bytes = (uint8_t *)OICCalloc(1, certificate->len);
574     VERIFY_NOT_NULL(TAG, certificate->bytes, ERROR);
575     memcpy(certificate->bytes, buf, certificate->len);
576
577     res = OC_STACK_OK;
578
579 exit:
580
581     if (OC_STACK_OK != res)
582     {
583         OICFree(certificate->bytes);
584         certificate->bytes = NULL;
585         certificate->len = 0;
586     }
587
588     mbedtls_ctr_drbg_free(&ctr_drbg);
589     mbedtls_entropy_free(&entropy);
590     mbedtls_asn1_free_named_data_list(&names.general_name.directory_name);
591     mbedtls_mpi_free(&serialMpi);
592     mbedtls_x509_crt_free(&issCertCtx);
593     mbedtls_pk_free(&issKeyCtx);
594     mbedtls_pk_free(&subjKeyCtx);
595     mbedtls_x509write_crt_free(&outCertCtx);
596
597     return res;
598 }
599
600 OCStackResult OC_CALL OCGenerateRootCACertificate(
601     const char *subject,
602     const char *subjectPublicKey,
603     const char *issuerCert,
604     const char *issuerPrivateKey,
605     const char *serial,
606     const char *notValidBefore,
607     const char *notValidAfter,
608     char **certificate,
609     size_t *certificateLen)
610 {
611     OCStackResult res = OC_STACK_OK;
612     OCByteString byteStr = { NULL, 0 };
613
614     res = GenerateCertificate(
615         CERT_TYPE_ROOT_CA,
616         subject,
617         subjectPublicKey,
618         issuerCert,
619         issuerPrivateKey,
620         serial,
621         notValidBefore,
622         notValidAfter,
623         NULL,
624         NULL,
625         &byteStr);
626
627     if (OC_STACK_OK == res)
628     {
629         *certificate = (char *)byteStr.bytes;
630         *certificateLen = byteStr.len;
631     }
632
633     return res;
634 }
635
636 OCStackResult OC_CALL OCGenerateIntermediateCACertificate(
637     const char *subject,
638     const char *subjectPublicKey,
639     const char *issuerCert,
640     const char *issuerPrivateKey,
641     const char *serial,
642     const char *notValidBefore,
643     const char *notValidAfter,
644     char **certificate,
645     size_t *certificateLen)
646 {
647     OCStackResult res = OC_STACK_OK;
648     OCByteString byteStr = { NULL, 0 };
649
650     res = GenerateCertificate(
651         CERT_TYPE_INTERMEDIATE_CA,
652         subject,
653         subjectPublicKey,
654         issuerCert,
655         issuerPrivateKey,
656         serial,
657         notValidBefore,
658         notValidAfter,
659         NULL,
660         NULL,
661         &byteStr);
662
663     if (OC_STACK_OK == res)
664     {
665         *certificate = (char *)byteStr.bytes;
666         *certificateLen = byteStr.len;
667     }
668
669     return res;
670 }
671
672 OCStackResult OC_CALL OCGenerateIdentityCertificate(
673     const OicUuid_t *subjectUuid,
674     const char *subjectPublicKey,
675     const char *issuerCert,
676     const char *issuerPrivateKey,
677     const char *serial,
678     const char *notValidBefore,
679     const char *notValidAfter,
680     char **certificate,
681     size_t *certificateLen)
682 {
683     OCStackResult res = OC_STACK_OK;
684     OCByteString byteStr = { NULL, 0 };
685     char uuidStr[UUID_STRING_SIZE] = { 0 } ;
686     char subject[sizeof(uuidStr) + sizeof(SUBJECT_PREFIX)] = { 0 } ;
687
688     if (NULL == issuerCert)
689     {
690         return OC_STACK_INVALID_PARAM;
691     }
692
693     if (!OCConvertUuidToString(subjectUuid->id, uuidStr))
694     {
695         OIC_LOG(ERROR, TAG, "Could not convert UUID");
696         return OC_STACK_INVALID_PARAM;
697     }
698
699     if (snprintf(subject, sizeof(subject), "%s%s", SUBJECT_PREFIX, uuidStr) == sizeof(subject))
700     {
701         OIC_LOG(ERROR, TAG, "Could not write subject string");
702         return OC_STACK_INVALID_PARAM;
703     }
704
705     res = GenerateCertificate(
706         CERT_TYPE_IDENTITY,
707         subject,
708         subjectPublicKey,
709         issuerCert,
710         issuerPrivateKey,
711         serial,
712         notValidBefore,
713         notValidAfter,
714         NULL,
715         NULL,
716         &byteStr);
717
718     if (OC_STACK_OK == res)
719     {
720         *certificate = (char *)byteStr.bytes;
721         *certificateLen = byteStr.len;
722     }
723
724     return res;
725 }
726
727 OCStackResult OC_CALL OCGenerateRoleCertificate(
728     const OicUuid_t *subjectUuid,
729     const char *subjectPublicKey,
730     const char *issuerCert,
731     const char *issuerPrivateKey,
732     const char *serial,
733     const char *notValidBefore,
734     const char *notValidAfter,
735     const char *role,
736     const char *authority,
737     char **certificate,
738     size_t *certificateLen)
739 {
740     OCStackResult res = OC_STACK_ERROR;
741     OCByteString byteStr;
742     char uuidStr[UUID_STRING_SIZE] = { 0 };
743     char subject[sizeof(uuidStr) + sizeof(SUBJECT_PREFIX)] = { 0 };
744
745     memset(&byteStr, 0, sizeof(byteStr));
746
747     if (NULL == role || NULL == issuerCert)
748     {
749         OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", __func__, !role ? "role" : "isserCert");
750         return OC_STACK_INVALID_PARAM;
751     }
752
753     if (!OCConvertUuidToString(subjectUuid->id, uuidStr))
754     {
755         OIC_LOG(ERROR, TAG, "Could not convert UUID");
756         return OC_STACK_INVALID_PARAM;
757     }
758
759     if (snprintf(subject, sizeof(subject), "%s%s", SUBJECT_PREFIX, uuidStr) == sizeof(subject))
760     {
761         OIC_LOG(ERROR, TAG, "Could not write subject string");
762         return OC_STACK_INVALID_PARAM;
763     }
764
765     res = GenerateCertificate(
766         CERT_TYPE_ROLE,
767         subject,
768         subjectPublicKey,
769         issuerCert,
770         issuerPrivateKey,
771         serial,
772         notValidBefore,
773         notValidAfter,
774         role,
775         authority,
776         &byteStr);
777
778     if (OC_STACK_OK == res)
779     {
780         *certificate = (char *)byteStr.bytes;
781         *certificateLen = byteStr.len;
782     }
783     else
784     {
785         OIC_LOG_V(ERROR, TAG, "%s: GenerateCertificate", __func__);
786     }
787
788     return res;
789 }
790
791
792 /* Verify the signature in a CSR is valid. */
793 static int VerifyCSRSignature(mbedtls_x509_csr* csr)
794 {
795     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
796
797     if (csr->sig_md != MBEDTLS_MD_SHA256)
798     {
799         OIC_LOG(ERROR, TAG, "Unexpected digest used in CSR\n");
800         return -1;
801     }
802
803     if ((csr->cri.len == 0) || (csr->cri.p == NULL))
804     {
805         OIC_LOG(ERROR, TAG, "Missing CertificateRequestInfo field in CSR\n");
806         return -1;
807     }
808
809     if ((csr->sig.len == 0) || (csr->sig.p == NULL))
810     {
811         OIC_LOG(ERROR, TAG, "Missing signature field in CSR\n");
812         return -1;
813     }
814
815     if (MBEDTLS_OID_CMP(MBEDTLS_OID_ECDSA_SHA256, &csr->sig_oid) != 0)
816     {
817         char buf[256];
818         if (mbedtls_oid_get_numeric_string(buf, sizeof(buf), &csr->sig_oid) > 0)
819         {
820             OIC_LOG_V(ERROR, TAG, "Unexpected signature OID in CSR (got %s)\n", buf);
821         }
822         else
823         {
824             OIC_LOG(ERROR, TAG, "Unexpected signature OID in CSR\n");
825         }
826         return -1;
827     }
828
829     if (mbedtls_pk_get_type(&csr->pk) != MBEDTLS_PK_ECKEY)
830     {
831         OIC_LOG(ERROR, TAG, "Unexpected public key type in CSR\n");
832         return -1;
833     }
834
835     /* mbedtls_pk_get_bitlen returns the bit length of the curve */
836     if (mbedtls_pk_get_bitlen(&csr->pk) != 256)
837     {
838         OIC_LOG(ERROR, TAG, "Unexpected public length in CSR\n");
839         return -1;
840     }
841
842     mbedtls_ecp_keypair* ecKey = mbedtls_pk_ec(csr->pk);
843     if ((ecKey != NULL) && (ecKey->grp.id != MBEDTLS_ECP_DP_SECP256R1))
844     {
845         OIC_LOG(ERROR, TAG, "Unexpected curve parameters in CSR\n");
846         return -1;
847     }
848
849     /* Hash the CertificateRequestInfoField (https://tools.ietf.org/html/rfc2986#section-3) */
850     int ret = mbedtls_md(mbedtls_md_info_from_type(csr->sig_md), csr->cri.p, csr->cri.len, hash);
851     if (ret != 0)
852     {
853         OIC_LOG(ERROR, TAG, "Failed to hash CertificateRequestInfoField\n");
854         return ret;
855     }
856
857     /* the length of hash is determined from csr->sig_md*/
858     ret = mbedtls_pk_verify(&csr->pk, csr->sig_md, hash, 0, csr->sig.p, csr->sig.len);
859
860     return ret;
861 }
862
863 OCStackResult OC_CALL OCVerifyCSRSignature(const char* csr)
864 {
865     mbedtls_x509_csr csrObj;
866
867     mbedtls_x509_csr_init(&csrObj);
868     int ret = mbedtls_x509_csr_parse(&csrObj, (const unsigned char*)csr, strlen(csr) + 1);
869     if (ret < 0)
870     {
871         OIC_LOG_V(ERROR, TAG, "Couldn't parse CSR: %d", ret);
872         mbedtls_x509_csr_free(&csrObj);
873         return OC_STACK_ERROR;
874     }
875
876     ret = VerifyCSRSignature(&csrObj);
877
878     mbedtls_x509_csr_free(&csrObj);
879
880     if (ret != 0)
881     {
882         return OC_STACK_ERROR;
883     }
884
885     return OC_STACK_OK;
886 }
887
888 OCStackResult OC_CALL OCGetUuidFromCSR(const char* csr, OicUuid_t* uuid)
889 {
890     OCStackResult res = OC_STACK_ERROR;
891     mbedtls_x509_csr csrObj;
892     char *p = NULL;
893     char *dnStr = NULL;
894     size_t dnSize = UUID_STRING_SIZE + sizeof(SUBJECT_PREFIX) - 1;
895
896     mbedtls_x509_csr_init(&csrObj);
897
898     int ret = mbedtls_x509_csr_parse(&csrObj, (const unsigned char*)csr, strlen(csr) + 1);
899     if (ret < 0)
900     {
901         OIC_LOG_V(ERROR, TAG, "Couldn't parse CSR: %d", ret);
902         LOG_MBEDTLS_ERROR(ret);
903         goto exit;
904     }
905
906     dnStr = (char*)OICCalloc(dnSize, 1);
907     if (NULL == dnStr)
908     {
909         OIC_LOG_V(ERROR, TAG, "%s: allocate", __func__);
910         goto exit;
911     }
912
913     ret = mbedtls_x509_dn_gets(dnStr, dnSize - 1, &csrObj.subject);
914     if (ret < 0)
915     {
916         while (MBEDTLS_ERR_X509_BUFFER_TOO_SMALL == ret && 8192 > dnSize)
917         {
918             dnSize += 512;
919             p = (char*)OICRealloc(dnStr, dnSize);
920             if (p == NULL)
921             {
922                 OIC_LOG_V(ERROR, TAG, "%s: allocate", __func__);
923                 goto exit;
924             }
925             dnStr = p;
926             *(dnStr + dnSize) = '\0';
927             ret = mbedtls_x509_dn_gets(dnStr, dnSize - 1, &csrObj.subject);
928         }
929
930         if (ret < 0)
931         {
932             OIC_LOG_V(ERROR, TAG, "mbedtls_x509_dn_gets returned length or error: %d, expected %" PRIuPTR, ret, sizeof(dnStr) - 1);
933             LOG_MBEDTLS_ERROR(ret);
934             goto exit;
935         }
936     }
937
938     p = strstr(dnStr, "CN=");
939     if (NULL == p)
940     {
941         OIC_LOG_V(ERROR, TAG, "Failed to find: CN in: %s", dnStr);
942         goto exit;
943     }
944
945     p += 3;
946     *(p + UUID_STRING_SIZE - 1) = '\0';
947
948     if (!OCConvertStringToUuid(p, uuid->id))
949     {
950         OIC_LOG_V(ERROR, TAG, "Failed to convert UUID: %s", p);
951         goto exit;
952     }
953
954     if (memcmp(uuid->id, &WILDCARD_SUBJECT_ID, sizeof(uuid->id)) == 0)
955     {
956         OIC_LOG(ERROR, TAG, "Invalid UUID in CSR: '*'");
957         goto exit;
958     }
959
960     res = OC_STACK_OK;
961 exit:
962     if (dnStr)
963     {
964         OICFree(dnStr);
965     }
966     mbedtls_x509_csr_free(&csrObj);
967     return res;
968 }
969
970 OCStackResult OC_CALL OCGetPublicKeyFromCSR(const char* csr, char** publicKey)
971 {
972     mbedtls_x509_csr csrObj;
973
974     mbedtls_x509_csr_init(&csrObj);
975     int ret = mbedtls_x509_csr_parse(&csrObj, (const unsigned char*)csr, strlen(csr) + 1);
976     if (ret < 0)
977     {
978         OIC_LOG_V(ERROR, TAG, "Couldn't parse CSR: %d", ret);
979         LOG_MBEDTLS_ERROR(ret);
980         mbedtls_x509_csr_free(&csrObj);
981         return OC_STACK_ERROR;
982     }
983
984     char subjectPublicKey[500] = { 0 };
985     ret = mbedtls_pk_write_pubkey_pem(&csrObj.pk, (unsigned char*)subjectPublicKey, sizeof(subjectPublicKey));
986     if (ret != 0)
987     {
988         OIC_LOG_V(ERROR, TAG, "Failed to write subject public key as PEM: %d", ret);
989         LOG_MBEDTLS_ERROR(ret);
990         mbedtls_x509_csr_free(&csrObj);
991         return OC_STACK_ERROR;
992     }
993
994     size_t pkLen = strlen(subjectPublicKey) + 1;
995     *publicKey = (char*) OICCalloc(1, pkLen);
996     if (*publicKey == NULL)
997     {
998         OIC_LOG(ERROR, TAG, "Failed to allocate memory for public key");
999         mbedtls_x509_csr_free(&csrObj);
1000         return OC_STACK_ERROR;
1001     }
1002
1003     memcpy(*publicKey, subjectPublicKey, pkLen);
1004     mbedtls_x509_csr_free(&csrObj);
1005
1006     return OC_STACK_OK;
1007 }
1008
1009 OCStackResult OC_CALL OCConvertDerCSRToPem(const char* derCSR, size_t derCSRLen, char** pemCSR)
1010 {
1011     const char* pemHeader = "-----BEGIN CERTIFICATE REQUEST-----\n";
1012     const char* pemFooter = "-----END CERTIFICATE REQUEST-----\n";
1013
1014     /* Get the length required for output*/
1015     size_t pemCSRLen;
1016     int ret = mbedtls_pem_write_buffer(pemHeader,
1017         pemFooter,
1018         (const unsigned char*)derCSR,
1019         derCSRLen,
1020         NULL,
1021         0,
1022         &pemCSRLen);
1023     if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL)
1024     {
1025         OIC_LOG_V(ERROR, TAG, "Couldn't convert CSR into PEM, failed getting required length: %d", ret);
1026         return OC_STACK_ERROR;
1027     }
1028
1029     *pemCSR = (char*)OICCalloc(1, pemCSRLen + 1);
1030     if (*pemCSR == NULL)
1031     {
1032         OIC_LOG(ERROR, TAG, "Failed to allocate memory for PEM CSR");
1033         return OC_STACK_ERROR;
1034     }
1035
1036     /* Try the conversion */
1037     ret = mbedtls_pem_write_buffer(pemHeader, pemFooter,
1038         (const unsigned char *)derCSR,
1039         derCSRLen,
1040         (unsigned char*) *pemCSR,
1041         pemCSRLen,
1042         &pemCSRLen);
1043     if (ret < 0)
1044     {
1045         OIC_LOG_V(ERROR, TAG, "Couldn't convert CSR into PEM, failed getting required length: %d", ret);
1046         OICFree(*pemCSR);
1047         *pemCSR = NULL;
1048         return OC_STACK_ERROR;
1049     }
1050
1051     return OC_STACK_OK;
1052 }
1053
1054 #endif /* defined(__WITH_TLS__) || defined(__WITH_DTLS__) */