Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
x509.c
00001 /** 00002 * @file x509.c 00003 * @brief X.509 certificate parsing and verification 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneCrypto Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include <string.h> 00034 #include <ctype.h> 00035 #include "crypto.h" 00036 #include "x509.h" 00037 #include "asn1.h" 00038 #include "oid.h" 00039 #include "rsa.h" 00040 #include "dsa.h" 00041 #include "ecdsa.h" 00042 #include "md5.h" 00043 #include "sha1.h" 00044 #include "sha224.h" 00045 #include "sha256.h" 00046 #include "sha384.h" 00047 #include "sha512.h" 00048 #include "debug.h" 00049 00050 //Check crypto library configuration 00051 #if (X509_SUPPORT == ENABLED) 00052 00053 //Common Name OID (2.5.4.3) 00054 const uint8_t X509_COMMON_NAME_OID[3] = {0x55, 0x04, 0x03}; 00055 //Surname OID (2.5.4.4) 00056 const uint8_t X509_SURNAME_OID[3] = {0x55, 0x04, 0x04}; 00057 //Serial Number OID (2.5.4.5) 00058 const uint8_t X509_SERIAL_NUMBER_OID[3] = {0x55, 0x04, 0x05}; 00059 //Country Name OID (2.5.4.6) 00060 const uint8_t X509_COUNTRY_NAME_OID[3] = {0x55, 0x04, 0x06}; 00061 //Locality Name OID (2.5.4.7) 00062 const uint8_t X509_LOCALITY_NAME_OID[3] = {0x55, 0x04, 0x07}; 00063 //State Or Province Name OID (2.5.4.8) 00064 const uint8_t X509_STATE_OR_PROVINCE_NAME_OID[] = {0x55, 0x04, 0x08}; 00065 //Organization Name OID (2.5.4.10) 00066 const uint8_t X509_ORGANIZATION_NAME_OID[3] = {0x55, 0x04, 0x0A}; 00067 //Organizational Unit Name OID (2.5.4.11) 00068 const uint8_t X509_ORGANIZATIONAL_UNIT_NAME_OID[3] = {0x55, 0x04, 0x0B}; 00069 //Title OID (2.5.4.12) 00070 const uint8_t X509_TITLE_OID[3] = {0x55, 0x04, 0x0C}; 00071 //Name OID (2.5.4.41) 00072 const uint8_t X509_NAME_OID[3] = {0x55, 0x04, 0x29}; 00073 //Given Name OID (2.5.4.42) 00074 const uint8_t X509_GIVEN_NAME_OID[3] = {0x55, 0x04, 0x2A}; 00075 //Initials OID (2.5.4.43) 00076 const uint8_t X509_INITIALS_OID[3] = {0x55, 0x04, 0x2B}; 00077 //Generation Qualifier OID (2.5.4.44) 00078 const uint8_t X509_GENERATION_QUALIFIER_OID[3] = {0x55, 0x04, 0x2C}; 00079 //DN Qualifier OID (2.5.4.46) 00080 const uint8_t X509_DN_QUALIFIER_OID[3] = {0x55, 0x04, 0x2E}; 00081 //Pseudonym OID (2.5.4.65) 00082 const uint8_t X509_PSEUDONYM_OID[3] = {0x55, 0x04, 0x41}; 00083 00084 //Subject Directory Attributes OID (2.5.29.9) 00085 const uint8_t X509_SUBJECT_DIRECTORY_ATTR_OID[3] = {0x55, 0x1D, 0x09}; 00086 //Subject Key Identifier OID (2.5.29.14) 00087 const uint8_t X509_SUBJECT_KEY_ID_OID[3] = {0x55, 0x1D, 0x0E}; 00088 //Key Usage OID (2.5.29.15) 00089 const uint8_t X509_KEY_USAGE_OID[3] = {0x55, 0x1D, 0x0F}; 00090 //Subject Alternative Name OID (2.5.29.17) 00091 const uint8_t X509_SUBJECT_ALT_NAME_OID[3] = {0x55, 0x1D, 0x11}; 00092 //Issuer Alternative Name OID (2.5.29.18) 00093 const uint8_t X509_ISSUER_ALT_NAME_OID[3] = {0x55, 0x1D, 0x12}; 00094 //Basic Constraints OID (2.5.29.19) 00095 const uint8_t X509_BASIC_CONSTRAINTS_OID[3] = {0x55, 0x1D, 0x13}; 00096 //Name Constraints OID (2.5.29.30) 00097 const uint8_t X509_NAME_CONSTRAINTS_OID[3] = {0x55, 0x1D, 0x1E}; 00098 //CRL Distribution Points OID (2.5.29.31) 00099 const uint8_t X509_CRL_DISTR_POINTS_OID[3] = {0x55, 0x1D, 0x1F}; 00100 //Certificate Policies OID (2.5.29.32) 00101 const uint8_t X509_CERTIFICATE_POLICIES_OID[3] = {0x55, 0x1D, 0x20}; 00102 //Policy Mappings OID (2.5.29.33) 00103 const uint8_t X509_POLICY_MAPPINGS_OID[3] = {0x55, 0x1D, 0x21}; 00104 //Authority Key Identifier OID (2.5.29.35) 00105 const uint8_t X509_AUTHORITY_KEY_ID_OID[3] = {0x55, 0x1D, 0x23}; 00106 //Policy Constraints OID (2.5.29.36) 00107 const uint8_t X509_POLICY_CONSTRAINTS_OID[3] = {0x55, 0x1D, 0x24}; 00108 //Extended Key Usage OID (2.5.29.37) 00109 const uint8_t X509_EXTENDED_KEY_USAGE_OID[3] = {0x55, 0x1D, 0x25}; 00110 //Freshest CRL OID (2.5.29.46) 00111 const uint8_t X509_FRESHEST_CRL_OID[3] = {0x55, 0x1D, 0x2E}; 00112 //Inhibit Any-Policy OID (2.5.29.54) 00113 const uint8_t X509_INHIBIT_ANY_POLICY_OID[3] = {0x55, 0x1D, 0x36}; 00114 00115 00116 /** 00117 * @brief Parse a X.509 certificate 00118 * @param[in] data Pointer to the X.509 certificate to parse 00119 * @param[in] length Length of the X.509 certificate 00120 * @param[out] certInfo Information resulting from the parsing process 00121 * @return Error code 00122 **/ 00123 00124 error_t x509ParseCertificate(const uint8_t *data, size_t length, 00125 X509CertificateInfo *certInfo) 00126 { 00127 error_t error; 00128 size_t totalLength; 00129 Asn1Tag tag; 00130 00131 //Debug message 00132 TRACE_DEBUG("Parsing X.509 certificate...\r\n"); 00133 //Clear the certificate information structure 00134 memset(certInfo, 0, sizeof(X509CertificateInfo)); 00135 00136 //Read the contents of the certificate 00137 error = asn1ReadTag(data, length, &tag); 00138 //Failed to decode ASN.1 tag? 00139 if(error) 00140 return ERROR_BAD_CERTIFICATE; 00141 00142 //Point to the very first field 00143 data = tag.value; 00144 length = tag.length; 00145 00146 //Parse TBSCertificate structure 00147 error = x509ParseTbsCertificate(data, length, &totalLength, certInfo); 00148 //Any error to report? 00149 if(error) 00150 return ERROR_BAD_CERTIFICATE; 00151 00152 //Point to the next field 00153 data += totalLength; 00154 length -= totalLength; 00155 00156 //Parse SignatureAlgorithm structure 00157 error = x509ParseSignatureAlgo(data, length, &totalLength, certInfo); 00158 //Any error to report? 00159 if(error) 00160 return ERROR_BAD_CERTIFICATE; 00161 00162 //Point to the next field 00163 data += totalLength; 00164 length -= totalLength; 00165 00166 //Parse SignatureValue structure 00167 error = x509ParseSignatureValue(data, length, &totalLength, certInfo); 00168 //Any error to report? 00169 if(error) 00170 return ERROR_BAD_CERTIFICATE; 00171 00172 //Certificate successfully parsed 00173 return NO_ERROR; 00174 } 00175 00176 00177 /** 00178 * @brief Parse TBSCertificate structure 00179 * @param[in] data Pointer to the ASN.1 structure to parse 00180 * @param[in] length Length of the ASN.1 structure 00181 * @param[out] totalLength Number of bytes that have been parsed 00182 * @param[out] certInfo Information resulting from the parsing process 00183 * @return Error code 00184 **/ 00185 00186 error_t x509ParseTbsCertificate(const uint8_t *data, size_t length, 00187 size_t *totalLength, X509CertificateInfo *certInfo) 00188 { 00189 error_t error; 00190 size_t n; 00191 Asn1Tag tag; 00192 00193 //Debug message 00194 TRACE_DEBUG(" Parsing TBSCertificate...\r\n"); 00195 00196 //Read the contents of the TBSCertificate structure 00197 error = asn1ReadTag(data, length, &tag); 00198 //Failed to decode ASN.1 tag? 00199 if(error) 00200 return error; 00201 00202 //Save the total length of the field 00203 *totalLength = tag.totalLength; 00204 00205 //The ASN.1 DER encoded tbsCertificate is used as the input to the signature function 00206 certInfo->tbsCertificate = data; 00207 certInfo->tbsCertificateLen = tag.totalLength; 00208 00209 //Point to the very first field of the TBSCertificate 00210 data = tag.value; 00211 length = tag.length; 00212 00213 //Parse Version field 00214 error = x509ParseVersion(data, length, &n, certInfo); 00215 //Failed to parse Version field? 00216 if(error) 00217 return error; 00218 00219 //Point to the next field 00220 data += n; 00221 length -= n; 00222 00223 //Read SerialNumber field 00224 error = x509ParseSerialNumber(data, length, &n, certInfo); 00225 //Failed to parse SerialNumber field? 00226 if(error) 00227 return error; 00228 00229 //Point to the next field 00230 data += n; 00231 length -= n; 00232 00233 //Read Signature field 00234 error = x509ParseSignature(data, length, &n, certInfo); 00235 //Failed to parse Signature field? 00236 if(error) 00237 return error; 00238 00239 //Point to the next field 00240 data += n; 00241 length -= n; 00242 00243 //Read Issuer field 00244 error = x509ParseName(data, length, &n, &certInfo->issuer); 00245 //Failed to parse Issuer field? 00246 if(error) 00247 return error; 00248 00249 //Point to the next field 00250 data += n; 00251 length -= n; 00252 00253 //Read Validity field 00254 error = x509ParseValidity(data, length, &n, certInfo); 00255 //Failed to parse Validity field? 00256 if(error) 00257 return error; 00258 00259 //Point to the next field 00260 data += n; 00261 length -= n; 00262 00263 //Read Subject field 00264 error = x509ParseName(data, length, &n, &certInfo->subject); 00265 //Failed to parse Subject field? 00266 if(error) 00267 return error; 00268 00269 //Point to the next field 00270 data += n; 00271 length -= n; 00272 00273 //Read SubjectPublicKeyInfo field 00274 error = x509ParseSubjectPublicKeyInfo(data, length, &n, certInfo); 00275 //Failed to parse Version field? 00276 if(error) 00277 return error; 00278 00279 //Point to the next field 00280 data += n; 00281 length -= n; 00282 00283 //Read IssuerUniqueID field (optional) 00284 error = x509ParseIssuerUniqueId(data, length, &n, certInfo); 00285 //Failed to parse Version field? 00286 if(error) 00287 return error; 00288 00289 //Point to the next field 00290 data += n; 00291 length -= n; 00292 00293 //Read SubjectUniqueID field (optional) 00294 error = x509ParseSubjectUniqueId(data, length, &n, certInfo); 00295 //Failed to parse Version field? 00296 if(error) 00297 return error; 00298 00299 //Point to the next field 00300 data += n; 00301 length -= n; 00302 00303 //Read SubjectUniqueID field (optional) 00304 error = x509ParseExtensions(data, length, &n, certInfo); 00305 //Failed to parse Version field? 00306 if(error) 00307 return error; 00308 00309 //No error to report 00310 return NO_ERROR; 00311 } 00312 00313 00314 /** 00315 * @brief Parse Version field 00316 * @param[in] data Pointer to the ASN.1 structure to parse 00317 * @param[in] length Length of the ASN.1 structure 00318 * @param[out] totalLength Number of bytes that have been parsed 00319 * @param[out] certInfo Information resulting from the parsing process 00320 * @return Error code 00321 **/ 00322 00323 error_t x509ParseVersion(const uint8_t *data, size_t length, 00324 size_t *totalLength, X509CertificateInfo *certInfo) 00325 { 00326 error_t error; 00327 Asn1Tag tag; 00328 00329 //Debug message 00330 TRACE_DEBUG(" Parsing Version...\r\n"); 00331 00332 //Explicit tagging shall be used to encode version 00333 error = asn1ReadTag(data, length, &tag); 00334 //Failed to decode ASN.1 tag? 00335 if(error) 00336 return error; 00337 00338 //Enforce encoding, class and type 00339 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 0); 00340 00341 //The tag does not match the criteria? 00342 if(error) 00343 { 00344 //Assume X.509v1 format 00345 certInfo->version = X509_VERSION_1; 00346 //Skip the current field 00347 *totalLength = 0; 00348 //Exit immediately 00349 return NO_ERROR; 00350 } 00351 00352 //Save the total length of the field 00353 *totalLength = tag.totalLength; 00354 00355 //Read the inner tag 00356 error = asn1ReadTag(tag.value, tag.length, &tag); 00357 //Failed to decode ASN.1 tag? 00358 if(error) 00359 return error; 00360 00361 //Enforce encoding, class and type 00362 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00363 //The tag does not match the criteria? 00364 if(error) 00365 return error; 00366 00367 //Check length field 00368 if(tag.length != 1) 00369 return ERROR_INVALID_LENGTH; 00370 //Check version field 00371 if(tag.value[0] > X509_VERSION_3) 00372 return ERROR_INVALID_VERSION; 00373 00374 //Save certificate version 00375 certInfo->version = tag.value[0]; 00376 //No error to report 00377 return NO_ERROR; 00378 } 00379 00380 00381 /** 00382 * @brief Parse SerialNumber field 00383 * @param[in] data Pointer to the ASN.1 structure to parse 00384 * @param[in] length Length of the ASN.1 structure 00385 * @param[out] totalLength Number of bytes that have been parsed 00386 * @param[out] certInfo Information resulting from the parsing process 00387 * @return Error code 00388 **/ 00389 00390 error_t x509ParseSerialNumber(const uint8_t *data, size_t length, 00391 size_t *totalLength, X509CertificateInfo *certInfo) 00392 { 00393 error_t error; 00394 Asn1Tag tag; 00395 00396 //Debug message 00397 TRACE_DEBUG(" Parsing SerialNumber...\r\n"); 00398 00399 //Read the contents of the SerialNumber structure 00400 error = asn1ReadTag(data, length, &tag); 00401 //Failed to decode ASN.1 tag? 00402 if(error) 00403 return error; 00404 00405 //Save the total length of the field 00406 *totalLength = tag.totalLength; 00407 00408 //Enforce encoding, class and type 00409 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00410 //The tag does not match the criteria? 00411 if(error) 00412 return error; 00413 00414 //Get the signature value 00415 certInfo->serialNumber = tag.value; 00416 certInfo->serialNumberLen = tag.length; 00417 00418 //No error to report 00419 return NO_ERROR; 00420 } 00421 00422 00423 /** 00424 * @brief Parse Signature field 00425 * @param[in] data Pointer to the ASN.1 structure to parse 00426 * @param[in] length Length of the ASN.1 structure 00427 * @param[out] totalLength Number of bytes that have been parsed 00428 * @param[out] certInfo Information resulting from the parsing process 00429 * @return Error code 00430 **/ 00431 00432 error_t x509ParseSignature(const uint8_t *data, size_t length, 00433 size_t *totalLength, X509CertificateInfo *certInfo) 00434 { 00435 error_t error; 00436 Asn1Tag tag; 00437 00438 //Debug message 00439 TRACE_DEBUG(" Parsing Signature...\r\n"); 00440 00441 //Read the contents of the Signature structure 00442 error = asn1ReadTag(data, length, &tag); 00443 //Failed to decode ASN.1 tag? 00444 if(error) 00445 return error; 00446 00447 //Save the total length of the field 00448 *totalLength = tag.totalLength; 00449 00450 //Enforce encoding, class and type 00451 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 00452 //The tag does not match the criteria? 00453 if(error) 00454 return error; 00455 00456 //Read the inner tag 00457 error = asn1ReadTag(tag.value, tag.length, &tag); 00458 //Failed to decode ASN.1 tag? 00459 if(error) 00460 return error; 00461 00462 //Enforce encoding, class and type 00463 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OBJECT_IDENTIFIER); 00464 //The tag does not match the criteria? 00465 if(error) 00466 return error; 00467 00468 //Get the signature algorithm identifier 00469 certInfo->signatureAlgo = tag.value; 00470 certInfo->signatureAlgoLen = tag.length; 00471 00472 //Validity field successfully parsed 00473 return NO_ERROR; 00474 } 00475 00476 00477 /** 00478 * @brief Parse Name structure 00479 * @param[in] data Pointer to the ASN.1 structure to parse 00480 * @param[in] length Length of the ASN.1 structure 00481 * @param[out] totalLength Number of bytes that have been parsed 00482 * @param[out] name Information resulting from the parsing process 00483 * @return Error code 00484 **/ 00485 00486 error_t x509ParseName(const uint8_t *data, size_t length, 00487 size_t *totalLength, X509Name *name) 00488 { 00489 error_t error; 00490 Asn1Tag tag; 00491 Asn1Tag attrType; 00492 Asn1Tag attrValue; 00493 00494 //Debug message 00495 TRACE_DEBUG(" Parsing Name...\r\n"); 00496 00497 //Read the contents of the Name structure 00498 error = asn1ReadTag(data, length, &tag); 00499 //Failed to decode ASN.1 tag? 00500 if(error) 00501 return error; 00502 00503 //Save the total length of the field 00504 *totalLength = tag.totalLength; 00505 00506 //Raw ASN.1 sequence 00507 name->rawData = data; 00508 name->rawDataLen = tag.totalLength; 00509 00510 //Enforce encoding, class and type 00511 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 00512 //The tag does not match the criteria? 00513 if(error) 00514 return error; 00515 00516 //The Name describes a hierarchical name composed of attributes 00517 data = tag.value; 00518 length = tag.length; 00519 00520 //Loop through all the attributes 00521 while(length > 0) 00522 { 00523 //Read current attribute 00524 error = asn1ReadTag(data, length, &tag); 00525 //Failed to decode ASN.1 tag? 00526 if(error) 00527 return error; 00528 00529 //Enforce encoding, class and type 00530 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SET); 00531 //The tag does not match the criteria? 00532 if(error) 00533 return error; 00534 00535 //Point to the next attribute 00536 data += tag.totalLength; 00537 length -= tag.totalLength; 00538 00539 //Read the inner tag 00540 error = asn1ReadTag(tag.value, tag.length, &tag); 00541 //Failed to decode ASN.1 tag? 00542 if(error) 00543 return error; 00544 00545 //Enforce encoding, class and type 00546 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 00547 //The tag does not match the criteria? 00548 if(error) 00549 return error; 00550 00551 //Read attribute type 00552 error = asn1ReadTag(tag.value, tag.length, &attrType); 00553 //Failed to decode ASN.1 tag? 00554 if(error) 00555 return error; 00556 00557 //Enforce encoding, class and type 00558 error = asn1CheckTag(&attrType, FALSE, 00559 ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OBJECT_IDENTIFIER); 00560 //The tag does not match the criteria? 00561 if(error) 00562 return error; 00563 00564 //Read attribute value 00565 error = asn1ReadTag(tag.value + attrType.totalLength, 00566 tag.length - attrType.totalLength, &attrValue); 00567 //Failed to decode ASN.1 tag? 00568 if(error) 00569 return error; 00570 00571 //Check the length of the OID 00572 if(attrType.length == 3) 00573 { 00574 //Common Name attribute found? 00575 if(!memcmp(attrType.value, X509_COMMON_NAME_OID, 3)) 00576 { 00577 name->commonName = (const char_t *) attrValue.value; 00578 name->commonNameLen = attrValue.length; 00579 } 00580 //Surname attribute found? 00581 else if(!memcmp(attrType.value, X509_SURNAME_OID, 3)) 00582 { 00583 name->surname = (const char_t *) attrValue.value; 00584 name->surnameLen = attrValue.length; 00585 } 00586 //Serial Number attribute found? 00587 else if(!memcmp(attrType.value, X509_SERIAL_NUMBER_OID, 3)) 00588 { 00589 name->serialNumber = (const char_t *) attrValue.value; 00590 name->serialNumberLen = attrValue.length; 00591 } 00592 //Country Name attribute found? 00593 else if(!memcmp(attrType.value, X509_COUNTRY_NAME_OID, 3)) 00594 { 00595 name->countryName = (const char_t *) attrValue.value; 00596 name->countryNameLen = attrValue.length; 00597 } 00598 //Locality Name attribute found? 00599 else if(!memcmp(attrType.value, X509_LOCALITY_NAME_OID, 3)) 00600 { 00601 name->localityName = (const char_t *) attrValue.value; 00602 name->localityNameLen = attrValue.length; 00603 } 00604 //State Or Province Name attribute found? 00605 else if(!memcmp(attrType.value, X509_STATE_OR_PROVINCE_NAME_OID, 3)) 00606 { 00607 name->stateOrProvinceName = (const char_t *) attrValue.value; 00608 name->stateOrProvinceNameLen = attrValue.length; 00609 } 00610 //Organization Name attribute found? 00611 else if(!memcmp(attrType.value, X509_ORGANIZATION_NAME_OID, 3)) 00612 { 00613 name->organizationName = (const char_t *) attrValue.value; 00614 name->organizationNameLen = attrValue.length; 00615 } 00616 //Organizational Unit Name attribute found? 00617 else if(!memcmp(attrType.value, X509_ORGANIZATIONAL_UNIT_NAME_OID, 3)) 00618 { 00619 name->organizationalUnitName = (const char_t *) attrValue.value; 00620 name->organizationalUnitNameLen = attrValue.length; 00621 } 00622 //Title attribute found? 00623 else if(!memcmp(attrType.value, X509_TITLE_OID, 3)) 00624 { 00625 name->title = (const char_t *) attrValue.value; 00626 name->titleLen = attrValue.length; 00627 } 00628 //Name attribute found? 00629 else if(!memcmp(attrType.value, X509_NAME_OID, 3)) 00630 { 00631 name->name = (const char_t *) attrValue.value; 00632 name->nameLen = attrValue.length; 00633 } 00634 //Given Name attribute found? 00635 else if(!memcmp(attrType.value, X509_GIVEN_NAME_OID, 3)) 00636 { 00637 name->givenName = (const char_t *) attrValue.value; 00638 name->givenNameLen = attrValue.length; 00639 } 00640 //Initials attribute OID (2.5.4.43) 00641 else if(!memcmp(attrType.value, X509_INITIALS_OID, 3)) 00642 { 00643 name->initials = (const char_t *) attrValue.value; 00644 name->initialsLen = attrValue.length; 00645 } 00646 //Generation Qualifier attribute found? 00647 else if(!memcmp(attrType.value, X509_GENERATION_QUALIFIER_OID, 3)) 00648 { 00649 name->generationQualifier = (const char_t *) attrValue.value; 00650 name->generationQualifierLen = attrValue.length; 00651 } 00652 //DN Qualifier attribute found? 00653 else if(!memcmp(attrType.value, X509_DN_QUALIFIER_OID, 3)) 00654 { 00655 name->dnQualifier = (const char_t *) attrValue.value; 00656 name->dnQualifierLen = attrValue.length; 00657 } 00658 //Pseudonym attribute found? 00659 else if(!memcmp(attrType.value, X509_PSEUDONYM_OID, 3)) 00660 { 00661 name->pseudonym = (const char_t *) attrValue.value; 00662 name->pseudonymLen = attrValue.length; 00663 } 00664 } 00665 } 00666 00667 //Name field successfully parsed 00668 return NO_ERROR; 00669 } 00670 00671 00672 /** 00673 * @brief Parse Validity field 00674 * @param[in] data Pointer to the ASN.1 structure to parse 00675 * @param[in] length Length of the ASN.1 structure 00676 * @param[out] totalLength Number of bytes that have been parsed 00677 * @param[out] certInfo Information resulting from the parsing process 00678 * @return Error code 00679 **/ 00680 00681 error_t x509ParseValidity(const uint8_t *data, size_t length, 00682 size_t *totalLength, X509CertificateInfo *certInfo) 00683 { 00684 error_t error; 00685 size_t n; 00686 Asn1Tag tag; 00687 00688 //Debug message 00689 TRACE_DEBUG(" Parsing Validity...\r\n"); 00690 00691 //Read current ASN.1 tag 00692 error = asn1ReadTag(data, length, &tag); 00693 //Failed to decode ASN.1 tag? 00694 if(error) 00695 return error; 00696 00697 //Save the total length of the field 00698 *totalLength = tag.totalLength; 00699 00700 //Enforce encoding, class and type 00701 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 00702 //The tag does not match the criteria? 00703 if(error) 00704 return error; 00705 00706 //Point to the very first field of the sequence 00707 data = tag.value; 00708 length = tag.length; 00709 00710 //NotBefore field may be encoded as UTCTime or GeneralizedTime 00711 error = x509ParseTime(data, length, &n, &certInfo->validity.notBefore); 00712 //Failed to decode ASN.1 tag? 00713 if(error) 00714 return error; 00715 00716 //Point to the next field 00717 data += n; 00718 length -= n; 00719 00720 //NotAfter field may be encoded as UTCTime or GeneralizedTime 00721 error = x509ParseTime(data, length, &n, &certInfo->validity.notAfter); 00722 //Failed to decode ASN.1 tag? 00723 if(error) 00724 return error; 00725 00726 //Validity field successfully parsed 00727 return NO_ERROR; 00728 } 00729 00730 00731 /** 00732 * @brief Parse UTCTime or GeneralizedTime structure 00733 * @param[in] data Pointer to the ASN.1 structure to parse 00734 * @param[in] length Length of the ASN.1 structure 00735 * @param[out] totalLength Number of bytes that have been parsed 00736 * @param[out] dateTime date resulting from the parsing process 00737 * @return Error code 00738 **/ 00739 00740 error_t x509ParseTime(const uint8_t *data, size_t length, 00741 size_t *totalLength, DateTime *dateTime) 00742 { 00743 error_t error; 00744 uint_t value; 00745 Asn1Tag tag; 00746 00747 //Debug message 00748 TRACE_DEBUG(" Parsing Time...\r\n"); 00749 00750 //Read current ASN.1 tag 00751 error = asn1ReadTag(data, length, &tag); 00752 //Failed to decode ASN.1 tag? 00753 if(error) 00754 return error; 00755 00756 //Save the total length of the field 00757 *totalLength = tag.totalLength; 00758 00759 //The date may be encoded as UTCTime or GeneralizedTime 00760 if(!asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_UTC_TIME)) 00761 { 00762 //Check the length of the UTCTime field 00763 if(tag.length < 12) 00764 return ERROR_INVALID_SYNTAX; 00765 00766 //The UTCTime uses a 2-digit representation of the year 00767 error = x509ParseInt(tag.value, 2, &value); 00768 //Any error to report? 00769 if(error) 00770 return error; 00771 00772 //If YY is greater than or equal to 50, the year shall be interpreted 00773 //as 19YY. If YY is less than 50, the year shall be interpreted as 20YY 00774 if(value >= 50) 00775 dateTime->year = 1900 + value; 00776 else 00777 dateTime->year = 2000 + value; 00778 00779 //Point to the next field 00780 data = tag.value + 2; 00781 } 00782 else if(!asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_GENERALIZED_TIME)) 00783 { 00784 //Check the length of the GeneralizedTime field 00785 if(tag.length < 14) 00786 return ERROR_INVALID_SYNTAX; 00787 00788 //The GeneralizedTime uses a 4-digit representation of the year 00789 error = x509ParseInt(tag.value, 4, &value); 00790 //Any error to report? 00791 if(error) 00792 return error; 00793 00794 //Point to the next field 00795 data = tag.value + 4; 00796 } 00797 else 00798 { 00799 //The tag does not contain a valid date 00800 return ERROR_FAILURE; 00801 } 00802 00803 //Month 00804 error = x509ParseInt(data, 2, &value); 00805 //Any error to report? 00806 if(error) 00807 return error; 00808 00809 //Save the resulting value 00810 dateTime->month = value; 00811 00812 //Day 00813 error = x509ParseInt(data + 2, 2, &value); 00814 //Any error to report? 00815 if(error) 00816 return error; 00817 00818 //Save the resulting value 00819 dateTime->day = value; 00820 00821 //Hours 00822 error = x509ParseInt(data + 4, 2, &value); 00823 //Any error to report? 00824 if(error) 00825 return error; 00826 00827 //Save the resulting value 00828 dateTime->hours = value; 00829 00830 //Minutes 00831 error = x509ParseInt(data + 6, 2, &value); 00832 //Any error to report? 00833 if(error) 00834 return error; 00835 00836 //Save the resulting value 00837 dateTime->minutes = value; 00838 00839 //Seconds 00840 error = x509ParseInt(data + 8, 2, &value); 00841 //Any error to report? 00842 if(error) 00843 return error; 00844 00845 //Save the resulting value 00846 dateTime->seconds = value; 00847 00848 //Milliseconds 00849 dateTime->milliseconds = 0; 00850 00851 //UTCTime or GeneralizedTime field successfully parsed 00852 return NO_ERROR; 00853 } 00854 00855 00856 /** 00857 * @brief Parse SubjectPublicKeyInfo structure 00858 * @param[in] data Pointer to the ASN.1 structure to parse 00859 * @param[in] length Length of the ASN.1 structure 00860 * @param[out] totalLength Number of bytes that have been parsed 00861 * @param[out] certInfo Information resulting from the parsing process 00862 * @return Error code 00863 **/ 00864 00865 error_t x509ParseSubjectPublicKeyInfo(const uint8_t *data, size_t length, 00866 size_t *totalLength, X509CertificateInfo *certInfo) 00867 { 00868 error_t error; 00869 size_t n; 00870 Asn1Tag tag; 00871 00872 //Debug message 00873 TRACE_DEBUG(" Parsing SubjectPublicKeyInfo...\r\n"); 00874 00875 //Read SubjectPublicKeyInfo field 00876 error = asn1ReadTag(data, length, &tag); 00877 //Failed to decode ASN.1 tag? 00878 if(error) 00879 return error; 00880 00881 //Save the total length of the field 00882 *totalLength = tag.totalLength; 00883 00884 //Enforce encoding, class and type 00885 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 00886 //The tag does not match the criteria? 00887 if(error) 00888 return error; 00889 00890 //Point to the first field 00891 data = tag.value; 00892 length = tag.length; 00893 00894 //Read AlgorithmIdentifier field 00895 error = x509ParseAlgorithmIdentifier(data, length, &n, certInfo); 00896 //Any error to report? 00897 if(error) 00898 return error; 00899 00900 //Point to the next field 00901 data += n; 00902 length -= n; 00903 00904 //The SubjectPublicKey structure is encapsulated within a bit string 00905 error = asn1ReadTag(data, length, &tag); 00906 //Failed to decode ASN.1 tag? 00907 if(error) 00908 return error; 00909 00910 //Enforce encoding, class and type 00911 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_BIT_STRING); 00912 //The tag does not match the criteria? 00913 if(error) 00914 return error; 00915 00916 //The bit string shall contain an initial octet which encodes 00917 //the number of unused bits in the final subsequent octet 00918 if(tag.length < 1 || tag.value[0] != 0x00) 00919 return ERROR_FAILURE; 00920 00921 #if (RSA_SUPPORT == ENABLED) 00922 //RSA algorithm identifier? 00923 if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen, 00924 RSA_ENCRYPTION_OID, sizeof(RSA_ENCRYPTION_OID))) 00925 { 00926 //Read RSAPublicKey structure 00927 error = x509ParseRsaPublicKey(tag.value + 1, tag.length - 1, certInfo); 00928 } 00929 else 00930 #endif 00931 #if (DSA_SUPPORT == ENABLED) 00932 //DSA algorithm identifier? 00933 if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen, 00934 DSA_OID, sizeof(DSA_OID))) 00935 { 00936 //Read DSAPublicKey structure 00937 error = x509ParseDsaPublicKey(tag.value + 1, tag.length - 1, certInfo); 00938 } 00939 else 00940 #endif 00941 #if (EC_SUPPORT == ENABLED) 00942 //EC public key identifier? 00943 if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen, 00944 EC_PUBLIC_KEY_OID, sizeof(EC_PUBLIC_KEY_OID))) 00945 { 00946 //Read ECPublicKey structure 00947 error = x509ParseEcPublicKey(tag.value + 1, tag.length - 1, certInfo); 00948 } 00949 else 00950 #endif 00951 //The certificate does not contain any valid public key... 00952 { 00953 //Report an error 00954 error = ERROR_BAD_CERTIFICATE; 00955 } 00956 00957 //Return status code 00958 return error; 00959 } 00960 00961 00962 /** 00963 * @brief Parse AlgorithmIdentifier structure 00964 * @param[in] data Pointer to the ASN.1 structure to parse 00965 * @param[in] length Length of the ASN.1 structure 00966 * @param[out] totalLength Number of bytes that have been parsed 00967 * @param[out] certInfo Information resulting from the parsing process 00968 * @return Error code 00969 **/ 00970 00971 error_t x509ParseAlgorithmIdentifier(const uint8_t *data, size_t length, 00972 size_t *totalLength, X509CertificateInfo *certInfo) 00973 { 00974 error_t error; 00975 Asn1Tag tag; 00976 00977 //Debug message 00978 TRACE_DEBUG(" Parsing AlgorithmIdentifier...\r\n"); 00979 00980 //Read AlgorithmIdentifier field 00981 error = asn1ReadTag(data, length, &tag); 00982 //Failed to decode ASN.1 tag? 00983 if(error) 00984 return error; 00985 00986 //Save the total length of the field 00987 *totalLength = tag.totalLength; 00988 00989 //Enforce encoding, class and type 00990 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 00991 //The tag does not match the criteria? 00992 if(error) 00993 return error; 00994 00995 //Point to the first field 00996 data = tag.value; 00997 length = tag.length; 00998 00999 //Read algorithm identifier (OID) 01000 error = asn1ReadTag(data, length, &tag); 01001 //Failed to decode ASN.1 tag? 01002 if(error) 01003 return error; 01004 01005 //Enforce encoding, class and type 01006 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OBJECT_IDENTIFIER); 01007 //The tag does not match the criteria? 01008 if(error) 01009 return error; 01010 01011 //Save the algorithm identifier 01012 certInfo->subjectPublicKeyInfo.oid = tag.value; 01013 certInfo->subjectPublicKeyInfo.oidLen = tag.length; 01014 01015 //Point to the next field (if any) 01016 data += tag.totalLength; 01017 length -= tag.totalLength; 01018 01019 #if (RSA_SUPPORT == ENABLED) 01020 //RSA algorithm identifier? 01021 if(!asn1CheckOid(&tag, RSA_ENCRYPTION_OID, sizeof(RSA_ENCRYPTION_OID))) 01022 { 01023 //RSA does not require any additional parameters 01024 error = NO_ERROR; 01025 } 01026 else 01027 #endif 01028 #if (DSA_SUPPORT == ENABLED) 01029 //DSA algorithm identifier? 01030 if(!asn1CheckOid(&tag, DSA_OID, sizeof(DSA_OID))) 01031 { 01032 //Read DsaParameters structure 01033 error = x509ParseDsaParameters(data, length, certInfo); 01034 } 01035 else 01036 #endif 01037 #if (EC_SUPPORT == ENABLED) 01038 //EC public key identifier? 01039 if(!asn1CheckOid(&tag, EC_PUBLIC_KEY_OID, sizeof(EC_PUBLIC_KEY_OID))) 01040 { 01041 //Read ECParameters structure 01042 error = x509ParseEcParameters(data, length, certInfo); 01043 } 01044 else 01045 #endif 01046 //The certificate does not contain any valid public key... 01047 { 01048 //Report an error 01049 error = ERROR_BAD_CERTIFICATE; 01050 } 01051 01052 //Return status code 01053 return error; 01054 } 01055 01056 01057 /** 01058 * @brief Parse RSAPublicKey structure 01059 * @param[in] data Pointer to the ASN.1 structure to parse 01060 * @param[in] length Length of the ASN.1 structure 01061 * @param[out] certInfo Information resulting from the parsing process 01062 * @return Error code 01063 **/ 01064 01065 error_t x509ParseRsaPublicKey(const uint8_t *data, 01066 size_t length, X509CertificateInfo *certInfo) 01067 { 01068 #if (RSA_SUPPORT == ENABLED) 01069 error_t error; 01070 Asn1Tag tag; 01071 01072 //Debug message 01073 TRACE_DEBUG(" Parsing RSAPublicKey...\r\n"); 01074 01075 //Read RSAPublicKey structure 01076 error = asn1ReadTag(data, length, &tag); 01077 //Failed to decode ASN.1 tag? 01078 if(error) 01079 return error; 01080 01081 //Enforce encoding, class and type 01082 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 01083 //The tag does not match the criteria? 01084 if(error) 01085 return error; 01086 01087 //Point to the first field 01088 data = tag.value; 01089 length = tag.length; 01090 01091 //Read Modulus field 01092 error = asn1ReadTag(data, length, &tag); 01093 //Failed to decode ASN.1 tag? 01094 if(error) 01095 return error; 01096 01097 //Enforce encoding, class and type 01098 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 01099 //The tag does not match the criteria? 01100 if(error) 01101 return error; 01102 01103 //Get the modulus 01104 certInfo->subjectPublicKeyInfo.rsaPublicKey.n = tag.value; 01105 certInfo->subjectPublicKeyInfo.rsaPublicKey.nLen = tag.length; 01106 01107 //Point to the next field 01108 data += tag.totalLength; 01109 length -= tag.totalLength; 01110 01111 //Read PublicExponent field 01112 error = asn1ReadTag(data, length, &tag); 01113 //Failed to decode ASN.1 tag? 01114 if(error) 01115 return error; 01116 01117 //Enforce encoding, class and type 01118 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 01119 //The tag does not match the criteria? 01120 if(error) 01121 return error; 01122 01123 //Get the public exponent 01124 certInfo->subjectPublicKeyInfo.rsaPublicKey.e = tag.value; 01125 certInfo->subjectPublicKeyInfo.rsaPublicKey.eLen = tag.length; 01126 01127 //Successful processing 01128 return NO_ERROR; 01129 #else 01130 //Not implemented 01131 return ERROR_NOT_IMPLEMENTED; 01132 #endif 01133 } 01134 01135 01136 /** 01137 * @brief Parse DSA domain parameters 01138 * @param[in] data Pointer to the ASN.1 structure to parse 01139 * @param[in] length Length of the ASN.1 structure 01140 * @param[out] certInfo Information resulting from the parsing process 01141 * @return Error code 01142 **/ 01143 01144 error_t x509ParseDsaParameters(const uint8_t *data, 01145 size_t length, X509CertificateInfo *certInfo) 01146 { 01147 #if (DSA_SUPPORT == ENABLED) 01148 error_t error; 01149 Asn1Tag tag; 01150 01151 //Debug message 01152 TRACE_DEBUG(" Parsing DSAParameters...\r\n"); 01153 01154 //Read DSAParameters structure 01155 error = asn1ReadTag(data, length, &tag); 01156 //Failed to decode ASN.1 tag? 01157 if(error) 01158 return error; 01159 01160 //Enforce encoding, class and type 01161 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 01162 //The tag does not match the criteria? 01163 if(error) 01164 return error; 01165 01166 //Point to the first field 01167 data = tag.value; 01168 length = tag.length; 01169 01170 //Read the parameter p 01171 error = asn1ReadTag(data, length, &tag); 01172 //Failed to decode ASN.1 tag? 01173 if(error) 01174 return error; 01175 01176 //Enforce encoding, class and type 01177 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 01178 //The tag does not match the criteria? 01179 if(error) 01180 return error; 01181 01182 //Save the parameter p 01183 certInfo->subjectPublicKeyInfo.dsaParams.p = tag.value; 01184 certInfo->subjectPublicKeyInfo.dsaParams.pLen = tag.length; 01185 01186 //Point to the next field 01187 data += tag.totalLength; 01188 length -= tag.totalLength; 01189 01190 //Read the parameter q 01191 error = asn1ReadTag(data, length, &tag); 01192 //Failed to decode ASN.1 tag? 01193 if(error) 01194 return error; 01195 01196 //Enforce encoding, class and type 01197 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 01198 //The tag does not match the criteria? 01199 if(error) 01200 return error; 01201 01202 //Save the parameter q 01203 certInfo->subjectPublicKeyInfo.dsaParams.q = tag.value; 01204 certInfo->subjectPublicKeyInfo.dsaParams.qLen = tag.length; 01205 01206 //Point to the next field 01207 data += tag.totalLength; 01208 length -= tag.totalLength; 01209 01210 //Read the parameter g 01211 error = asn1ReadTag(data, length, &tag); 01212 //Failed to decode ASN.1 tag? 01213 if(error) 01214 return error; 01215 01216 //Enforce encoding, class and type 01217 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 01218 //The tag does not match the criteria? 01219 if(error) 01220 return error; 01221 01222 //Save the parameter g 01223 certInfo->subjectPublicKeyInfo.dsaParams.g = tag.value; 01224 certInfo->subjectPublicKeyInfo.dsaParams.gLen = tag.length; 01225 01226 //Successful processing 01227 return NO_ERROR; 01228 #else 01229 //Not implemented 01230 return ERROR_NOT_IMPLEMENTED; 01231 #endif 01232 } 01233 01234 01235 /** 01236 * @brief Parse DSAPublicKey structure 01237 * @param[in] data Pointer to the ASN.1 structure to parse 01238 * @param[in] length Length of the ASN.1 structure 01239 * @param[out] certInfo Information resulting from the parsing process 01240 * @return Error code 01241 **/ 01242 01243 error_t x509ParseDsaPublicKey(const uint8_t *data, 01244 size_t length, X509CertificateInfo *certInfo) 01245 { 01246 #if (DSA_SUPPORT == ENABLED) 01247 error_t error; 01248 Asn1Tag tag; 01249 01250 //Debug message 01251 TRACE_DEBUG(" Parsing DSAPublicKey...\r\n"); 01252 01253 //Read DSAPublicKey structure 01254 error = asn1ReadTag(data, length, &tag); 01255 //Failed to decode ASN.1 tag? 01256 if(error) 01257 return error; 01258 01259 //Enforce encoding, class and type 01260 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 01261 //The tag does not match the criteria? 01262 if(error) 01263 return error; 01264 01265 //Save the DSA public value 01266 certInfo->subjectPublicKeyInfo.dsaPublicKey.y = tag.value; 01267 certInfo->subjectPublicKeyInfo.dsaPublicKey.yLen = tag.length; 01268 01269 //Successful processing 01270 return NO_ERROR; 01271 #else 01272 //Not implemented 01273 return ERROR_NOT_IMPLEMENTED; 01274 #endif 01275 } 01276 01277 01278 /** 01279 * @brief Parse ECParameters structure 01280 * @param[in] data Pointer to the ASN.1 structure to parse 01281 * @param[in] length Length of the ASN.1 structure 01282 * @param[out] certInfo Information resulting from the parsing process 01283 * @return Error code 01284 **/ 01285 01286 error_t x509ParseEcParameters(const uint8_t *data, 01287 size_t length, X509CertificateInfo *certInfo) 01288 { 01289 #if (EC_SUPPORT == ENABLED) 01290 error_t error; 01291 Asn1Tag tag; 01292 01293 //Debug message 01294 TRACE_DEBUG(" Parsing ECParameters...\r\n"); 01295 01296 //Read namedCurve field 01297 error = asn1ReadTag(data, length, &tag); 01298 //Failed to decode ASN.1 tag? 01299 if(error) 01300 return error; 01301 01302 //Enforce encoding, class and type 01303 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OBJECT_IDENTIFIER); 01304 //The tag does not match the criteria? 01305 if(error) 01306 return error; 01307 01308 //The namedCurve field identifies all the required values for a particular 01309 //set of elliptic curve domain parameters to be represented by an object 01310 //identifier 01311 certInfo->subjectPublicKeyInfo.ecParams.namedCurve = tag.value; 01312 certInfo->subjectPublicKeyInfo.ecParams.namedCurveLen = tag.length; 01313 01314 //Successful processing 01315 return NO_ERROR; 01316 #else 01317 //Not implemented 01318 return ERROR_NOT_IMPLEMENTED; 01319 #endif 01320 } 01321 01322 01323 /** 01324 * @brief Parse ECPublicKey structure 01325 * @param[in] data Pointer to the ASN.1 structure to parse 01326 * @param[in] length Length of the ASN.1 structure 01327 * @param[out] certInfo Information resulting from the parsing process 01328 * @return Error code 01329 **/ 01330 01331 error_t x509ParseEcPublicKey(const uint8_t *data, 01332 size_t length, X509CertificateInfo *certInfo) 01333 { 01334 #if (EC_SUPPORT == ENABLED) 01335 //Debug message 01336 TRACE_DEBUG(" Parsing ECPublicKey...\r\n"); 01337 01338 //Make sure the EC public key is valid 01339 if(!length) 01340 return ERROR_BAD_CERTIFICATE; 01341 01342 //Save the EC public value 01343 certInfo->subjectPublicKeyInfo.ecPublicKey.q = data; 01344 certInfo->subjectPublicKeyInfo.ecPublicKey.qLen = length; 01345 01346 //Successful processing 01347 return NO_ERROR; 01348 #else 01349 //Not implemented 01350 return ERROR_NOT_IMPLEMENTED; 01351 #endif 01352 } 01353 01354 01355 /** 01356 * @brief Parse IssuerUniqueID structure 01357 * @param[in] data Pointer to the ASN.1 structure to parse 01358 * @param[in] length Length of the ASN.1 structure 01359 * @param[out] totalLength Number of bytes that have been parsed 01360 * @param[out] certInfo Information resulting from the parsing process 01361 * @return Error code 01362 **/ 01363 01364 error_t x509ParseIssuerUniqueId(const uint8_t *data, size_t length, 01365 size_t *totalLength, X509CertificateInfo *certInfo) 01366 { 01367 error_t error; 01368 Asn1Tag tag; 01369 01370 //No more data to process? 01371 if(!length) 01372 { 01373 //The IssuerUniqueID field is optional 01374 *totalLength = 0; 01375 //Exit immediately 01376 return NO_ERROR; 01377 } 01378 01379 //Explicit tagging is used to encode the IssuerUniqueID field 01380 error = asn1ReadTag(data, length, &tag); 01381 //Failed to decode ASN.1 tag? 01382 if(error) 01383 return error; 01384 01385 //Enforce encoding, class and type 01386 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 1); 01387 //The tag does not match the criteria? 01388 if(error) 01389 { 01390 //The IssuerUniqueID field is optional 01391 *totalLength = 0; 01392 //Exit immediately 01393 return NO_ERROR; 01394 } 01395 01396 //Save the total length of the field 01397 *totalLength = tag.totalLength; 01398 01399 //Debug message 01400 TRACE_DEBUG(" Parsing IssuerUniqueID...\r\n"); 01401 01402 //This field must only appear if the version is 2 or 3 01403 if(certInfo->version < X509_VERSION_2) 01404 return ERROR_INVALID_VERSION; 01405 01406 //Successful processing 01407 return NO_ERROR; 01408 } 01409 01410 01411 /** 01412 * @brief Parse SubjectUniqueID structure 01413 * @param[in] data Pointer to the ASN.1 structure to parse 01414 * @param[in] length Length of the ASN.1 structure 01415 * @param[out] totalLength Number of bytes that have been parsed 01416 * @param[out] certInfo Information resulting from the parsing process 01417 * @return Error code 01418 **/ 01419 01420 error_t x509ParseSubjectUniqueId(const uint8_t *data, size_t length, 01421 size_t *totalLength, X509CertificateInfo *certInfo) 01422 { 01423 error_t error; 01424 Asn1Tag tag; 01425 01426 //No more data to process? 01427 if(!length) 01428 { 01429 //The SubjectUniqueID field is optional 01430 *totalLength = 0; 01431 //Exit immediately 01432 return NO_ERROR; 01433 } 01434 01435 //Explicit tagging is used to encode the SubjectUniqueID field 01436 error = asn1ReadTag(data, length, &tag); 01437 //Failed to decode ASN.1 tag? 01438 if(error) 01439 return error; 01440 01441 //Enforce encoding, class and type 01442 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 2); 01443 //The tag does not match the criteria? 01444 if(error) 01445 { 01446 //The SubjectUniqueID field is optional 01447 *totalLength = 0; 01448 //Exit immediately 01449 return NO_ERROR; 01450 } 01451 01452 //Save the total length of the field 01453 *totalLength = tag.totalLength; 01454 01455 //Debug message 01456 TRACE_DEBUG(" Parsing SubjectUniqueID...\r\n"); 01457 01458 //This field must only appear if the version is 2 or 3 01459 if(certInfo->version < X509_VERSION_2) 01460 return ERROR_INVALID_VERSION; 01461 01462 //Successful processing 01463 return NO_ERROR; 01464 } 01465 01466 01467 /** 01468 * @brief Parse Extensions structure 01469 * @param[in] data Pointer to the ASN.1 structure to parse 01470 * @param[in] length Length of the ASN.1 structure 01471 * @param[out] totalLength Number of bytes that have been parsed 01472 * @param[out] certInfo Information resulting from the parsing process 01473 * @return Error code 01474 **/ 01475 01476 error_t x509ParseExtensions(const uint8_t *data, size_t length, 01477 size_t *totalLength, X509CertificateInfo *certInfo) 01478 { 01479 error_t error; 01480 bool_t critical; 01481 const uint8_t *extensionData; 01482 size_t extensionLength; 01483 Asn1Tag tag; 01484 Asn1Tag oidTag; 01485 01486 //No more data to process? 01487 if(!length) 01488 { 01489 //The Extensions field is optional 01490 *totalLength = 0; 01491 //Exit immediately 01492 return NO_ERROR; 01493 } 01494 01495 //Explicit tagging is used to encode the Extensions field 01496 error = asn1ReadTag(data, length, &tag); 01497 //Failed to decode ASN.1 tag? 01498 if(error) 01499 return error; 01500 01501 //Enforce encoding, class and type 01502 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 3); 01503 //The tag does not match the criteria? 01504 if(error) 01505 { 01506 //The Extensions field is optional 01507 *totalLength = 0; 01508 //Exit immediately 01509 return NO_ERROR; 01510 } 01511 01512 //Save the total length of the field 01513 *totalLength = tag.totalLength; 01514 01515 //Debug message 01516 TRACE_DEBUG(" Parsing Extensions...\r\n"); 01517 01518 //This field must only appear if the version is 3 01519 if(certInfo->version < X509_VERSION_3) 01520 return ERROR_INVALID_VERSION; 01521 01522 //Read inner tag 01523 error = asn1ReadTag(tag.value, tag.length, &tag); 01524 //Failed to decode ASN.1 tag? 01525 if(error) 01526 return error; 01527 01528 //Enforce encoding, class and type 01529 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 01530 //The tag does not match the criteria? 01531 if(error) 01532 return error; 01533 01534 //This field is a sequence of one or more certificate extensions 01535 data = tag.value; 01536 length = tag.length; 01537 01538 //Loop through the extensions 01539 while(length > 0) 01540 { 01541 //Read current extension 01542 error = asn1ReadTag(data, length, &tag); 01543 //Failed to decode ASN.1 tag? 01544 if(error) 01545 return error; 01546 01547 //Enforce encoding, class and type 01548 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 01549 //The tag does not match the criteria? 01550 if(error) 01551 return error; 01552 01553 //Point to the next extension 01554 data += tag.totalLength; 01555 length -= tag.totalLength; 01556 01557 //Contents of the current extension 01558 extensionData = tag.value; 01559 extensionLength = tag.length; 01560 01561 //Read the object identifier 01562 error = asn1ReadTag(extensionData, extensionLength, &oidTag); 01563 //Failed to decode ASN.1 tag? 01564 if(error) 01565 return error; 01566 01567 //Enforce encoding, class and type 01568 error = asn1CheckTag(&oidTag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OBJECT_IDENTIFIER); 01569 //The tag does not match the criteria? 01570 if(error) 01571 return error; 01572 01573 //Next item 01574 extensionData += oidTag.totalLength; 01575 extensionLength -= oidTag.totalLength; 01576 01577 //Read the Critical flag (if present) 01578 error = asn1ReadTag(extensionData, extensionLength, &tag); 01579 //Failed to decode ASN.1 tag? 01580 if(error) 01581 return error; 01582 01583 //Enforce encoding, class and type 01584 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_BOOLEAN); 01585 01586 //Check whether the Critical field is present 01587 if(!error) 01588 { 01589 //Make sure the length of the boolean is valid 01590 if(tag.length != 1) 01591 return ERROR_INVALID_LENGTH; 01592 01593 //Each extension in a certificate is designated as either 01594 //critical or non-critical 01595 critical = tag.value[0] ? TRUE : FALSE; 01596 01597 //Next item 01598 extensionData += tag.totalLength; 01599 extensionLength -= tag.totalLength; 01600 } 01601 else 01602 { 01603 //The extension is considered as non-critical 01604 critical = FALSE; 01605 } 01606 01607 //The extension itself is encapsulated in an octet string 01608 error = asn1ReadTag(extensionData, extensionLength, &tag); 01609 //Failed to decode ASN.1 tag? 01610 if(error) 01611 return error; 01612 01613 //Enforce encoding, class and type 01614 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OCTET_STRING); 01615 //The tag does not match the criteria? 01616 if(error) 01617 return error; 01618 01619 //The current extension matches the BasicConstraints OID? 01620 if(!oidComp(oidTag.value, oidTag.length, X509_BASIC_CONSTRAINTS_OID, 3)) 01621 { 01622 //Parse BasicConstraints extension 01623 error = x509ParseBasicConstraints(tag.value, tag.length, certInfo); 01624 //Any error to report? 01625 if(error) 01626 return error; 01627 } 01628 //The current extension matches the KeyUsage OID? 01629 else if(!oidComp(oidTag.value, oidTag.length, X509_KEY_USAGE_OID, 3)) 01630 { 01631 //Parse KeyUsage extension 01632 } 01633 //The current extension matches the ExtendedKeyUsage OID? 01634 else if(!oidComp(oidTag.value, oidTag.length, X509_EXTENDED_KEY_USAGE_OID, 3)) 01635 { 01636 //Parse ExtendedKeyUsage extension 01637 } 01638 //The current extension is marked as critical? 01639 else if(critical) 01640 { 01641 //A certificate-using system must reject the certificate if it encounters 01642 //a critical extension it does not recognize or a critical extension that 01643 //contains information that it cannot process 01644 return ERROR_UNSUPPORTED_EXTENSION; 01645 } 01646 } 01647 01648 //Successful processing 01649 return NO_ERROR; 01650 } 01651 01652 01653 /** 01654 * @brief Parse BasicConstraints structure 01655 * @param[in] data Pointer to the ASN.1 structure to parse 01656 * @param[in] length Length of the ASN.1 structure 01657 * @param[out] certInfo Information resulting from the parsing process 01658 * @return Error code 01659 **/ 01660 01661 error_t x509ParseBasicConstraints(const uint8_t *data, 01662 size_t length, X509CertificateInfo *certInfo) 01663 { 01664 error_t error; 01665 Asn1Tag tag; 01666 01667 //Debug message 01668 TRACE_DEBUG(" Parsing BasicConstraints...\r\n"); 01669 01670 //The BasicConstraints structure shall contain a valid sequence 01671 error = asn1ReadTag(data, length, &tag); 01672 //Failed to decode ASN.1 tag? 01673 if(error) 01674 return error; 01675 01676 //Enforce encoding, class and type 01677 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 01678 //The tag does not match the criteria? 01679 if(error) 01680 return error; 01681 01682 //Point to the first item of the sequence 01683 data = tag.value; 01684 length = tag.length; 01685 01686 //The cA boolean is optional... 01687 if(length > 0) 01688 { 01689 //The cA boolean indicates whether the certified public key 01690 //may be used to verify certificate signatures 01691 error = asn1ReadTag(data, length, &tag); 01692 //Failed to decode ASN.1 tag? 01693 if(error) 01694 return error; 01695 01696 //Enforce encoding, class and type 01697 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_BOOLEAN); 01698 01699 //The cA field is present? 01700 if(!error) 01701 { 01702 //The tag should be 1-byte long 01703 if(tag.length != 1) 01704 return ERROR_INVALID_LENGTH; 01705 01706 //Get boolean value 01707 certInfo->basicConstraints.ca = tag.value ? TRUE : FALSE; 01708 01709 //Point to the next item 01710 data += tag.totalLength; 01711 length -= tag.totalLength; 01712 } 01713 } 01714 01715 //The pathLenConstraint field is optional... 01716 if(length > 0) 01717 { 01718 //The pathLenConstraint field gives the maximum number of non-self-issued 01719 //intermediate certificates that may follow this certificate in a valid 01720 //certification path 01721 error = asn1ReadTag(data, length, &tag); 01722 //Failed to decode ASN.1 tag? 01723 if(error) 01724 return error; 01725 01726 //Enforce encoding, class and type 01727 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 01728 //The tag does not match the criteria? 01729 if(error) 01730 return error; 01731 01732 //The pathLenConstraint field is not supported 01733 certInfo->basicConstraints.pathLenConstraint = 0; 01734 } 01735 01736 //Successful processing 01737 return NO_ERROR; 01738 } 01739 01740 01741 /** 01742 * @brief Parse SignatureAlgorithm structure 01743 * @param[in] data Pointer to the ASN.1 structure to parse 01744 * @param[in] length Length of the ASN.1 structure 01745 * @param[out] totalLength Number of bytes that have been parsed 01746 * @param[out] certInfo Information resulting from the parsing process 01747 * @return Error code 01748 **/ 01749 01750 error_t x509ParseSignatureAlgo(const uint8_t *data, size_t length, 01751 size_t *totalLength, X509CertificateInfo *certInfo) 01752 { 01753 error_t error; 01754 Asn1Tag tag; 01755 01756 //Debug message 01757 TRACE_DEBUG(" Parsing SignatureAlgorithm...\r\n"); 01758 01759 //Read the contents of the SignatureAlgorithm field 01760 error = asn1ReadTag(data, length, &tag); 01761 //Failed to decode ASN.1 tag? 01762 if(error) 01763 return error; 01764 01765 //Save the total length of the field 01766 *totalLength = tag.totalLength; 01767 01768 //Enforce encoding, class and type 01769 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 01770 //The tag does not match the criteria? 01771 if(error) 01772 return error; 01773 01774 //Read the inner tag 01775 error = asn1ReadTag(tag.value, tag.length, &tag); 01776 //Failed to decode ASN.1 tag? 01777 if(error) 01778 return error; 01779 01780 //This field must contain the same algorithm identifier 01781 //as the signature field in the TBSCertificate sequence 01782 error = asn1CheckOid(&tag, certInfo->signatureAlgo, certInfo->signatureAlgoLen); 01783 //The tag does not match the criteria? 01784 if(error) 01785 return error; 01786 01787 //Successful processing 01788 return NO_ERROR; 01789 } 01790 01791 01792 /** 01793 * @brief Parse SignatureValue field 01794 * @param[in] data Pointer to the ASN.1 structure to parse 01795 * @param[in] length Length of the ASN.1 structure 01796 * @param[out] totalLength Number of bytes that have been parsed 01797 * @param[out] certInfo Information resulting from the parsing process 01798 * @return Error code 01799 **/ 01800 01801 error_t x509ParseSignatureValue(const uint8_t *data, size_t length, 01802 size_t *totalLength, X509CertificateInfo *certInfo) 01803 { 01804 error_t error; 01805 Asn1Tag tag; 01806 01807 //Debug message 01808 TRACE_DEBUG(" Parsing SignatureValue...\r\n"); 01809 01810 //Read the contents of the SignatureValue structure 01811 error = asn1ReadTag(data, length, &tag); 01812 //Failed to decode ASN.1 tag? 01813 if(error) 01814 return error; 01815 01816 //Save the total length of the field 01817 *totalLength = tag.totalLength; 01818 01819 //Enforce encoding, class and type 01820 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_BIT_STRING); 01821 //The tag does not match the criteria? 01822 if(error) 01823 return error; 01824 01825 //The bit string shall contain an initial octet which encodes 01826 //the number of unused bits in the final subsequent octet 01827 if(tag.length < 1 || tag.value[0] != 0x00) 01828 return ERROR_FAILURE; 01829 01830 //Get the signature value 01831 certInfo->signatureValue = tag.value + 1; 01832 certInfo->signatureValueLen = tag.length - 1; 01833 01834 //Successful processing 01835 return NO_ERROR; 01836 } 01837 01838 01839 /** 01840 * @brief Convert string to integer 01841 * @param[in] data String containing the representation of an integral number 01842 * @param[in] length Length of the string 01843 * @param[out] value On success, the function returns the converted integral number 01844 * @return Error code 01845 **/ 01846 01847 error_t x509ParseInt(const uint8_t *data, size_t length, uint_t *value) 01848 { 01849 //Initialize integer value 01850 *value = 0; 01851 01852 //Parse the string 01853 while(length > 0) 01854 { 01855 //Check whether the character is decimal digit 01856 if(!isdigit(*data)) 01857 return ERROR_FAILURE; 01858 01859 //Convert the string to integer 01860 *value = *value * 10 + (*data - '0'); 01861 01862 //Next character 01863 data++; 01864 length--; 01865 } 01866 01867 //Successful processing 01868 return NO_ERROR; 01869 } 01870 01871 01872 /** 01873 * @brief Read a RSA public key 01874 * @param[in] certInfo X.509 certificate 01875 * @param[out] key RSA public key 01876 * @return Error code 01877 **/ 01878 01879 error_t x509ReadRsaPublicKey(const X509CertificateInfo *certInfo, RsaPublicKey *key) 01880 { 01881 #if (RSA_SUPPORT == ENABLED) 01882 error_t error; 01883 01884 //The certificate shall contain a valid RSA public key 01885 if(!certInfo->subjectPublicKeyInfo.rsaPublicKey.n || 01886 !certInfo->subjectPublicKeyInfo.rsaPublicKey.e) 01887 { 01888 //Report an error 01889 return ERROR_INVALID_KEY; 01890 } 01891 01892 //Convert the modulus to a big number 01893 error = mpiReadRaw(&key->n, certInfo->subjectPublicKeyInfo.rsaPublicKey.n, 01894 certInfo->subjectPublicKeyInfo.rsaPublicKey.nLen); 01895 //Convertion failed? 01896 if(error) 01897 return error; 01898 01899 //Convert the public exponent to a big number 01900 error = mpiReadRaw(&key->e, certInfo->subjectPublicKeyInfo.rsaPublicKey.e, 01901 certInfo->subjectPublicKeyInfo.rsaPublicKey.eLen); 01902 //Convertion failed? 01903 if(error) 01904 return error; 01905 01906 //Debug message 01907 TRACE_DEBUG("RSA public key:\r\n"); 01908 TRACE_DEBUG(" Modulus:\r\n"); 01909 TRACE_DEBUG_MPI(" ", &key->n); 01910 TRACE_DEBUG(" Public exponent:\r\n"); 01911 TRACE_DEBUG_MPI(" ", &key->e); 01912 01913 //Successful processing 01914 return NO_ERROR; 01915 #else 01916 //Not implemented 01917 return ERROR_NOT_IMPLEMENTED; 01918 #endif 01919 } 01920 01921 01922 /** 01923 * @brief Read a DSA public key 01924 * @param[in] certInfo X.509 certificate 01925 * @param[out] key DSA public key 01926 * @return Error code 01927 **/ 01928 01929 error_t x509ReadDsaPublicKey(const X509CertificateInfo *certInfo, DsaPublicKey *key) 01930 { 01931 #if (DSA_SUPPORT == ENABLED) 01932 error_t error; 01933 01934 //The certificate shall contain a valid DSA public key 01935 if(!certInfo->subjectPublicKeyInfo.dsaParams.p || 01936 !certInfo->subjectPublicKeyInfo.dsaParams.q || 01937 !certInfo->subjectPublicKeyInfo.dsaParams.g || 01938 !certInfo->subjectPublicKeyInfo.dsaPublicKey.y) 01939 { 01940 //Report an error 01941 return ERROR_INVALID_KEY; 01942 } 01943 01944 //Convert the parameter p to a big number 01945 error = mpiReadRaw(&key->p, certInfo->subjectPublicKeyInfo.dsaParams.p, 01946 certInfo->subjectPublicKeyInfo.dsaParams.pLen); 01947 //Convertion failed? 01948 if(error) 01949 return error; 01950 01951 //Convert the parameter q to a big number 01952 error = mpiReadRaw(&key->q, certInfo->subjectPublicKeyInfo.dsaParams.q, 01953 certInfo->subjectPublicKeyInfo.dsaParams.qLen); 01954 //Convertion failed? 01955 if(error) 01956 return error; 01957 01958 //Convert the parameter g to a big number 01959 error = mpiReadRaw(&key->g, certInfo->subjectPublicKeyInfo.dsaParams.g, 01960 certInfo->subjectPublicKeyInfo.dsaParams.gLen); 01961 //Convertion failed? 01962 if(error) 01963 return error; 01964 01965 //Convert the public value to a big number 01966 error = mpiReadRaw(&key->y, certInfo->subjectPublicKeyInfo.dsaPublicKey.y, 01967 certInfo->subjectPublicKeyInfo.dsaPublicKey.yLen); 01968 //Convertion failed? 01969 if(error) 01970 return error; 01971 01972 //Debug message 01973 TRACE_DEBUG("DSA public key:\r\n"); 01974 TRACE_DEBUG(" Parameter p:\r\n"); 01975 TRACE_DEBUG_MPI(" ", &key->p); 01976 TRACE_DEBUG(" Parameter q:\r\n"); 01977 TRACE_DEBUG_MPI(" ", &key->q); 01978 TRACE_DEBUG(" Parameter g:\r\n"); 01979 TRACE_DEBUG_MPI(" ", &key->g); 01980 TRACE_DEBUG(" Public value y:\r\n"); 01981 TRACE_DEBUG_MPI(" ", &key->y); 01982 01983 //Successful processing 01984 return NO_ERROR; 01985 #else 01986 //Not implemented 01987 return ERROR_NOT_IMPLEMENTED; 01988 #endif 01989 } 01990 01991 01992 /** 01993 * @brief X.509 certificate validation 01994 * @param[in] certInfo X.509 certificate to be verified 01995 * @param[in] issuerCertInfo Issuer certificate 01996 * @return Error code 01997 **/ 01998 01999 error_t x509ValidateCertificate(const X509CertificateInfo *certInfo, 02000 const X509CertificateInfo *issuerCertInfo) 02001 { 02002 error_t error; 02003 time_t currentTime; 02004 time_t notBefore; 02005 time_t notAfter; 02006 const HashAlgo *hashAlgo; 02007 HashContext *hashContext; 02008 02009 //Use RSA, DSA or ECDSA signature algorithm? 02010 #if (RSA_SUPPORT == ENABLED) 02011 bool_t rsaSignAlgo = FALSE; 02012 #endif 02013 #if (DSA_SUPPORT == ENABLED) 02014 bool_t dsaSignAlgo = FALSE; 02015 #endif 02016 #if (ECDSA_SUPPORT == ENABLED) 02017 bool_t ecdsaSignAlgo = FALSE; 02018 #endif 02019 02020 //Retrieve current time 02021 currentTime = getCurrentUnixTime(); 02022 02023 //Any real-time clock implemented? 02024 if(currentTime != 0) 02025 { 02026 //Convert NotBefore and NotAfter to Unix timestamps 02027 notBefore = convertDateToUnixTime(&certInfo->validity.notBefore); 02028 notAfter = convertDateToUnixTime(&certInfo->validity.notAfter); 02029 02030 //Check the certificate validity period 02031 if(currentTime < notBefore || currentTime > notAfter) 02032 return ERROR_CERTIFICATE_EXPIRED; 02033 } 02034 02035 //Make sure that the subject and issuer names chain correctly 02036 if(certInfo->issuer.rawDataLen != issuerCertInfo->subject.rawDataLen) 02037 return ERROR_BAD_CERTIFICATE; 02038 if(memcmp(certInfo->issuer.rawData, issuerCertInfo->subject.rawData, certInfo->issuer.rawDataLen)) 02039 return ERROR_BAD_CERTIFICATE; 02040 02041 //Ensure that the issuer certificate is a CA certificate 02042 if(issuerCertInfo->version >= X509_VERSION_3 && !issuerCertInfo->basicConstraints.ca) 02043 return ERROR_BAD_CERTIFICATE; 02044 02045 //Retrieve the signature algorithm that has been used to sign the certificate 02046 #if (RSA_SUPPORT == ENABLED && MD5_SUPPORT == ENABLED) 02047 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02048 MD5_WITH_RSA_ENCRYPTION_OID, sizeof(MD5_WITH_RSA_ENCRYPTION_OID))) 02049 { 02050 //MD5 with RSA signature algorithm 02051 rsaSignAlgo = TRUE; 02052 hashAlgo = MD5_HASH_ALGO; 02053 } 02054 else 02055 #endif 02056 #if (RSA_SUPPORT == ENABLED && SHA1_SUPPORT == ENABLED) 02057 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02058 SHA1_WITH_RSA_ENCRYPTION_OID, sizeof(SHA1_WITH_RSA_ENCRYPTION_OID))) 02059 { 02060 //SHA-1 with RSA signature algorithm 02061 rsaSignAlgo = TRUE; 02062 hashAlgo = SHA1_HASH_ALGO; 02063 } 02064 else 02065 #endif 02066 #if (RSA_SUPPORT == ENABLED && SHA256_SUPPORT == ENABLED) 02067 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02068 SHA256_WITH_RSA_ENCRYPTION_OID, sizeof(SHA256_WITH_RSA_ENCRYPTION_OID))) 02069 { 02070 //SHA-256 with RSA signature algorithm 02071 rsaSignAlgo = TRUE; 02072 hashAlgo = SHA256_HASH_ALGO; 02073 } 02074 else 02075 #endif 02076 #if (RSA_SUPPORT == ENABLED && SHA384_SUPPORT == ENABLED) 02077 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02078 SHA384_WITH_RSA_ENCRYPTION_OID, sizeof(SHA384_WITH_RSA_ENCRYPTION_OID))) 02079 { 02080 //SHA-384 with RSA signature algorithm 02081 rsaSignAlgo = TRUE; 02082 hashAlgo = SHA384_HASH_ALGO; 02083 } 02084 else 02085 #endif 02086 #if (RSA_SUPPORT == ENABLED && SHA512_SUPPORT == ENABLED) 02087 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02088 SHA512_WITH_RSA_ENCRYPTION_OID, sizeof(SHA512_WITH_RSA_ENCRYPTION_OID))) 02089 { 02090 //SHA-512 with RSA signature algorithm 02091 rsaSignAlgo = TRUE; 02092 hashAlgo = SHA512_HASH_ALGO; 02093 } 02094 else 02095 #endif 02096 #if (DSA_SUPPORT == ENABLED && SHA1_SUPPORT == ENABLED) 02097 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02098 DSA_WITH_SHA1_OID, sizeof(DSA_WITH_SHA1_OID))) 02099 { 02100 //DSA with SHA-1 signature algorithm 02101 dsaSignAlgo = TRUE; 02102 hashAlgo = SHA1_HASH_ALGO; 02103 } 02104 else 02105 #endif 02106 #if (DSA_SUPPORT == ENABLED && SHA224_SUPPORT == ENABLED) 02107 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02108 DSA_WITH_SHA224_OID, sizeof(DSA_WITH_SHA224_OID))) 02109 { 02110 //DSA with SHA-224 signature algorithm 02111 dsaSignAlgo = TRUE; 02112 hashAlgo = SHA224_HASH_ALGO; 02113 } 02114 else 02115 #endif 02116 #if (DSA_SUPPORT == ENABLED && SHA256_SUPPORT == ENABLED) 02117 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02118 DSA_WITH_SHA256_OID, sizeof(DSA_WITH_SHA256_OID))) 02119 { 02120 //DSA with SHA-256 signature algorithm 02121 dsaSignAlgo = TRUE; 02122 hashAlgo = SHA256_HASH_ALGO; 02123 } 02124 else 02125 #endif 02126 #if (ECDSA_SUPPORT == ENABLED && SHA1_SUPPORT == ENABLED) 02127 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02128 ECDSA_WITH_SHA1_OID, sizeof(ECDSA_WITH_SHA1_OID))) 02129 { 02130 //ECDSA with SHA-1 signature algorithm 02131 ecdsaSignAlgo = TRUE; 02132 hashAlgo = SHA1_HASH_ALGO; 02133 } 02134 else 02135 #endif 02136 #if (ECDSA_SUPPORT == ENABLED && SHA224_SUPPORT == ENABLED) 02137 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02138 ECDSA_WITH_SHA224_OID, sizeof(ECDSA_WITH_SHA224_OID))) 02139 { 02140 //ECDSA with SHA-224 signature algorithm 02141 ecdsaSignAlgo = TRUE; 02142 hashAlgo = SHA224_HASH_ALGO; 02143 } 02144 else 02145 #endif 02146 #if (ECDSA_SUPPORT == ENABLED && SHA256_SUPPORT == ENABLED) 02147 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02148 ECDSA_WITH_SHA256_OID, sizeof(ECDSA_WITH_SHA256_OID))) 02149 { 02150 //ECDSA with SHA-256 signature algorithm 02151 ecdsaSignAlgo = TRUE; 02152 hashAlgo = SHA256_HASH_ALGO; 02153 } 02154 else 02155 #endif 02156 #if (ECDSA_SUPPORT == ENABLED && SHA384_SUPPORT == ENABLED) 02157 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02158 ECDSA_WITH_SHA384_OID, sizeof(ECDSA_WITH_SHA384_OID))) 02159 { 02160 //ECDSA with SHA-384 signature algorithm 02161 ecdsaSignAlgo = TRUE; 02162 hashAlgo = SHA384_HASH_ALGO; 02163 } 02164 else 02165 #endif 02166 #if (ECDSA_SUPPORT == ENABLED && SHA512_SUPPORT == ENABLED) 02167 if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02168 ECDSA_WITH_SHA512_OID, sizeof(ECDSA_WITH_SHA512_OID))) 02169 { 02170 //ECDSA with SHA-512 signature algorithm 02171 ecdsaSignAlgo = TRUE; 02172 hashAlgo = SHA512_HASH_ALGO; 02173 } 02174 else 02175 #endif 02176 { 02177 //The specified signature algorithm is not supported 02178 return ERROR_UNSUPPORTED_SIGNATURE_ALGO; 02179 } 02180 02181 //Allocate a memory buffer to hold the hash context 02182 hashContext = cryptoAllocMem(hashAlgo->contextSize); 02183 //Failed to allocate memory? 02184 if(hashContext == NULL) 02185 return ERROR_OUT_OF_MEMORY; 02186 02187 //Digest the TBSCertificate structure using the specified hash algorithm 02188 hashAlgo->init(hashContext); 02189 hashAlgo->update(hashContext, certInfo->tbsCertificate, certInfo->tbsCertificateLen); 02190 hashAlgo->final(hashContext, NULL); 02191 02192 //Check signature algorithm 02193 #if (RSA_SUPPORT == ENABLED) 02194 if(rsaSignAlgo) 02195 { 02196 RsaPublicKey publicKey; 02197 02198 //Initialize RSA public key 02199 rsaInitPublicKey(&publicKey); 02200 02201 //Get the RSA public key 02202 error = x509ReadRsaPublicKey(issuerCertInfo, &publicKey); 02203 02204 //Check status code 02205 if(!error) 02206 { 02207 //Verify RSA signature 02208 error = rsassaPkcs1v15Verify(&publicKey, hashAlgo, hashContext->digest, 02209 certInfo->signatureValue, certInfo->signatureValueLen); 02210 } 02211 02212 //Release previously allocated resources 02213 rsaFreePublicKey(&publicKey); 02214 } 02215 else 02216 #endif 02217 #if (DSA_SUPPORT == ENABLED) 02218 if(dsaSignAlgo) 02219 { 02220 DsaPublicKey publicKey; 02221 DsaSignature signature; 02222 02223 //Initialize DSA public key 02224 dsaInitPublicKey(&publicKey); 02225 //Initialize DSA signature 02226 dsaInitSignature(&signature); 02227 02228 //Get the DSA public key 02229 error = x509ReadDsaPublicKey(issuerCertInfo, &publicKey); 02230 02231 //Check status code 02232 if(!error) 02233 { 02234 //Read the ASN.1 encoded signature 02235 error = dsaReadSignature(certInfo->signatureValue, 02236 certInfo->signatureValueLen, &signature); 02237 } 02238 02239 //Check status code 02240 if(!error) 02241 { 02242 //Verify DSA signature 02243 error = dsaVerifySignature(&publicKey, hashContext->digest, 02244 hashAlgo->digestSize, &signature); 02245 } 02246 02247 //Release previously allocated resources 02248 dsaFreePublicKey(&publicKey); 02249 dsaFreeSignature(&signature); 02250 } 02251 else 02252 #endif 02253 #if (ECDSA_SUPPORT == ENABLED) 02254 if(ecdsaSignAlgo) 02255 { 02256 const EcCurveInfo *curveInfo; 02257 EcDomainParameters params; 02258 EcPoint publicKey; 02259 EcdsaSignature signature; 02260 02261 //Initialize EC domain parameters 02262 ecInitDomainParameters(¶ms); 02263 //Initialize ECDSA public key 02264 ecInit(&publicKey); 02265 //Initialize ECDSA signature 02266 ecdsaInitSignature(&signature); 02267 02268 //Retrieve EC domain parameters 02269 curveInfo = ecGetCurveInfo(issuerCertInfo->subjectPublicKeyInfo.ecParams.namedCurve, 02270 issuerCertInfo->subjectPublicKeyInfo.ecParams.namedCurveLen); 02271 02272 //Make sure the specified elliptic curve is supported 02273 error = (curveInfo == NULL) ? ERROR_BAD_CERTIFICATE : NO_ERROR; 02274 02275 //Check status code 02276 if(!error) 02277 { 02278 //Load EC domain parameters 02279 error = ecLoadDomainParameters(¶ms, curveInfo); 02280 } 02281 02282 //Check status code 02283 if(!error) 02284 { 02285 //Retrieve the EC public key 02286 error = ecImport(¶ms, &publicKey, issuerCertInfo->subjectPublicKeyInfo.ecPublicKey.q, 02287 issuerCertInfo->subjectPublicKeyInfo.ecPublicKey.qLen); 02288 } 02289 02290 //Check status code 02291 if(!error) 02292 { 02293 //Read the ASN.1 encoded signature 02294 error = ecdsaReadSignature(certInfo->signatureValue, 02295 certInfo->signatureValueLen, &signature); 02296 } 02297 02298 //Check status code 02299 if(!error) 02300 { 02301 //Verify ECDSA signature 02302 error = ecdsaVerifySignature(¶ms, &publicKey, 02303 hashContext->digest, hashAlgo->digestSize, &signature); 02304 } 02305 02306 //Release previously allocated resources 02307 ecFreeDomainParameters(¶ms); 02308 ecFree(&publicKey); 02309 ecdsaFreeSignature(&signature); 02310 } 02311 else 02312 #endif 02313 { 02314 //The signature algorithm is not supported... 02315 error = ERROR_UNSUPPORTED_SIGNATURE_ALGO; 02316 } 02317 02318 //Release hash algorithm context 02319 cryptoFreeMem(hashContext); 02320 //Return status code 02321 return error; 02322 } 02323 02324 #endif 02325
Generated on Tue Jul 12 2022 17:10:17 by
1.7.2