Imported Upstream version 1.1.1
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / adapter_util / pkix / pki.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 #include "pki.h"
22 #include "cert.h"
23 #include "sn_store.h"
24 #include "der_dec.h"
25 #include "crypto_adapter.h"
26
27 #ifndef WITH_ARDUINO
28 #include <time.h>
29 #endif
30
31
32 /**
33  * Check: notBefore <= now <= notAfter.
34  */
35 PKIError CheckValidity(ByteArray dateFrom, ByteArray dateTo)
36 {
37     FUNCTION_INIT(
38         struct tm t = {0};
39         struct tm lnow = {0};
40         time_t now;
41         int i;
42         ByteArray date;
43         CHECK_EQUAL(dateFrom.len, UTC_TIME_LEN, PKI_INVALID_DATE_FORMAT);
44         CHECK_EQUAL(dateTo.len, UTC_TIME_LEN, PKI_INVALID_DATE_FORMAT);
45     );
46     /* Get the current time */
47     now = time(NULL);
48     gmtime_r( &now, &lnow);
49     for (i = 0; i < 2; i ++)
50     {
51         date = (i == 0 ? dateFrom : dateTo);
52         t.tm_year = (date.data[0] - '0') * 10 + date.data[1] - '0';
53         /* It is considered date from 1950 to 2050 */
54         if (t.tm_year < 50)
55         {
56             t.tm_year += 100;
57         }
58         t.tm_mon = (date.data[2] - '0') * 10 + date.data[3] - '0' - 1;
59         t.tm_mday = (date.data[4] - '0') * 10 + date.data[5] - '0';
60         t.tm_hour = (date.data[6] - '0') * 10 + date.data[7] - '0';
61         t.tm_min = (date.data[8] - '0') * 10 + date.data[9] - '0';
62         t.tm_sec = (date.data[10] - '0') * 10 + date.data[11] - '0';
63         if (i == 0)
64         {
65             CHECK_LESS_EQUAL(t.tm_year, lnow.tm_year, PKI_CERT_DATE_INVALID);
66             if (t.tm_year == lnow.tm_year)
67             CHECK_LESS_EQUAL(t.tm_mon, lnow.tm_mon, PKI_CERT_DATE_INVALID);
68             if (t.tm_year == lnow.tm_year && t.tm_mon == lnow.tm_mon)
69                 CHECK_LESS_EQUAL(t.tm_mday, lnow.tm_mday, PKI_CERT_DATE_INVALID);
70             if (t.tm_year == lnow.tm_year && t.tm_mon == lnow.tm_mon &&  t.tm_mday == lnow.tm_mday)
71                 CHECK_LESS_EQUAL(t.tm_hour, lnow.tm_hour, PKI_CERT_DATE_INVALID);
72             if (t.tm_year == lnow.tm_year && t.tm_mon == lnow.tm_mon &&  t.tm_mday == lnow.tm_mday
73                 && t.tm_hour == lnow.tm_hour)
74                 CHECK_LESS_EQUAL(t.tm_min, lnow.tm_min, PKI_CERT_DATE_INVALID);
75             if (t.tm_year == lnow.tm_year && t.tm_mon == lnow.tm_mon &&  t.tm_mday == lnow.tm_mday
76                 && t.tm_hour == lnow.tm_hour && t.tm_min == lnow.tm_min)
77                 CHECK_LESS_EQUAL(t.tm_sec, lnow.tm_sec, PKI_CERT_DATE_INVALID);
78         }
79         else
80         {
81             CHECK_LESS_EQUAL(lnow.tm_year, t.tm_year,  PKI_CERT_DATE_INVALID);
82             if (t.tm_year == lnow.tm_year)
83             CHECK_LESS_EQUAL(lnow.tm_mon, t.tm_mon,  PKI_CERT_DATE_INVALID);
84             if (t.tm_year == lnow.tm_year && t.tm_mon == lnow.tm_mon)
85                 CHECK_LESS_EQUAL(lnow.tm_mday, t.tm_mday,  PKI_CERT_DATE_INVALID);
86             if (t.tm_year == lnow.tm_year && t.tm_mon == lnow.tm_mon &&  t.tm_mday == lnow.tm_mday)
87                 CHECK_LESS_EQUAL(lnow.tm_hour, t.tm_hour,  PKI_CERT_DATE_INVALID);
88             if (t.tm_year == lnow.tm_year && t.tm_mon == lnow.tm_mon &&  t.tm_mday == lnow.tm_mday
89                 && t.tm_hour == lnow.tm_hour)
90                 CHECK_LESS_EQUAL(lnow.tm_min, t.tm_min,  PKI_CERT_DATE_INVALID);
91             if (t.tm_year == lnow.tm_year && t.tm_mon == lnow.tm_mon &&  t.tm_mday == lnow.tm_mday
92                 && t.tm_hour == lnow.tm_hour && t.tm_min == lnow.tm_min)
93                 CHECK_LESS_EQUAL(lnow.tm_sec, t.tm_sec, PKI_CERT_DATE_INVALID);
94         }
95     }
96     FUNCTION_CLEAR();
97 }
98
99 /**
100  * Decode certDerCode certificate and performs verification.
101  *
102  * @param[in] certDerCode  Byte array with DER encoded certificate
103  * @param[in] caPublicKey  Byte array with CA public key
104  * @return PKI_SUCCESS if success, error code otherwise
105  */
106 PKIError CheckCertificate(ByteArray certDerCode, ByteArray caPublicKey)
107 {
108     FUNCTION_INIT(
109         CertificateX509 crt;
110         INIT_BYTE_ARRAY(crt.tbs);
111         INIT_BYTE_ARRAY(crt.signR);
112         INIT_BYTE_ARRAY(crt.signS);
113         INIT_BYTE_ARRAY(crt.pubKey);
114         INIT_BYTE_ARRAY(crt.issuer);
115         INIT_BYTE_ARRAY(crt.subject);
116     );
117
118     CHECK_CALL(DecodeCertificate, certDerCode, &crt);
119     CHECK_CALL(CheckValidity, crt.validFrom, crt.validTo);
120     CHECK_CALL(ParsePublicKey, &caPublicKey);
121     CHECK_SIGN(crt, caPublicKey);
122     CHECK_CALL(CheckSerialNumber, crt.serNum);
123
124     FUNCTION_CLEAR();
125 }
126
127 /*
128  * https://tools.ietf.org/html/rfc5246
129  * This is a sequence (chain) of certificates.  The sender's  certificate MUST come first
130  * in the list.  Each following certificate MUST directly certify the one preceding it.
131  */
132
133
134 /*
135  * Handshake Message: certificate consist of the list of certificates.
136  * Certificate length (3 bytes)
137  * DER encoded certificate
138  * The first is server’s certificate
139  * Other certificates are optional
140  * Usually intermediate CA certificates
141  */
142
143 // Parses each certificate from list.
144 PKIError ParseCertificateChain (ByteArray *chainDerCode, CertificateX509 *chainCrt,
145                                 uint8_t chainLen)
146 {
147     FUNCTION_INIT(
148         int i;
149         CHECK_NULL(chainDerCode, PKI_NULL_PASSED);
150         CHECK_NULL(chainCrt, PKI_NULL_PASSED);
151         CHECK_LESS_EQUAL(chainLen, MAX_CHAIN_LEN, PKI_WRONG_ARRAY_LEN);
152     );
153     for (i = 0; i < chainLen; i++)
154     {
155         CHECK_CALL(DecodeCertificate, (*chainDerCode), chainCrt);
156 #ifdef X509_DEBUG
157         PrintCertificate(chainCrt);
158 #endif
159         chainDerCode++;
160         chainCrt++;
161     }
162     FUNCTION_CLEAR();
163 }
164
165 // Loads certificates from TLS message
166 PKIError LoadCertificateChain (ByteArray msg, ByteArray *chain, uint8_t *chainLength)
167 {
168     FUNCTION_INIT(
169         CHECK_NULL(msg.data, PKI_NULL_PASSED);
170         CHECK_LESS_EQUAL(3, msg.len, PKI_WRONG_ARRAY_LEN);
171         CHECK_NULL(chain, PKI_NULL_PASSED);
172         CHECK_NULL(chainLength, PKI_NULL_PASSED);
173         uint32_t tmpLengthChain = 0;
174         *chainLength = 0;
175     );
176
177     CHECK_COND(msg.data[0] != 0 || msg.data[1] != 0 || msg.data[2] != 3, PKI_SUCCESS);
178 #ifdef X509_DEBUG
179     printf("start chain parsing\n");
180 #endif
181     while (msg.len > 0)
182     {
183 #ifdef X509_DEBUG
184         printf("chain parsing: %d\n", msg.len);
185 #endif
186         CHECK_LESS_EQUAL(3, msg.len, PKI_WRONG_ARRAY_LEN);
187         tmpLengthChain = (((uint32_t) msg.data[0]) << 16) | (((uint32_t) msg.data[1]) << 8) | msg.data[2];
188         CHECK_INC_BYTE_ARRAY(msg, 3);
189         (*chain).data = msg.data;
190         (*chain).len = tmpLengthChain;
191         chain ++;
192         (*chainLength) ++;
193         CHECK_LESS_EQUAL((*chainLength), MAX_CHAIN_LEN, PKI_WRONG_ARRAY_LEN);
194         CHECK_INC_BYTE_ARRAY(msg, tmpLengthChain); // Check this
195     }
196     FUNCTION_CLEAR();
197 }
198
199 /*
200  * Certificate validation requires that root keys be distributed independently, 
201  * the self-signed certificate that specifies the root certificate authority MAY be omitted 
202  * from the chain, under the assumption that the remote end must already possess it in order to
203  * validate it in any case.
204  */
205
206 // Verifies each certificate from list using next public key from list
207 PKIError CheckCertificateChain (CertificateX509 *chainCrt, uint8_t chainLen, ByteArray caPubKey)
208 {
209     FUNCTION_INIT(
210         int i;
211         CHECK_NULL(chainCrt, PKI_NULL_PASSED);
212         CHECK_LESS_EQUAL(chainLen, MAX_CHAIN_LEN, PKI_WRONG_ARRAY_LEN);
213     );
214     for (i = 0; i < chainLen - 1; i++)
215     {
216        ParsePublicKey(&(chainCrt + 1)->pubKey);
217        CHECK_SIGN(*chainCrt, (chainCrt + 1)->pubKey);
218        CHECK_CALL(CheckSerialNumber, chainCrt->serNum);
219        chainCrt++;
220     }
221     CHECK_SIGN(*chainCrt, caPubKey);
222     CHECK_CALL(CheckSerialNumber, chainCrt->serNum);
223     FUNCTION_CLEAR();
224 }
225