1 /******************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
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
11 * LICENSE-2.0" target="_blank">http://www.apache.org/licenses/LICENSE-2.0
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.
20 ******************************************************************/
25 #include "oic_malloc.h"
28 #include "psinterface.h"
29 #include "srmresourcestrings.h"
30 #include "crlresource.h"
31 #include "crl_generator.h"
37 //constants used in ckmInfo
38 #define CKM_INFO_IS_NOT_LOADED (0)
39 #define CKM_INFO_IS_LOADED (1)
40 #define CA_PRIVATE_KEY_IS_NOT_SET (0)
41 #define CA_PRIVATE_KEY_IS_SET (1)
42 #define CA_PRIVATE_KEY_DEFAULT_VALUE (0)
43 #define CA_PUBLIC_KEY_IS_NOT_SET (0)
44 #define CA_PUBLIC_KEY_IS_SET (1)
45 #define CA_PUBLIC_KEY_DEFAULT_VALUE (0)
46 #define CA_CERTIFICATE_CHAIN_IS_NOT_SET (0)
47 #define CA_CERTIFICATE_CHAIN_MEMORY_IS_NOT_ALLOCATED (0)
48 #define CA_NAME_IS_NOT_SET (0)
49 #define CA_NAME_DEFAULT_VALUE (0)
50 #define CERTIFICATE_SN_INITIAL_VALUE (1)
51 #define CRL_SN_INITIAL_VALUE (1)
52 #define NUMBER_OF_REVOKED_CERTIFICATES_INITIAL_VALUE (0)
54 //constants used in crlInfo
55 #define CRL_IS_NOT_SET (0)
56 #define CRL_MEMORY_IS_NOT_ALLOCATED (0)
58 static CKMInfo_t g_ckmInfo = {CKM_INFO_IS_NOT_LOADED,
59 CA_PRIVATE_KEY_IS_NOT_SET, {CA_PRIVATE_KEY_DEFAULT_VALUE},
60 CA_PUBLIC_KEY_IS_NOT_SET, {CA_PUBLIC_KEY_DEFAULT_VALUE},
61 CA_CERTIFICATE_CHAIN_IS_NOT_SET,
62 CA_CERTIFICATE_CHAIN_MEMORY_IS_NOT_ALLOCATED,
63 CA_NAME_IS_NOT_SET, {CA_NAME_DEFAULT_VALUE},
64 CERTIFICATE_SN_INITIAL_VALUE, CRL_SN_INITIAL_VALUE,
65 NUMBER_OF_REVOKED_CERTIFICATES_INITIAL_VALUE};
67 static OicSecCrl_t g_crlInfo = {CRL_IS_NOT_SET,
68 BYTE_ARRAY_INITIALIZER, BYTE_ARRAY_INITIALIZER};
72 PKIError InitCKMInfo(void)
75 FILE *filePointer = NULL;
80 if (!g_ckmInfo.CKMInfoIsLoaded)
82 filePointer = fopen(CA_STORAGE_FILE, "rb");
83 if (filePointer) //read existing storage
85 objectsRead = fread(&g_ckmInfo, sizeof(CKMInfo_t), count, filePointer);
86 g_ckmInfo.CACertificateChain = CA_CERTIFICATE_CHAIN_MEMORY_IS_NOT_ALLOCATED;
87 CHECK_EQUAL(objectsRead, count, ISSUER_CA_STORAGE_FILE_READ_ERROR);
89 else ////create new storage
93 if (0 == lstat(CA_STORAGE_FILE, &st))
95 CHECK_COND(S_ISREG(st.st_mode), ISSUER_FILE_WRITE_ERROR);
96 CHECK_COND(!S_ISLNK(st.st_mode), ISSUER_FILE_WRITE_ERROR);
99 filePointer = fopen(CA_STORAGE_FILE, "wb");
100 CHECK_NULL(filePointer, ISSUER_CA_STORAGE_FILE_WRITE_ERROR);
101 objectsWrote = fwrite(&g_ckmInfo, sizeof(CKMInfo_t), count, filePointer);
102 CHECK_EQUAL(objectsWrote, count, ISSUER_CA_STORAGE_FILE_WRITE_ERROR);
106 g_ckmInfo.CKMInfoIsLoaded = CKM_INFO_IS_LOADED;
117 PKIError SaveCKMInfo(void)
120 FILE *filePointer = NULL;
122 int objectsWrote = 0;
127 CHECK_COND(g_ckmInfo.CKMInfoIsLoaded, CKM_INFO_IS_NOT_INIT);
129 if (0 == lstat(CA_STORAGE_FILE, &st))
131 CHECK_COND(S_ISREG(st.st_mode), ISSUER_FILE_WRITE_ERROR);
132 CHECK_COND(!S_ISLNK(st.st_mode), ISSUER_FILE_WRITE_ERROR);
135 filePointer = fopen(CA_STORAGE_FILE, "wb");
136 CHECK_NULL(filePointer, ISSUER_CA_STORAGE_FILE_WRITE_ERROR);
137 objectsWrote = fwrite(&g_ckmInfo, sizeof(CKMInfo_t), count, filePointer);
138 CHECK_EQUAL(objectsWrote, count, ISSUER_CA_STORAGE_FILE_WRITE_ERROR);
139 if ((g_crlInfo.CrlData.data)&&(g_crlInfo.CrlData.len))
143 if (g_ckmInfo.CAChainLength)
156 PKIError CloseCKMInfo(void)
159 CHECK_CALL(SaveCKMInfo);
160 OICFree(g_crlInfo.CrlData.data);
161 g_crlInfo.CrlData.data = CRL_MEMORY_IS_NOT_ALLOCATED;
162 OICFree(g_crlInfo.ThisUpdate.data);
163 g_crlInfo.ThisUpdate.data = CRL_MEMORY_IS_NOT_ALLOCATED;
164 OICFree(g_ckmInfo.CACertificateChain);
165 g_ckmInfo.CACertificateChain = CA_CERTIFICATE_CHAIN_MEMORY_IS_NOT_ALLOCATED;
166 g_ckmInfo.CKMInfoIsLoaded = CKM_INFO_IS_NOT_LOADED;
167 g_crlInfo.CrlId = CRL_IS_NOT_SET;
171 PKIError SetCKMInfo (const long nextSN, const long CRLSerialNumber,
172 const ByteArray *CAPrivateKey, const ByteArray *CAPublicKey,
173 const ByteArray *CAName)
177 CHECK_CALL(SetNextSerialNumber, nextSN);
179 CHECK_CALL(SetCRLSerialNumber, CRLSerialNumber);
181 CHECK_CALL(SetCAPrivateKey, CAPrivateKey);
183 CHECK_CALL(SetCAPublicKey, CAPublicKey);
185 CHECK_CALL(SetCAName, CAName);
190 PKIError GetCKMInfo (long *nextSN, long *CRLSerialNumber,
191 ByteArray *CAPrivateKey, ByteArray *CAPublicKey,
196 CHECK_CALL(GetNextSerialNumber, nextSN);
198 CHECK_CALL(GetCRLSerialNumber, CRLSerialNumber);
200 CHECK_CALL(GetCAPrivateKey, CAPrivateKey);
202 CHECK_CALL(GetCAPublicKey, CAPublicKey);
204 CHECK_CALL(GetCAName, CAName);
210 PKIError SetCAPrivateKey (const ByteArray *CAPrivateKey)
213 CHECK_NULL_BYTE_ARRAY_PTR(CAPrivateKey, ISSUER_CA_STORAGE_NULL_PASSED);
214 CHECK_EQUAL(CAPrivateKey->len, PRIVATE_KEY_SIZE, ISSUER_CA_STORAGE_WRONG_PRIVATE_KEY_LEN);
215 memcpy(g_ckmInfo.CAPrivateKey, CAPrivateKey->data, PRIVATE_KEY_SIZE);
216 g_ckmInfo.CAPrivateKeyIsSet = CA_PRIVATE_KEY_IS_SET;
221 PKIError GetCAPrivateKey (ByteArray *CAPrivateKey)
224 CHECK_COND(g_ckmInfo.CAPrivateKeyIsSet, ISSUER_CA_STORAGE_PRIVATE_KEY_UNDEFINED);
225 CHECK_NULL_BYTE_ARRAY_PTR(CAPrivateKey, ISSUER_CA_STORAGE_NULL_PASSED);
226 memcpy(CAPrivateKey->data, g_ckmInfo.CAPrivateKey, PRIVATE_KEY_SIZE);
227 CAPrivateKey->len = PRIVATE_KEY_SIZE;
233 PKIError SetCAPublicKey (const ByteArray *CAPublicKey)
236 CHECK_NULL_BYTE_ARRAY_PTR(CAPublicKey, ISSUER_CA_STORAGE_NULL_PASSED);
237 CHECK_EQUAL(CAPublicKey->len, PUBLIC_KEY_SIZE, ISSUER_CA_STORAGE_WRONG_PUBLIC_KEY_LEN);
238 memcpy(g_ckmInfo.CAPublicKey, CAPublicKey->data, PUBLIC_KEY_SIZE);
239 g_ckmInfo.CAPublicKeyIsSet = CA_PUBLIC_KEY_IS_SET;
244 PKIError GetCAPublicKey (ByteArray *CAPublicKey)
247 CHECK_COND(g_ckmInfo.CAPublicKeyIsSet, ISSUER_CA_STORAGE_PUBLIC_KEY_UNDEFINED);
248 CHECK_NULL_BYTE_ARRAY_PTR(CAPublicKey, ISSUER_CA_STORAGE_NULL_PASSED);
249 memcpy(CAPublicKey->data, g_ckmInfo.CAPublicKey, PUBLIC_KEY_SIZE);
250 CAPublicKey->len = PUBLIC_KEY_SIZE;
256 PKIError SetCAName (const ByteArray *CAName)
259 CHECK_NULL_BYTE_ARRAY_PTR(CAName, ISSUER_CA_STORAGE_NULL_PASSED);
260 CHECK_LESS_EQUAL(CAName->len, ISSUER_MAX_NAME_SIZE, ISSUER_CA_STORAGE_WRONG_CA_NAME_LEN);
261 memcpy(g_ckmInfo.CAName, CAName->data, CAName->len);
262 g_ckmInfo.CANameSize = (uint32_t)CAName->len;
267 PKIError GetCAName (ByteArray *CAName)
270 CHECK_COND(g_ckmInfo.CANameSize, ISSUER_CA_STORAGE_CA_NAME_UNDEFINED);
271 CHECK_NULL_BYTE_ARRAY_PTR(CAName, ISSUER_CA_STORAGE_NULL_PASSED);
272 memcpy(CAName->data, g_ckmInfo.CAName, g_ckmInfo.CANameSize);
273 CAName->len = g_ckmInfo.CANameSize;
278 //Certificate-related functions
280 #define CERT_LEN_PREFIX (3)
281 #define BYTE_SIZE (8) //bits
283 static void WriteCertPrefix(uint8_t *prefix, uint32_t certLen)
285 for (size_t i = 0; i < CERT_LEN_PREFIX; ++i)
287 prefix[i] = (certLen >> (BYTE_SIZE * (CERT_LEN_PREFIX - 1 - i))) & 0xFF;
291 static uint32_t ParseCertPrefix(uint8_t *prefix)
296 for(int i=0; i < CERT_LEN_PREFIX; ++i)
298 res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
304 PKIError InitCRT(void)
307 FILE *filePointer = NULL;
308 uint32_t objectsRead = 0;
309 uint8_t prefix[CERT_LEN_PREFIX] = {0};
311 if (g_ckmInfo.CAChainLength)
313 filePointer = fopen(CA_STORAGE_CRT_FILE, "rb");
314 CHECK_NULL(filePointer, ISSUER_CA_STORAGE_CRT_READ_ERROR);
316 g_ckmInfo.CACertificateChain =
317 (ByteArray *)OICMalloc(sizeof(ByteArray) * g_ckmInfo.CAChainLength);
318 CHECK_NULL(g_ckmInfo.CACertificateChain, ISSUER_CA_STORAGE_MEMORY_ALLOC_FAILED);
320 for (int i = 0; i < g_ckmInfo.CAChainLength; i++)
322 objectsRead = (uint32_t)fread(prefix, sizeof(uint8_t), CERT_LEN_PREFIX, filePointer);
323 CHECK_EQUAL(objectsRead, CERT_LEN_PREFIX, ISSUER_CA_STORAGE_CRT_READ_ERROR);
324 g_ckmInfo.CACertificateChain[i].len = ParseCertPrefix(prefix);
326 g_ckmInfo.CACertificateChain[i].data =
327 (uint8_t *)OICMalloc(g_ckmInfo.CACertificateChain[i].len);
328 CHECK_NULL(g_ckmInfo.CACertificateChain[i].data,
329 ISSUER_CA_STORAGE_MEMORY_ALLOC_FAILED);
330 objectsRead = (uint32_t)fread(g_ckmInfo.CACertificateChain[i].data, sizeof(uint8_t),
331 g_ckmInfo.CACertificateChain[i].len, filePointer);
332 CHECK_EQUAL(objectsRead, g_ckmInfo.CACertificateChain[i].len,
333 ISSUER_CA_STORAGE_CRT_READ_ERROR);
345 PKIError SaveCRT(void)
348 FILE *filePointer = NULL;
349 uint32_t objectsWrote = 0;
350 uint8_t prefix[CERT_LEN_PREFIX] = {0};
353 if (0 == lstat(CA_STORAGE_CRT_FILE, &st))
355 CHECK_COND(S_ISREG(st.st_mode), ISSUER_FILE_WRITE_ERROR);
356 CHECK_COND(!S_ISLNK(st.st_mode), ISSUER_FILE_WRITE_ERROR);
359 filePointer = fopen(CA_STORAGE_CRT_FILE, "wb");
360 CHECK_NULL(filePointer, ISSUER_CA_STORAGE_CRT_WRITE_ERROR);
362 for (int i = 0; i < g_ckmInfo.CAChainLength; i++)
364 WriteCertPrefix(prefix, g_ckmInfo.CACertificateChain[i].len);
365 objectsWrote = (uint32_t)fwrite(prefix, sizeof(uint8_t), CERT_LEN_PREFIX, filePointer);
366 CHECK_EQUAL(objectsWrote, CERT_LEN_PREFIX, ISSUER_CA_STORAGE_CRT_WRITE_ERROR);
367 objectsWrote = (uint32_t)fwrite(g_ckmInfo.CACertificateChain[i].data, sizeof(uint8_t),
368 g_ckmInfo.CACertificateChain[i].len, filePointer);
369 CHECK_EQUAL(objectsWrote, g_ckmInfo.CACertificateChain[i].len,
370 ISSUER_CA_STORAGE_CRT_WRITE_ERROR);
383 PKIError SetNextSerialNumber (const long nextSN)
386 CHECK_LESS_EQUAL(0, nextSN, ISSUER_CA_STORAGE_WRONG_SERIAL_NUMBER);
387 g_ckmInfo.nextSerialNumber = nextSN;
392 PKIError GetNextSerialNumber (long *nextSN)
395 CHECK_NULL(nextSN, ISSUER_CA_STORAGE_NULL_PASSED);
396 CHECK_NULL(g_ckmInfo.nextSerialNumber, ISSUER_CA_STORAGE_SN_UNDEFINED);
397 *nextSN = g_ckmInfo.nextSerialNumber;
402 /*CA Certificate Chain*/
403 PKIError SetCAChain (const uint8_t CAChainLength, const ByteArray *CAChain)
406 CHECK_NULL_BYTE_ARRAY_PTR(CAChain, ISSUER_CA_STORAGE_NULL_PASSED);
407 CHECK_NULL(CAChainLength, ISSUER_CA_STORAGE_NULL_PASSED);
409 OICFree(g_ckmInfo.CACertificateChain);
410 g_ckmInfo.CACertificateChain = NULL;
411 g_ckmInfo.CACertificateChain = (ByteArray *)OICMalloc(sizeof(ByteArray) * CAChainLength);
412 CHECK_NULL(g_ckmInfo.CACertificateChain, ISSUER_CA_STORAGE_MEMORY_ALLOC_FAILED);
414 for (int i = 0; i < CAChainLength; i++)
416 g_ckmInfo.CACertificateChain[i].data = (uint8_t *)OICMalloc(CAChain[i].len);
417 CHECK_NULL(g_ckmInfo.CACertificateChain[i].data, ISSUER_CA_STORAGE_MEMORY_ALLOC_FAILED);
418 memcpy(g_ckmInfo.CACertificateChain[i].data, CAChain[i].data, CAChain[i].len);
419 g_ckmInfo.CACertificateChain[i].len = CAChain[i].len;
421 g_ckmInfo.CAChainLength = CAChainLength;
426 PKIError GetCAChain (uint8_t* CAChainLength, ByteArray *CAChain)
429 CHECK_COND(g_ckmInfo.CAChainLength, ISSUER_CA_STORAGE_CA_CHAIN_LENGTH_UNDEFINED);
430 CHECK_NULL_BYTE_ARRAY_PTR(CAChain, ISSUER_CA_STORAGE_NULL_PASSED);
431 CHECK_NULL(CAChainLength, PKI_NULL_PASSED);
433 for (int i = 0; i < g_ckmInfo.CAChainLength; i++)
435 CHECK_LESS_EQUAL(g_ckmInfo.CACertificateChain[i].len, CAChain[i].len,
436 ISSUER_CA_STORAGE_WRONG_BYTE_ARRAY_LEN);
437 memcpy(CAChain[i].data, g_ckmInfo.CACertificateChain[i].data,
438 g_ckmInfo.CACertificateChain[i].len);
439 CAChain[i].len = g_ckmInfo.CACertificateChain[i].len;
442 *CAChainLength = g_ckmInfo.CAChainLength;
448 PKIError SetCACertificate (const ByteArray *CACertificate)
451 CHECK_NULL_BYTE_ARRAY_PTR(CACertificate, ISSUER_CA_STORAGE_NULL_PASSED);
452 CHECK_CALL(SetCAChain, 1, CACertificate);
457 PKIError GetCACertificate (ByteArray *CACertificate)
461 CHECK_NULL_BYTE_ARRAY_PTR(CACertificate, ISSUER_CA_STORAGE_NULL_PASSED);
462 CHECK_CALL(GetCAChain, &i, CACertificate);
466 //CRL-related functions
468 PKIError InitCRL(void)
471 g_crlInfo = *(OicSecCrl_t *)GetCRLResource();
472 CHECK_NULL(g_crlInfo.CrlData.data, ISSUER_CA_STORAGE_NULL_PASSED);
473 CHECK_NULL(g_crlInfo.ThisUpdate.data, ISSUER_CA_STORAGE_NULL_PASSED);
478 PKIError SaveCRL(void)
482 CHECK_EQUAL(UpdateCRLResource(&g_crlInfo),
483 OC_STACK_OK, ISSUER_CA_STORAGE_CRL_WRITE_ERROR);
487 /*CRL Serial Number*/
488 PKIError SetCRLSerialNumber (const long CRLSerialNumber)
491 CHECK_LESS_EQUAL(0, CRLSerialNumber, ISSUER_CA_STORAGE_WRONG_CRL_SERIAL_NUMBER);
492 g_ckmInfo.CRLSerialNumber = CRLSerialNumber;
497 PKIError GetCRLSerialNumber (long *CRLSerialNumber)
500 CHECK_NULL(CRLSerialNumber, ISSUER_CA_STORAGE_NULL_PASSED);
501 CHECK_NULL(g_ckmInfo.CRLSerialNumber, ISSUER_CA_STORAGE_CRL_SN_UNDEFINED);
502 *CRLSerialNumber = g_ckmInfo.CRLSerialNumber;
508 PKIError SetCertificateRevocationList (const ByteArray *certificateRevocationList)
511 CHECK_NULL_BYTE_ARRAY_PTR(certificateRevocationList, ISSUER_CA_STORAGE_NULL_PASSED);
513 OICFree(g_crlInfo.CrlData.data);
514 g_crlInfo.CrlData.data = CRL_MEMORY_IS_NOT_ALLOCATED;
515 g_crlInfo.CrlData.data = (uint8_t *)OICMalloc(certificateRevocationList->len + 1);
516 CHECK_NULL(g_crlInfo.CrlData.data, ISSUER_CA_STORAGE_MEMORY_ALLOC_FAILED);
517 memcpy(g_crlInfo.CrlData.data, certificateRevocationList->data, certificateRevocationList->len);
518 g_crlInfo.CrlData.len = certificateRevocationList->len;
526 PKIError GetCertificateRevocationList (ByteArray *certificateRevocationList)
529 OicSecCrl_t *tmpCRL = NULL;
531 CHECK_COND(g_crlInfo.CrlData.data, ISSUER_CA_STORAGE_CRL_UNDEFINED);
532 CHECK_NULL_BYTE_ARRAY_PTR(certificateRevocationList, ISSUER_CA_STORAGE_NULL_PASSED);
533 tmpCRL = (OicSecCrl_t *)GetCRLResource();
534 CHECK_NULL(tmpCRL, ISSUER_CA_STORAGE_NULL_PASSED);
535 g_crlInfo.CrlId = tmpCRL->CrlId;
536 g_crlInfo.CrlData = tmpCRL->CrlData;
537 g_crlInfo.ThisUpdate = tmpCRL->ThisUpdate;
539 CHECK_LESS_EQUAL(g_crlInfo.CrlData.len, certificateRevocationList->len,
540 ISSUER_WRONG_BYTE_ARRAY_LEN);
541 memcpy(certificateRevocationList->data, g_crlInfo.CrlData.data, g_crlInfo.CrlData.len);
542 certificateRevocationList->len = g_crlInfo.CrlData.len;
549 PKIError SetNumberOfRevoked (const long numberOfRevoked)
552 CHECK_LESS_EQUAL(0, numberOfRevoked, ISSUER_CA_STORAGE_WRONG_CRL_SERIAL_NUMBER);
553 g_ckmInfo.numberOfRevoked = numberOfRevoked;
557 PKIError GetNumberOfRevoked (long *numberOfRevoked)
560 CHECK_NULL(numberOfRevoked, ISSUER_CA_STORAGE_NULL_PASSED);
561 CHECK_NULL(g_ckmInfo.numberOfRevoked, ISSUER_CA_STORAGE_CRL_SN_UNDEFINED);
562 *numberOfRevoked = g_ckmInfo.numberOfRevoked;