IOT-2539 Cleanup -Wformat= warnings
[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 "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 "ocrandom.h"
34 #include "cacommonutil.h"
35
36 #include "ocpayload.h"
37 #include "payload_logging.h"
38 #include "pmutility.h"
39 #include "srmutility.h"
40 #include "srmresourcestrings.h"
41
42 // headers required for mbed TLS
43 #include "mbedtls/config.h"
44 #include "mbedtls/platform.h"
45 #include "mbedtls/entropy.h"
46 #include "mbedtls/ctr_drbg.h"
47 #include "mbedtls/x509_csr.h"
48 #include "mbedtls/oid.h"
49 #include "mbedtls/x509_crt.h"
50 #include "mbedtls/oid.h"
51 #include "mbedtls/pem.h"
52 #include "mbedtls/base64.h"
53
54 #ifndef NDEBUG
55 #include "mbedtls/debug.h"
56 #include "mbedtls/version.h"
57 #endif
58
59 #ifdef HAVE_UNISTD_H
60 #include <unistd.h>
61 #endif
62 #include <fcntl.h>
63
64 #include "certhelpers.h"
65 #include "occertutility.h"
66
67 #define TAG "OIC_OCCERTUTILITY"
68
69 /**
70  * @def PERSONALIZATION_STRING
71  * @brief Personalization string for the mbedtls RNG
72  */
73 #define PERSONALIZATION_STRING "IOTIVITY_RND"
74
75 #define MAX_URI_QUERY MAX_URI_LENGTH + MAX_QUERY_LENGTH
76
77 #define MAX_STRING_LEN 254
78
79 /* ASN.1 DER encoding of the EKU for identity certificates (1.3.6.1.4.1.44924.1.6) */
80 static const unsigned char s_ekuIdentity[] = { 0x30, 0x0C, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDE, 0x7C, 0x01, 0x06 };
81
82 /* ASN.1 DER encoding of the EKU for role certificates (1.3.6.1.4.1.44924.1.7) */
83 static const unsigned char s_ekuRole[] = { 0x30, 0x0C, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDE, 0x7C, 0x01, 0x07 };
84
85 /* ASN.1 DER encoding of the EKU for both identity and roles (for use by CAs) */
86 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 };
87
88 OCStackResult OC_CALL OCGenerateRandomSerialNumber(char **serial, size_t *serialLen)
89 {
90     int ret = 0;
91     OCStackResult res = OC_STACK_ERROR;
92     unsigned char random[20]; /* Per RFC 5280, 20 octets is the maximum length of a serial number. */
93     mbedtls_mpi serialMpi;
94
95     VERIFY_NOT_NULL_RETURN(TAG, serial, ERROR, OC_STACK_INVALID_PARAM);
96     VERIFY_NOT_NULL_RETURN(TAG, serialLen, ERROR, OC_STACK_INVALID_PARAM);
97
98     mbedtls_mpi_init(&serialMpi);
99     memset(serial, 0, sizeof(*serial));
100
101     VERIFY_SUCCESS(TAG, OCGetRandomBytes(random, sizeof(random)), ERROR);
102
103     /* Per RFC 5280, 20 octets is the maximum length of a serial number. In ASN.1, if the highest-order
104      * bit is set it causes a padding octet to be written, which would be 21 and non-compliant.
105      * Therefore, always clear the highest-order bit. Integers in ASN.1 are always big-Endian.
106      */
107     random[0] &= 0x7F;
108
109     /* Import into a large integer object and then output as a string. */
110     ret = mbedtls_mpi_read_binary(&serialMpi, random, sizeof(random));
111     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
112
113     /* Get the needed string length and allocate. */
114     ret = mbedtls_mpi_write_string(&serialMpi, 10, NULL, 0, serialLen);
115     VERIFY_SUCCESS(TAG, ret == MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL, ERROR);
116     *serial = OICCalloc(1, *serialLen);
117     VERIFY_NOT_NULL(TAG, *serial, ERROR);
118
119     /* Do the write for real. */
120     ret = mbedtls_mpi_write_string(&serialMpi, 10, *serial, *serialLen, serialLen);
121     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
122
123     res = OC_STACK_OK;
124
125 exit:
126
127     if (OC_STACK_OK != res)
128     {
129         OICFree(*serial);
130         *serial = NULL;
131         *serialLen = 0;
132     }
133     mbedtls_mpi_free(&serialMpi);
134
135     return res;
136 }
137
138 OCStackResult OC_CALL OCGenerateKeyPair(char **publicKey, size_t *publicKeyLen,
139                                         char **privateKey, size_t *privateKeyLen)
140 {
141     int ret = 0;
142     mbedtls_pk_context keyPair;
143     unsigned char buf[2048];
144
145     mbedtls_pk_init(&keyPair);
146
147     VERIFY_NOT_NULL_RETURN(TAG, publicKey, ERROR, OC_STACK_INVALID_PARAM);
148     VERIFY_NOT_NULL_RETURN(TAG, publicKeyLen, ERROR, OC_STACK_INVALID_PARAM);
149     VERIFY_NOT_NULL_RETURN(TAG, privateKey, ERROR, OC_STACK_INVALID_PARAM);
150     VERIFY_NOT_NULL_RETURN(TAG, privateKeyLen, ERROR, OC_STACK_INVALID_PARAM);
151
152     *publicKey = NULL;
153     *publicKeyLen = 0;
154     *privateKey = NULL;
155     *privateKeyLen = 0;
156
157     ret = OCInternalGenerateKeyPair(&keyPair);
158     if (ret != 0)
159     {
160         OIC_LOG_V(ERROR, TAG, "Failed to generate key pair: %d", ret);
161         goto exit;
162     }
163
164     ret = mbedtls_pk_write_pubkey_pem(&keyPair, buf, sizeof(buf));
165     if (ret != 0)
166     {
167         OIC_LOG_V(ERROR, TAG, "Failed to export public key as PEM: %d", ret);
168         goto exit;
169     }
170
171     *publicKeyLen = strlen((char *)buf) + 1;
172     *publicKey = OICCalloc(1, *publicKeyLen);
173     if (NULL == *publicKey)
174     {
175         OIC_LOG(ERROR, TAG, "Could not allocate memory for public key");
176         ret = -1;
177         goto exit;
178     }
179     memcpy(*publicKey, buf, *publicKeyLen);
180
181     ret = mbedtls_pk_write_key_pem(&keyPair, buf, sizeof(buf));
182     if (ret != 0)
183     {
184         OIC_LOG_V(ERROR, TAG, "Failed to export private key as PEM: %d", ret);
185         goto exit;
186     }
187
188     *privateKeyLen = strlen((char *)buf) + 1;
189     *privateKey = OICCalloc(1, *privateKeyLen);
190     if (NULL == *privateKey)
191     {
192         OIC_LOG(ERROR, TAG, "Could not allocate memory for private key");
193         ret = -1;
194         goto exit;
195     }
196     memcpy(*privateKey, buf, *privateKeyLen);
197
198 exit:
199
200     mbedtls_pk_free(&keyPair);
201
202     OICClearMemory(buf, sizeof(buf));
203
204     if (ret != 0)
205     {
206         OICFree(*publicKey);
207         OICClearMemory(*privateKey, *privateKeyLen);
208         OICFree(*privateKey);
209
210         *publicKey = NULL;
211         *publicKeyLen = 0;
212         *privateKey = NULL;
213         *privateKeyLen = 0;
214
215         return OC_STACK_ERROR;
216     }
217     else
218     {
219         return OC_STACK_OK;
220     }
221 }
222
223 typedef enum {
224     CERT_TYPE_CA,
225     CERT_TYPE_IDENTITY,
226     CERT_TYPE_ROLE
227 } CertificateType_t;
228
229 static OCStackResult GenerateCertificate(
230     CertificateType_t certType,
231     const char *subject,
232     const char *subjectPublicKey,
233     const char *issuerCert,
234     const char *issuerPrivateKey,
235     const char *serial,
236     const char *notValidBefore,
237     const char *notValidAfter,
238     const char *role,
239     const char *authority,
240     OCByteString *certificate)
241 {
242     OCStackResult res = OC_STACK_INVALID_PARAM;
243     int ret = 0;
244     mbedtls_x509write_cert outCertCtx;
245     mbedtls_pk_context subjKeyCtx;
246     mbedtls_pk_context issKeyCtx;
247     mbedtls_x509_crt issCertCtx;
248     mbedtls_mpi serialMpi;
249     mbedtls_x509_general_names names;
250     mbedtls_entropy_context entropy;
251     mbedtls_ctr_drbg_context ctr_drbg;
252
253     char buf[2048];
254
255     if (NULL == subjectPublicKey || NULL == issuerPrivateKey || NULL == subject || NULL == serial ||
256         NULL == notValidBefore || NULL == notValidAfter)
257     {
258         return OC_STACK_INVALID_PARAM;
259     }
260
261     mbedtls_x509write_crt_init(&outCertCtx);
262     mbedtls_pk_init(&subjKeyCtx);
263     mbedtls_pk_init(&issKeyCtx);
264     mbedtls_x509_crt_init(&issCertCtx);
265     mbedtls_mpi_init(&serialMpi);
266     memset(&names, 0, sizeof(names));
267     mbedtls_ctr_drbg_init(&ctr_drbg);
268     mbedtls_entropy_init(&entropy);
269     memset(certificate, 0, sizeof(*certificate));
270
271     ret = mbedtls_mpi_read_string(&serialMpi, 10, serial);
272     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
273
274     ret = mbedtls_pk_parse_public_key(&subjKeyCtx, (const uint8_t *)subjectPublicKey, strlen(subjectPublicKey) + 1);
275     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
276
277     ret = mbedtls_pk_parse_key(&issKeyCtx, (const uint8_t *)issuerPrivateKey, strlen(issuerPrivateKey) + 1, NULL, 0);
278     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
279
280     /* If issuerCert is NULL, then the cert will be self-signed. */
281     if (NULL != issuerCert)
282     {
283         ret = mbedtls_x509_crt_parse(&issCertCtx, (const uint8_t *)issuerCert, strlen(issuerCert) + 1);
284         VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
285     }
286
287     ret = mbedtls_x509write_crt_set_validity(&outCertCtx, notValidBefore, notValidAfter);
288     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
289
290     mbedtls_x509write_crt_set_version(&outCertCtx, MBEDTLS_X509_CRT_VERSION_3);
291     mbedtls_x509write_crt_set_md_alg(&outCertCtx, MBEDTLS_MD_SHA256);
292
293     res = OC_STACK_ERROR;
294
295     ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
296         &entropy, (const uint8_t *)PERSONALIZATION_STRING, sizeof(PERSONALIZATION_STRING));
297     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
298     mbedtls_ctr_drbg_set_prediction_resistance(&ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON);
299
300     ret = mbedtls_x509write_crt_set_serial(&outCertCtx, &serialMpi);
301     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
302
303     ret = mbedtls_x509write_crt_set_subject_name(&outCertCtx, subject);
304     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
305
306     if (NULL != issuerCert)
307     {
308         // mbedtls_x509_dn_gets returns the number of bytes written to buf.
309         ret = mbedtls_x509_dn_gets(buf, sizeof(buf), &issCertCtx.subject);
310         VERIFY_SUCCESS(TAG, 0 < ret, ERROR);
311         ret = mbedtls_x509write_crt_set_issuer_name(&outCertCtx, buf);
312     }
313     else
314     {
315         /* If self-signed, use the same contents of subject for the issuer name. */
316         ret = mbedtls_x509write_crt_set_issuer_name(&outCertCtx, subject);
317     }
318     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
319
320     mbedtls_x509write_crt_set_subject_key(&outCertCtx, &subjKeyCtx);
321
322     mbedtls_x509write_crt_set_issuer_key(&outCertCtx, &issKeyCtx);
323
324     if (certType == CERT_TYPE_CA)
325     {
326         ret = mbedtls_x509write_crt_set_basic_constraints(&outCertCtx, 1, -1);
327         VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
328         ret = mbedtls_x509write_crt_set_key_usage(&outCertCtx,
329             MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN);
330         VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
331     }
332     else
333     {
334         ret = mbedtls_x509write_crt_set_basic_constraints(&outCertCtx, 0, 0);
335         VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
336         ret = mbedtls_x509write_crt_set_key_usage(&outCertCtx,
337             MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
338             MBEDTLS_X509_KU_KEY_ENCIPHERMENT |
339             MBEDTLS_X509_KU_DATA_ENCIPHERMENT |
340             MBEDTLS_X509_KU_KEY_AGREEMENT);
341         VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
342     }
343
344     switch (certType)
345     {
346     case CERT_TYPE_ROLE:
347         ret = mbedtls_x509write_crt_set_extension(&outCertCtx,
348             MBEDTLS_OID_EXTENDED_KEY_USAGE, MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
349             0,
350             s_ekuRole, sizeof(s_ekuRole));
351         VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
352         ret = snprintf(buf, sizeof(buf), "CN=%s%s%s", role, (NULL != authority) ? ",OU=" : "", (NULL != authority) ? authority : "");
353         VERIFY_SUCCESS(TAG, ret < sizeof(buf), ERROR);
354         names.next = NULL;
355         names.general_name.name_type = MBEDTLS_X509_GENERALNAME_DIRECTORYNAME;
356         ret = mbedtls_x509_string_to_names(&names.general_name.directory_name, buf);
357         VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
358
359         ret = mbedtls_x509write_crt_set_subject_alt_names(&outCertCtx, &names);
360         VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
361         break;
362
363     case CERT_TYPE_IDENTITY:
364         ret = mbedtls_x509write_crt_set_extension(&outCertCtx,
365             MBEDTLS_OID_EXTENDED_KEY_USAGE, MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
366             0,
367             s_ekuIdentity, sizeof(s_ekuIdentity));
368         VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
369         break;
370
371     case CERT_TYPE_CA:
372         ret = mbedtls_x509write_crt_set_extension(&outCertCtx,
373             MBEDTLS_OID_EXTENDED_KEY_USAGE, MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
374             0,
375             s_ekuCA, sizeof(s_ekuCA));
376         VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
377         break;
378
379     default:
380         assert(false);
381         VERIFY_SUCCESS(TAG, false, ERROR);
382     }
383
384     ret = mbedtls_x509write_crt_pem(&outCertCtx, (uint8_t *)buf, sizeof(buf), mbedtls_ctr_drbg_random, &ctr_drbg);
385     VERIFY_SUCCESS(TAG, 0 == ret, ERROR);
386
387     certificate->len = strlen(buf) + 1;
388     certificate->bytes = (uint8_t *)OICCalloc(1, certificate->len);
389     VERIFY_NOT_NULL(TAG, certificate->bytes, ERROR);
390     memcpy(certificate->bytes, buf, certificate->len);
391
392     res = OC_STACK_OK;
393
394 exit:
395
396     if (OC_STACK_OK != res)
397     {
398         OICFree(certificate->bytes);
399         certificate->bytes = NULL;
400         certificate->len = 0;
401     }
402
403     mbedtls_ctr_drbg_free(&ctr_drbg);
404     mbedtls_entropy_free(&entropy);
405     mbedtls_asn1_free_named_data_list(&names.general_name.directory_name);
406     mbedtls_mpi_free(&serialMpi);
407     mbedtls_x509_crt_free(&issCertCtx);
408     mbedtls_pk_free(&issKeyCtx);
409     mbedtls_pk_free(&subjKeyCtx);
410     mbedtls_x509write_crt_free(&outCertCtx);
411
412     return res;
413 }
414
415 OCStackResult OC_CALL OCGenerateCACertificate(
416     const char *subject,
417     const char *subjectPublicKey,
418     const char *issuerCert,
419     const char *issuerPrivateKey,
420     const char *serial,
421     const char *notValidBefore,
422     const char *notValidAfter,
423     char **certificate,
424     size_t *certificateLen)
425 {
426     OCStackResult res = OC_STACK_OK;
427     OCByteString byteStr = { 0 };
428
429     res = GenerateCertificate(
430         CERT_TYPE_CA,
431         subject,
432         subjectPublicKey,
433         issuerCert,
434         issuerPrivateKey,
435         serial,
436         notValidBefore,
437         notValidAfter,
438         NULL,
439         NULL,
440         &byteStr);
441
442     if (OC_STACK_OK == res)
443     {
444         *certificate = (char *)byteStr.bytes;
445         *certificateLen = byteStr.len;
446     }
447
448     return res;
449 }
450
451 OCStackResult OC_CALL OCGenerateIdentityCertificate(
452     const OicUuid_t *subjectUuid,
453     const char *subjectPublicKey,
454     const char *issuerCert,
455     const char *issuerPrivateKey,
456     const char *serial,
457     const char *notValidBefore,
458     const char *notValidAfter,
459     char **certificate,
460     size_t *certificateLen)
461 {
462     OCStackResult res = OC_STACK_OK;
463     OCByteString byteStr = { 0 };
464     char uuidStr[UUID_STRING_SIZE] = { 0 } ;
465     char subject[sizeof(uuidStr) + sizeof(SUBJECT_PREFIX)] = { 0 } ;
466
467     if (NULL == issuerCert)
468     {
469         return OC_STACK_INVALID_PARAM;
470     }
471
472     if (!OCConvertUuidToString(subjectUuid->id, uuidStr))
473     {
474         OIC_LOG(ERROR, TAG, "Could not convert UUID");
475         return OC_STACK_INVALID_PARAM;
476     }
477
478     if (snprintf(subject, sizeof(subject), "%s%s", SUBJECT_PREFIX, uuidStr) == sizeof(subject))
479     {
480         OIC_LOG(ERROR, TAG, "Could not write subject string");
481         return OC_STACK_INVALID_PARAM;
482     }
483
484     res = GenerateCertificate(
485         CERT_TYPE_IDENTITY,
486         subject,
487         subjectPublicKey,
488         issuerCert,
489         issuerPrivateKey,
490         serial,
491         notValidBefore,
492         notValidAfter,
493         NULL,
494         NULL,
495         &byteStr);
496
497     if (OC_STACK_OK == res)
498     {
499         *certificate = (char *)byteStr.bytes;
500         *certificateLen = byteStr.len;
501     }
502
503     return res;
504 }
505
506 OCStackResult OC_CALL OCGenerateRoleCertificate(
507     const OicUuid_t *subjectUuid,
508     const char *subjectPublicKey,
509     const char *issuerCert,
510     const char *issuerPrivateKey,
511     const char *serial,
512     const char *notValidBefore,
513     const char *notValidAfter,
514     const char *role,
515     const char *authority,
516     char **certificate,
517     size_t *certificateLen)
518 {
519     OCStackResult res = OC_STACK_ERROR;
520     OCByteString byteStr;
521     char uuidStr[UUID_STRING_SIZE] = { 0 };
522     char subject[sizeof(uuidStr) + sizeof(SUBJECT_PREFIX)] = { 0 };
523
524     memset(&byteStr, 0, sizeof(byteStr));
525
526     if (NULL == role || NULL == issuerCert)
527     {
528         return OC_STACK_INVALID_PARAM;
529     }
530
531     if (!OCConvertUuidToString(subjectUuid->id, uuidStr))
532     {
533         OIC_LOG(ERROR, TAG, "Could not convert UUID");
534         return OC_STACK_INVALID_PARAM;
535     }
536
537     if (snprintf(subject, sizeof(subject), "%s%s", SUBJECT_PREFIX, uuidStr) == sizeof(subject))
538     {
539         OIC_LOG(ERROR, TAG, "Could not write subject string");
540         return OC_STACK_INVALID_PARAM;
541     }
542
543     res = GenerateCertificate(
544         CERT_TYPE_ROLE,
545         subject,
546         subjectPublicKey,
547         issuerCert,
548         issuerPrivateKey,
549         serial,
550         notValidBefore,
551         notValidAfter,
552         role,
553         authority,
554         &byteStr);
555
556     if (OC_STACK_OK == res)
557     {
558         *certificate = (char *)byteStr.bytes;
559         *certificateLen = byteStr.len;
560     }
561
562     return res;
563 }
564
565
566 /* Verify the signature in a CSR is valid. */
567 static int VerifyCSRSignature(mbedtls_x509_csr* csr)
568 {
569     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
570
571     if (csr->sig_md != MBEDTLS_MD_SHA256)
572     {
573         OIC_LOG(ERROR, TAG, "Unexpected digest used in CSR\n");
574         return -1;
575     }
576
577     if ((csr->cri.len == 0) || (csr->cri.p == NULL))
578     {
579         OIC_LOG(ERROR, TAG, "Missing CertificateRequestInfo field in CSR\n");
580         return -1;
581     }
582
583     if ((csr->sig.len == 0) || (csr->sig.p == NULL))
584     {
585         OIC_LOG(ERROR, TAG, "Missing signature field in CSR\n");
586         return -1;
587     }
588
589     if (MBEDTLS_OID_CMP(MBEDTLS_OID_ECDSA_SHA256, &csr->sig_oid) != 0)
590     {
591         char buf[256];
592         if (mbedtls_oid_get_numeric_string(buf, sizeof(buf), &csr->sig_oid) > 0)
593         {
594             OIC_LOG_V(ERROR, TAG, "Unexpected signature OID in CSR (got %s)\n", buf);
595         }
596         else
597         {
598             OIC_LOG(ERROR, TAG, "Unexpected signature OID in CSR\n");
599         }
600         return -1;
601     }
602
603     if (mbedtls_pk_get_type(&csr->pk) != MBEDTLS_PK_ECKEY)
604     {
605         OIC_LOG(ERROR, TAG, "Unexpected public key type in CSR\n");
606         return -1;
607     }
608
609     /* mbedtls_pk_get_bitlen returns the bit length of the curve */
610     if (mbedtls_pk_get_bitlen(&csr->pk) != 256)
611     {
612         OIC_LOG(ERROR, TAG, "Unexpected public length in CSR\n");
613         return -1;
614     }
615
616     mbedtls_ecp_keypair* ecKey = mbedtls_pk_ec(csr->pk);
617     if ((ecKey != NULL) && (ecKey->grp.id != MBEDTLS_ECP_DP_SECP256R1))
618     {
619         OIC_LOG(ERROR, TAG, "Unexpected curve parameters in CSR\n");
620         return -1;
621     }
622
623     /* Hash the CertificateRequestInfoField (https://tools.ietf.org/html/rfc2986#section-3) */
624     int ret = mbedtls_md(mbedtls_md_info_from_type(csr->sig_md), csr->cri.p, csr->cri.len, hash);
625     if (ret != 0)
626     {
627         OIC_LOG(ERROR, TAG, "Failed to hash CertificateRequestInfoField\n");
628         return ret;
629     }
630
631     /* the length of hash is determined from csr->sig_md*/
632     ret = mbedtls_pk_verify(&csr->pk, csr->sig_md, hash, 0, csr->sig.p, csr->sig.len);
633
634     return ret;
635 }
636
637 OCStackResult OC_CALL OCVerifyCSRSignature(const char* csr)
638 {
639     mbedtls_x509_csr csrObj;
640
641     mbedtls_x509_csr_init(&csrObj);
642     int ret = mbedtls_x509_csr_parse(&csrObj, (const unsigned char*)csr, strlen(csr) + 1);
643     if (ret < 0)
644     {
645         OIC_LOG_V(ERROR, TAG, "Couldn't parse CSR: %d", ret);
646         mbedtls_x509_csr_free(&csrObj);
647         return OC_STACK_ERROR;
648     }
649
650     ret = VerifyCSRSignature(&csrObj);
651
652     mbedtls_x509_csr_free(&csrObj);
653
654     if (ret != 0)
655     {
656         return OC_STACK_ERROR;
657     }
658
659     return OC_STACK_OK;
660 }
661
662 OCStackResult OC_CALL OCGetUuidFromCSR(const char* csr, OicUuid_t* uuid)
663 {
664     mbedtls_x509_csr csrObj;
665
666     mbedtls_x509_csr_init(&csrObj);
667     int ret = mbedtls_x509_csr_parse(&csrObj, (const unsigned char*)csr, strlen(csr) + 1);
668     if (ret < 0)
669     {
670         OIC_LOG_V(ERROR, TAG, "Couldn't parse CSR: %d", ret);
671         mbedtls_x509_csr_free(&csrObj);
672         return OC_STACK_ERROR;
673     }
674
675     char uuidStr[UUID_STRING_SIZE + sizeof(SUBJECT_PREFIX) - 1] = { 0 };   // Both constants count NULL, subtract one
676     ret = mbedtls_x509_dn_gets(uuidStr, sizeof(uuidStr), &csrObj.subject);
677     if (ret != (sizeof(uuidStr) - 1))
678     {
679         OIC_LOG_V(ERROR, TAG, "mbedtls_x509_dn_gets returned length or error: %d, expected %" PRIuPTR, ret, sizeof(uuidStr) - 1);
680         mbedtls_x509_csr_free(&csrObj);
681         return OC_STACK_ERROR;
682     }
683
684     if (!OCConvertStringToUuid(uuidStr + sizeof(SUBJECT_PREFIX) - 1, uuid->id))
685     {
686         OIC_LOG_V(ERROR, TAG, "Failed to convert UUID: '%s'", uuidStr);
687         mbedtls_x509_csr_free(&csrObj);
688         return OC_STACK_ERROR;
689     }
690
691     if (memcmp(uuid->id, &WILDCARD_SUBJECT_ID, sizeof(uuid->id)) == 0)
692     {
693         OIC_LOG(ERROR, TAG, "Invalid UUID in CSR: '*'");
694         mbedtls_x509_csr_free(&csrObj);
695         return OC_STACK_ERROR;
696     }
697
698     mbedtls_x509_csr_free(&csrObj);
699     return OC_STACK_OK;
700 }
701
702 OCStackResult OC_CALL OCGetPublicKeyFromCSR(const char* csr, char** publicKey)
703 {
704     mbedtls_x509_csr csrObj;
705
706     mbedtls_x509_csr_init(&csrObj);
707     int ret = mbedtls_x509_csr_parse(&csrObj, (const unsigned char*)csr, strlen(csr) + 1);
708     if (ret < 0)
709     {
710         OIC_LOG_V(ERROR, TAG, "Couldn't parse CSR: %d", ret);
711         mbedtls_x509_csr_free(&csrObj);
712         return OC_STACK_ERROR;
713     }
714
715     char subjectPublicKey[500] = { 0 };
716     ret = mbedtls_pk_write_pubkey_pem(&csrObj.pk, (unsigned char*)subjectPublicKey, sizeof(subjectPublicKey));
717     if (ret != 0)
718     {
719         OIC_LOG_V(ERROR, TAG, "Failed to write subject public key as PEM: %d", ret);
720         mbedtls_x509_csr_free(&csrObj);
721         return OC_STACK_ERROR;
722     }
723
724     size_t pkLen = strlen(subjectPublicKey) + 1;
725     *publicKey = (char*) OICCalloc(1, pkLen);
726     if (*publicKey == NULL)
727     {
728         OIC_LOG(ERROR, TAG, "Failed to allocate memory for public key");
729         mbedtls_x509_csr_free(&csrObj);
730         return OC_STACK_ERROR;
731     }
732
733     memcpy(*publicKey, subjectPublicKey, pkLen);
734     mbedtls_x509_csr_free(&csrObj);
735
736     return OC_STACK_OK;
737 }
738
739 OCStackResult OC_CALL OCConvertDerCSRToPem(const char* derCSR, size_t derCSRLen, char** pemCSR)
740 {
741     const char* pemHeader = "-----BEGIN CERTIFICATE REQUEST-----\n";
742     const char* pemFooter = "-----END CERTIFICATE REQUEST-----\n";
743
744     /* Get the length required for output*/
745     size_t pemCSRLen;
746     int ret = mbedtls_pem_write_buffer(pemHeader,
747         pemFooter,
748         (const unsigned char*)derCSR,
749         derCSRLen,
750         NULL,
751         0,
752         &pemCSRLen);
753     if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL)
754     {
755         OIC_LOG_V(ERROR, TAG, "Couldn't convert CSR into PEM, failed getting required length: %d", ret);
756         return OC_STACK_ERROR;
757     }
758
759     *pemCSR = OICCalloc(1, pemCSRLen + 1);
760     if (*pemCSR == NULL)
761     {
762         OIC_LOG(ERROR, TAG, "Failed to allocate memory for PEM CSR");
763         return OC_STACK_ERROR;
764     }
765
766     /* Try the conversion */
767     ret = mbedtls_pem_write_buffer(pemHeader, pemFooter,
768         (const unsigned char *)derCSR,
769         derCSRLen,
770         (unsigned char*) *pemCSR,
771         pemCSRLen,
772         &pemCSRLen);
773     if (ret < 0)
774     {
775         OIC_LOG_V(ERROR, TAG, "Couldn't convert CSR into PEM, failed getting required length: %d", ret);
776         OICFree(*pemCSR);
777         *pemCSR = NULL;
778         return OC_STACK_ERROR;
779     }
780
781     return OC_STACK_OK;
782 }
783
784 #endif /* defined(__WITH_TLS__) || defined(__WITH_DTLS__) */