Embed:
(wiki syntax)
Show/hide line numbers
x509.c
Go to the documentation of this file.
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
