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 "crypto_adapter.h"
33 * Check: notBefore <= now <= notAfter.
35 PKIError CheckValidity(ByteArray dateFrom, ByteArray dateTo)
43 CHECK_EQUAL(dateFrom.len, UTC_TIME_LEN, PKI_INVALID_DATE_FORMAT);
44 CHECK_EQUAL(dateTo.len, UTC_TIME_LEN, PKI_INVALID_DATE_FORMAT);
46 /* Get the current time */
48 gmtime_r( &now, &lnow);
49 for (i = 0; i < 2; i ++)
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 */
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';
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);
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);
100 * Decode certDerCode certificate and performs verification.
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
106 PKIError CheckCertificate(ByteArray certDerCode, ByteArray caPublicKey)
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);
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);
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.
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
143 // Parses each certificate from list.
144 PKIError ParseCertificateChain (ByteArray *chainDerCode, CertificateX509 *chainCrt,
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);
153 for (i = 0; i < chainLen; i++)
155 CHECK_CALL(DecodeCertificate, (*chainDerCode), chainCrt);
157 PrintCertificate(chainCrt);
165 // Loads certificates from TLS message
166 PKIError LoadCertificateChain (ByteArray msg, ByteArray *chain, uint8_t *chainLength)
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;
177 CHECK_COND(msg.data[0] != 0 || msg.data[1] != 0 || msg.data[2] != 3, PKI_SUCCESS);
179 printf("start chain parsing\n");
184 printf("chain parsing: %d\n", msg.len);
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;
193 CHECK_LESS_EQUAL((*chainLength), MAX_CHAIN_LEN, PKI_WRONG_ARRAY_LEN);
194 CHECK_INC_BYTE_ARRAY(msg, tmpLengthChain); // Check this
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.
206 // Verifies each certificate from list using next public key from list
207 PKIError CheckCertificateChain (CertificateX509 *chainCrt, uint8_t chainLen, ByteArray caPubKey)
211 CHECK_NULL(chainCrt, PKI_NULL_PASSED);
212 CHECK_LESS_EQUAL(chainLen, MAX_CHAIN_LEN, PKI_WRONG_ARRAY_LEN);
214 for (i = 0; i < chainLen - 1; i++)
216 ParsePublicKey(&(chainCrt + 1)->pubKey);
217 CHECK_SIGN(*chainCrt, (chainCrt + 1)->pubKey);
218 CHECK_CALL(CheckSerialNumber, chainCrt->serNum);
221 CHECK_SIGN(*chainCrt, caPubKey);
222 CHECK_CALL(CheckSerialNumber, chainCrt->serNum);