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