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 ******************************************************************/
22 #include "crl_generator.h"
24 #include "oic_malloc.h"
27 //ecdsa-with-SHA256 1.2.840.10045.4.3.2 [RFC5759]
28 static const uint8_t g_ECDSA_WITH_SHA256_OID[] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02};
30 //commonName 2.5.4.3 [RFC2256]
31 static const uint8_t g_COMMON_NAME_OID[] = {0x55, 0x04, 0x03};
33 PKIError GenerateCRL (const UTF8String_t *issuerName,
34 const UTCTime_t *thisUpdateTime, const uint32_t numberOfRevoked,
35 const CertificateRevocationInfo_t *certificateRevocationInfo,
36 const BIT_STRING_t *issuerPrivateKey, ByteArray *encodedCRL)
40 CertificateRevocationList_t *certificateRevocationList = NULL; /* Type to encode */
41 AttributeTypeAndValue_t *issuerTypeAndValue = NULL;
42 RelativeDistinguishedName_t *issuerRDN = NULL;
43 CertificateRevocationInfo_t *cri = NULL;
45 uint32_t crlMaxSize = (uint32_t)(CRL_MIN_SIZE +
46 numberOfRevoked * (sizeof(CertificateRevocationInfo_t) + 4));
49 long serialNumber = 0;
51 CHECK_NULL(issuerName, ISSUER_CRL_NULL_PASSED);
52 CHECK_NULL(thisUpdateTime, ISSUER_CRL_NULL_PASSED);
53 CHECK_NULL(certificateRevocationInfo, ISSUER_CRL_NULL_PASSED);
54 CHECK_NULL(issuerPrivateKey, ISSUER_CRL_NULL_PASSED);
55 CHECK_NULL(encodedCRL, ISSUER_CRL_NULL_PASSED);
56 CHECK_NULL(encodedCRL->data, ISSUER_CRL_NULL_PASSED);
57 CHECK_LESS_EQUAL(crlMaxSize, encodedCRL->len, ISSUER_CRL_WRONG_BYTE_ARRAY_LEN);
59 /* Allocate the memory */
60 certificateRevocationList = OICCalloc(1, sizeof(CertificateRevocationList_t));//not malloc!
61 CHECK_NULL(certificateRevocationList, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
63 issuerTypeAndValue = OICCalloc(1, sizeof(AttributeTypeAndValue_t));
64 CHECK_NULL(issuerTypeAndValue, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
66 issuerRDN = OICCalloc(1, sizeof(RelativeDistinguishedName_t));
67 CHECK_NULL(issuerRDN, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
70 issuerTypeAndValue->value = *issuerName;
71 issuerTypeAndValue->type.buf = (uint8_t *)g_COMMON_NAME_OID; //2.5.4.3
72 issuerTypeAndValue->type.size = sizeof(g_COMMON_NAME_OID) / sizeof(g_COMMON_NAME_OID[0]);
73 ASN_SET_ADD(issuerRDN, issuerTypeAndValue);
74 ASN_SEQUENCE_ADD(&(certificateRevocationList->tbsCertList.issuer), issuerRDN);
76 //set signature algorithm
77 certificateRevocationList->signatureAlgorithm.algorithm.buf =
78 (uint8_t *)g_ECDSA_WITH_SHA256_OID; //1.2.840.10045.4.3.2
79 certificateRevocationList->signatureAlgorithm.algorithm.size =
80 sizeof(g_ECDSA_WITH_SHA256_OID) / sizeof(g_ECDSA_WITH_SHA256_OID[0]);
81 certificateRevocationList->signatureAlgorithm.nul = OICCalloc(1, sizeof(NULL_t));
82 CHECK_NULL(certificateRevocationList->signatureAlgorithm.nul,
83 ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
85 //set signature algorithm in TBS part
86 certificateRevocationList->tbsCertList.signature.algorithm.buf =
87 (uint8_t *)g_ECDSA_WITH_SHA256_OID; //1.2.840.10045.4.3.2
88 certificateRevocationList->tbsCertList.signature.algorithm.size =
89 sizeof(g_ECDSA_WITH_SHA256_OID) / sizeof(g_ECDSA_WITH_SHA256_OID[0]);
90 certificateRevocationList->tbsCertList.signature.nul = OICCalloc(1, sizeof(NULL_t));
91 CHECK_NULL(certificateRevocationList->tbsCertList.signature.nul,
92 ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
95 certificateRevocationList->tbsCertList.thisUpdate = *thisUpdateTime;
98 for ( i = 0; i < numberOfRevoked; i++)
100 cri = OICCalloc(1, sizeof(CertificateRevocationInfo_t));
101 CHECK_NULL(cri, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
103 cri->revocationDate.size = (certificateRevocationInfo + i)->revocationDate.size;
104 cri->revocationDate.buf = OICCalloc((cri->revocationDate.size) + 1, sizeof(char));
105 CHECK_NULL(cri->revocationDate.buf, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
107 memcpy(cri->revocationDate.buf, (certificateRevocationInfo + i)->revocationDate.buf,
108 cri->revocationDate.size + 1);
109 cri->userCertificate = (certificateRevocationInfo + i)->userCertificate;
110 ASN_SEQUENCE_ADD((void *)(&(certificateRevocationList->
111 tbsCertList.revokedCertificates.list)), (void *)(cri));
114 CHECK_CALL(SignCRL, certificateRevocationList, crlMaxSize, issuerPrivateKey, encodedCRL);
116 CHECK_CALL(InitCKMInfo);
117 CHECK_CALL(GetCRLSerialNumber, &serialNumber);
119 CHECK_CALL(SetCRLSerialNumber, serialNumber);
120 CHECK_CALL(SetNumberOfRevoked, numberOfRevoked);
121 CHECK_CALL(SaveCKMInfo);
124 if (issuerTypeAndValue)
126 issuerTypeAndValue->value.buf = NULL;
127 issuerTypeAndValue->type.buf = NULL;
129 if (certificateRevocationList)
131 certificateRevocationList->tbsCertList.signature.algorithm.buf = NULL;
132 certificateRevocationList->signatureAlgorithm.algorithm.buf = NULL;
133 certificateRevocationList->tbsCertList.thisUpdate.buf = NULL;
136 ASN_STRUCT_FREE(asn_DEF_CertificateRevocationList, certificateRevocationList);
137 certificateRevocationList = NULL;
141 PKIError SignCRL(CertificateRevocationList_t *certificateRevocationList,
142 const uint32_t crlMaxSize, const BIT_STRING_t *issuerPrivateKey,
143 ByteArray *encodedCRL)
146 uint8_t *crlInfoInDER = NULL;
147 asn_enc_rval_t ec; /* Encoder return value */
148 uint8_t *uint8Pointer = NULL;
149 ByteArray tbs = BYTE_ARRAY_INITIALIZER;
150 uint8_t signature[SIGN_FULL_SIZE];
151 uint8_t sha256[SHA_256_HASH_LEN];
153 CHECK_NULL(certificateRevocationList, ISSUER_CRL_NULL_PASSED);
154 CHECK_NULL(crlMaxSize, ISSUER_CRL_NULL_PASSED);
155 CHECK_NULL(issuerPrivateKey, ISSUER_CRL_NULL_PASSED);
156 CHECK_NULL(encodedCRL, ISSUER_CRL_NULL_PASSED);
157 CHECK_NULL(encodedCRL->data, ISSUER_CRL_NULL_PASSED);
158 CHECK_LESS_EQUAL(crlMaxSize, encodedCRL->len, ISSUER_CRL_WRONG_BYTE_ARRAY_LEN);
161 crlInfoInDER = OICCalloc(1, crlMaxSize);
162 CHECK_NULL(crlInfoInDER, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
164 ec = der_encode_to_buffer(&asn_DEF_TBSCertList, &(certificateRevocationList->tbsCertList),
165 crlInfoInDER, crlMaxSize);
168 CHECK_COND(ec.encoded > 0, ISSUER_CRL_ENCODER_DER_ENCODE_FAIL);
169 tbs.len = ec.encoded;
170 tbs.data = crlInfoInDER;
171 GET_SHA_256(tbs, sha256);
172 CHECK_COND(uECC_sign((issuerPrivateKey->buf) + 1, sha256, signature),
173 ISSUER_CRL_ENCODER_SIGNATURE_FAIL);
174 //additional byte for ASN1_UNCOMPRESSED_KEY_ID
176 // ECDSA-Sig-Value ::= SEQUENCE { r INTEGER, s INTEGER } (RFC 5480)
177 certificateRevocationList->signatureValue.size = SIGN_FULL_SIZE + 6;
178 // size for SEQUENCE ID + 2 * INTEGER ID
180 // if first byte of positive INTEGER exceed 127 add 0 byte before
181 if (signature[0] > 127)
183 certificateRevocationList->signatureValue.size ++;
186 // if first byte of positive INTEGER exceed 127 add 0 byte before
187 if (signature[SIGN_R_LEN] > 127)
189 certificateRevocationList->signatureValue.size ++;
191 OICFree(certificateRevocationList->signatureValue.buf);
192 certificateRevocationList->signatureValue.buf = (uint8_t *)OICCalloc(
193 certificateRevocationList->signatureValue.size, sizeof(uint8_t));
194 CHECK_NULL(certificateRevocationList->signatureValue.buf,
195 ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
196 *(certificateRevocationList->signatureValue.buf) = (12 << 2); //ASN.1 SEQUENCE ID
197 *(certificateRevocationList->signatureValue.buf + 1) =
198 certificateRevocationList->signatureValue.size - 2; //ASN.1 SEQUENCE size
200 uint8Pointer = certificateRevocationList->signatureValue.buf + 2; //skip SEQUENCE ID and size
201 *uint8Pointer = (2 << 0); //ASN.1 INTEGER ID
203 // if first byte of positive INTEGER exceed 127 add 0 byte before
204 if (signature[0] > 127)
206 *(uint8Pointer + 1) = SIGN_R_LEN + 1; //ASN.1 INTEGER size
207 uint8Pointer += 3; //skip INTEGER ID and size
211 *(uint8Pointer + 1) = SIGN_R_LEN; //ASN.1 INTEGER size
212 uint8Pointer += 2; //skip INTEGER ID and size
214 memcpy(uint8Pointer, signature, SIGN_R_LEN);
216 uint8Pointer += SIGN_R_LEN;
217 *uint8Pointer = (2 << 0); //ASN.1 INTEGER ID
219 // if first byte of positive INTEGER exceed 127 add 0 byte before
220 if (signature [SIGN_R_LEN] > 127)
222 *(uint8Pointer + 1) = SIGN_S_LEN + 1; //ASN.1 INTEGER size
223 uint8Pointer += 3; //skip INTEGER ID and size
227 *(uint8Pointer + 1) = SIGN_S_LEN; //ASN.1 INTEGER size
228 uint8Pointer += 2; //skip INTEGER ID and size
230 memcpy(uint8Pointer, signature + SIGN_R_LEN, SIGN_S_LEN);
232 ec = der_encode_to_buffer(&asn_DEF_CertificateRevocationList, certificateRevocationList,
233 encodedCRL->data, crlMaxSize);
234 CHECK_COND(ec.encoded > 0, ISSUER_CRL_ENCODER_DER_ENCODE_FAIL);
235 encodedCRL->len = ec.encoded;
238 OICFree(crlInfoInDER);