Imported Upstream version 1.1.0
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / ck_manager / src / crl_generator.c
1 /******************************************************************
2  *
3  * Copyright 2015 Samsung Electronics 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  *      LICENSE-2.0" target="_blank">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
22 #include "crl_generator.h"
23 #include "pki.h"
24 #include "oic_malloc.h"
25 #include "ckm_info.h"
26
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};
29
30 //commonName 2.5.4.3 [RFC2256]
31 static const uint8_t g_COMMON_NAME_OID[] = {0x55, 0x04, 0x03};
32
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)
37 {
38     FUNCTION_INIT();
39
40     CertificateRevocationList_t *certificateRevocationList = NULL; /* Type to encode */
41     AttributeTypeAndValue_t *issuerTypeAndValue     = NULL;
42     RelativeDistinguishedName_t *issuerRDN          = NULL;
43     CertificateRevocationInfo_t *cri                = NULL;
44
45     uint32_t crlMaxSize = (uint32_t)(CRL_MIN_SIZE +
46             numberOfRevoked * (sizeof(CertificateRevocationInfo_t) + 4));
47
48     uint32_t i;
49     long serialNumber = 0;
50
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);
58
59     /* Allocate the memory */
60     certificateRevocationList      = OICCalloc(1, sizeof(CertificateRevocationList_t));//not malloc!
61     CHECK_NULL(certificateRevocationList, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
62
63     issuerTypeAndValue = OICCalloc(1, sizeof(AttributeTypeAndValue_t));
64     CHECK_NULL(issuerTypeAndValue, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
65
66     issuerRDN          = OICCalloc(1, sizeof(RelativeDistinguishedName_t));
67     CHECK_NULL(issuerRDN, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
68
69     //set subject name
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);
75
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);
84
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);
93
94     //set thisUpdateTime
95     certificateRevocationList->tbsCertList.thisUpdate = *thisUpdateTime;
96
97     //add revoked info
98     for ( i = 0; i < numberOfRevoked; i++)
99     {
100         cri = OICCalloc(1, sizeof(CertificateRevocationInfo_t));
101         CHECK_NULL(cri, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
102
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);
106
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));
112     }
113
114     CHECK_CALL(SignCRL, certificateRevocationList, crlMaxSize, issuerPrivateKey, encodedCRL);
115
116     CHECK_CALL(InitCKMInfo);
117     CHECK_CALL(GetCRLSerialNumber, &serialNumber);
118     serialNumber++;
119     CHECK_CALL(SetCRLSerialNumber, serialNumber);
120     CHECK_CALL(SetNumberOfRevoked, numberOfRevoked);
121     CHECK_CALL(SaveCKMInfo);
122
123     FUNCTION_CLEAR(
124         if (issuerTypeAndValue)
125         {
126             issuerTypeAndValue->value.buf                                                    = NULL;
127             issuerTypeAndValue->type.buf                                                     = NULL;
128         }
129         if (certificateRevocationList)
130         {
131             certificateRevocationList->tbsCertList.signature.algorithm.buf                = NULL;
132             certificateRevocationList->signatureAlgorithm.algorithm.buf                   = NULL;
133             certificateRevocationList->tbsCertList.thisUpdate.buf                         = NULL;
134         }
135
136         ASN_STRUCT_FREE(asn_DEF_CertificateRevocationList, certificateRevocationList);
137         certificateRevocationList = NULL;
138     );
139 }
140
141 PKIError SignCRL(CertificateRevocationList_t *certificateRevocationList,
142                    const uint32_t crlMaxSize, const BIT_STRING_t *issuerPrivateKey,
143                    ByteArray *encodedCRL)
144 {
145     FUNCTION_INIT();
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];
152
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);
159
160     //encode TBS to DER
161     crlInfoInDER = OICCalloc(1, crlMaxSize);
162     CHECK_NULL(crlInfoInDER, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
163
164     ec = der_encode_to_buffer(&asn_DEF_TBSCertList, &(certificateRevocationList->tbsCertList),
165                               crlInfoInDER, crlMaxSize);
166
167     //sign CRL
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
175
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
179
180     // if first byte of positive INTEGER exceed 127 add 0 byte before
181     if (signature[0] > 127)
182     {
183         certificateRevocationList->signatureValue.size ++;
184     }
185
186     // if first byte of positive INTEGER exceed 127 add 0 byte before
187     if (signature[SIGN_R_LEN] > 127)
188     {
189         certificateRevocationList->signatureValue.size ++;
190     }
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
199
200     uint8Pointer = certificateRevocationList->signatureValue.buf + 2; //skip SEQUENCE ID and size
201     *uint8Pointer = (2 << 0); //ASN.1 INTEGER ID
202
203     // if first byte of positive INTEGER exceed 127 add 0 byte before
204     if (signature[0] > 127)
205     {
206         *(uint8Pointer + 1) = SIGN_R_LEN + 1; //ASN.1 INTEGER size
207         uint8Pointer += 3; //skip INTEGER ID and size
208     }
209     else
210     {
211         *(uint8Pointer + 1) = SIGN_R_LEN; //ASN.1 INTEGER size
212         uint8Pointer += 2; //skip INTEGER ID and size
213     }
214     memcpy(uint8Pointer, signature, SIGN_R_LEN);
215
216     uint8Pointer += SIGN_R_LEN;
217     *uint8Pointer = (2 << 0); //ASN.1 INTEGER ID
218
219     // if first byte of positive INTEGER exceed 127 add 0 byte before
220     if (signature [SIGN_R_LEN] > 127)
221     {
222         *(uint8Pointer + 1) = SIGN_S_LEN + 1; //ASN.1 INTEGER size
223         uint8Pointer += 3; //skip INTEGER ID and size
224     }
225     else
226     {
227         *(uint8Pointer + 1) = SIGN_S_LEN; //ASN.1 INTEGER size
228         uint8Pointer += 2; //skip INTEGER ID and size
229     }
230     memcpy(uint8Pointer, signature + SIGN_R_LEN, SIGN_S_LEN);
231
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;
236
237     FUNCTION_CLEAR(
238         OICFree(crlInfoInDER);
239         crlInfoInDER = NULL;
240     );
241 }