Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
pem.c
Go to the documentation of this file.
00001 /** 00002 * @file pem.c 00003 * @brief PEM (Privacy-Enhanced Mail) 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 "crypto.h" 00035 #include "pem.h" 00036 #include "asn1.h" 00037 #include "base64.h" 00038 #include "mpi.h" 00039 #include "debug.h" 00040 00041 //Check crypto library configuration 00042 #if (PEM_SUPPORT == ENABLED) 00043 00044 00045 /** 00046 * @brief Decode a PEM file containing Diffie-Hellman parameters 00047 * @param[in] input Pointer to the PEM structure 00048 * @param[in] length Length of the PEM structure 00049 * @param[out] params Diffie-Hellman parameters resulting from the parsing process 00050 * @return Error code 00051 **/ 00052 00053 error_t pemReadDhParameters(const char_t *input, size_t length, DhParameters *params) 00054 { 00055 #if (DH_SUPPORT == ENABLED) 00056 error_t error; 00057 size_t i; 00058 size_t j; 00059 int_t k; 00060 char_t *buffer; 00061 const uint8_t *data; 00062 Asn1Tag tag; 00063 00064 //Check parameters 00065 if(input == NULL && length != 0) 00066 return ERROR_INVALID_PARAMETER; 00067 if(params == NULL) 00068 return ERROR_INVALID_PARAMETER; 00069 00070 //Search for the beginning tag 00071 k = pemSearchTag(input, length, "-----BEGIN DH PARAMETERS-----", 29); 00072 //Failed to find the specified tag? 00073 if(k < 0) 00074 return ERROR_INVALID_SYNTAX; 00075 00076 //Advance the pointer over the tag 00077 input += k + 29; 00078 length -= k + 29; 00079 00080 //Search for the end tag 00081 k = pemSearchTag(input, length, "-----END DH PARAMETERS-----", 27); 00082 //Invalid PEM file? 00083 if(k <= 0) 00084 return ERROR_INVALID_SYNTAX; 00085 00086 //Length of the PEM structure 00087 length = k; 00088 00089 //Allocate a memory buffer to hold the decoded data 00090 buffer = cryptoAllocMem(length); 00091 //Failed to allocate memory? 00092 if(buffer == NULL) 00093 return ERROR_OUT_OF_MEMORY; 00094 00095 //Copy the contents of the PEM structure 00096 memcpy(buffer, input, length); 00097 00098 //Remove carriage returns and line feeds 00099 for(i = 0, j = 0; i < length; i++) 00100 { 00101 if(buffer[i] != '\r' && buffer[i] != '\n') 00102 buffer[j++] = buffer[i]; 00103 } 00104 00105 //Start of exception handling block 00106 do 00107 { 00108 //The PEM file is Base64 encoded... 00109 error = base64Decode(buffer, j, buffer, &length); 00110 //Failed to decode the file? 00111 if(error) 00112 break; 00113 00114 //Point to the resulting ASN.1 structure 00115 data = (uint8_t *) buffer; 00116 00117 //Display ASN.1 structure 00118 error = asn1DumpObject(data, length, 0); 00119 //Any error to report? 00120 if(error) 00121 break; 00122 00123 //The Diffie-Hellman parameters are encapsulated within a sequence 00124 error = asn1ReadTag(data, length, &tag); 00125 //Failed to decode ASN.1 tag? 00126 if(error) 00127 break; 00128 00129 //Enforce encoding, class and type 00130 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 00131 //The tag does not match the criteria? 00132 if(error) 00133 break; 00134 00135 //Point to the first field of the sequence 00136 data = tag.value; 00137 length = tag.length; 00138 00139 //Read the prime modulus 00140 error = asn1ReadTag(data, length, &tag); 00141 //Failed to decode ASN.1 tag? 00142 if(error) 00143 break; 00144 00145 //Enforce encoding, class and type 00146 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00147 //The tag does not match the criteria? 00148 if(error) 00149 break; 00150 00151 //Convert the prime modulus to a multiple precision integer 00152 error = mpiReadRaw(¶ms->p, tag.value, tag.length); 00153 //Any error to report? 00154 if(error) 00155 break; 00156 00157 //Point to the next field 00158 data += tag.totalLength; 00159 length -= tag.totalLength; 00160 00161 //Read the generator 00162 error = asn1ReadTag(data, length, &tag); 00163 //Failed to decode ASN.1 tag? 00164 if(error) 00165 break; 00166 00167 //Enforce encoding, class and type 00168 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00169 //The tag does not match the criteria? 00170 if(error) 00171 break; 00172 00173 //Convert the generator to a multiple precision integer 00174 error = mpiReadRaw(¶ms->g, tag.value, tag.length); 00175 //Any error to report? 00176 if(error) 00177 break; 00178 00179 //Debug message 00180 TRACE_DEBUG("Diffie-Hellman parameters:\r\n"); 00181 TRACE_DEBUG(" Prime modulus:\r\n"); 00182 TRACE_DEBUG_MPI(" ", ¶ms->p); 00183 TRACE_DEBUG(" Generator:\r\n"); 00184 TRACE_DEBUG_MPI(" ", ¶ms->g); 00185 00186 //End of exception handling block 00187 } while(0); 00188 00189 //Release previously allocated memory 00190 cryptoFreeMem(buffer); 00191 00192 //Any error to report? 00193 if(error) 00194 { 00195 //Clean up side effects 00196 mpiFree(¶ms->p); 00197 mpiFree(¶ms->g); 00198 } 00199 00200 //Return status code 00201 return error; 00202 #else 00203 //Not implemented 00204 return ERROR_NOT_IMPLEMENTED; 00205 #endif 00206 } 00207 00208 00209 /** 00210 * @brief Decode a PEM file containing a RSA private key 00211 * @param[in] input Pointer to the PEM structure 00212 * @param[in] length Length of the PEM structure 00213 * @param[out] key RSA private key resulting from the parsing process 00214 * @return Error code 00215 **/ 00216 00217 error_t pemReadRsaPrivateKey(const char_t *input, size_t length, RsaPrivateKey *key) 00218 { 00219 #if (RSA_SUPPORT == ENABLED) 00220 error_t error; 00221 size_t i; 00222 size_t j; 00223 int_t k; 00224 char_t *buffer; 00225 const uint8_t *data; 00226 Asn1Tag tag; 00227 00228 //Check parameters 00229 if(input == NULL && length != 0) 00230 return ERROR_INVALID_PARAMETER; 00231 if(key == NULL) 00232 return ERROR_INVALID_PARAMETER; 00233 00234 //Search for the beginning tag 00235 k = pemSearchTag(input, length, "-----BEGIN RSA PRIVATE KEY-----", 31); 00236 //Failed to find the specified tag? 00237 if(k < 0) 00238 return ERROR_INVALID_SYNTAX; 00239 00240 //Advance the pointer over the tag 00241 input += k + 31; 00242 length -= k + 31; 00243 00244 //Search for the end tag 00245 k = pemSearchTag(input, length, "-----END RSA PRIVATE KEY-----", 29); 00246 //Invalid PEM file? 00247 if(k <= 0) 00248 return ERROR_INVALID_SYNTAX; 00249 00250 //Length of the PEM structure 00251 length = k; 00252 00253 //Allocate a memory buffer to hold the decoded data 00254 buffer = cryptoAllocMem(length); 00255 //Failed to allocate memory? 00256 if(buffer == NULL) 00257 return ERROR_OUT_OF_MEMORY; 00258 00259 //Copy the contents of the PEM structure 00260 memcpy(buffer, input, length); 00261 00262 //Remove carriage returns and line feeds 00263 for(i = 0, j = 0; i < length; i++) 00264 { 00265 if(buffer[i] != '\r' && buffer[i] != '\n') 00266 buffer[j++] = buffer[i]; 00267 } 00268 00269 //Start of exception handling block 00270 do 00271 { 00272 //The PEM file is Base64 encoded... 00273 error = base64Decode(buffer, j, buffer, &length); 00274 //Failed to decode the file? 00275 if(error) 00276 break; 00277 00278 //Point to the resulting ASN.1 structure 00279 data = (uint8_t *) buffer; 00280 00281 //Display ASN.1 structure 00282 error = asn1DumpObject(data, length, 0); 00283 //Any error to report? 00284 if(error) 00285 break; 00286 00287 //The RSA private key is encapsulated within a sequence 00288 error = asn1ReadTag(data, length, &tag); 00289 //Failed to decode ASN.1 tag? 00290 if(error) 00291 break; 00292 00293 //Enforce encoding, class and type 00294 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 00295 //The tag does not match the criteria? 00296 if(error) 00297 break; 00298 00299 //Point to the first field of the sequence 00300 data = tag.value; 00301 length = tag.length; 00302 00303 //Read the version 00304 error = asn1ReadTag(data, length, &tag); 00305 //Failed to decode ASN.1 tag? 00306 if(error) 00307 break; 00308 00309 //Enforce encoding, class and type 00310 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00311 //The tag does not match the criteria? 00312 if(error) 00313 break; 00314 00315 //Skip the version field 00316 data += tag.totalLength; 00317 length -= tag.totalLength; 00318 00319 //Read the modulus 00320 error = asn1ReadTag(data, length, &tag); 00321 //Failed to decode ASN.1 tag? 00322 if(error) 00323 break; 00324 00325 //Enforce encoding, class and type 00326 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00327 //The tag does not match the criteria? 00328 if(error) 00329 break; 00330 00331 //Convert the modulus to a multiple precision integer 00332 error = mpiReadRaw(&key->n, tag.value, tag.length); 00333 //Any error to report? 00334 if(error) 00335 break; 00336 00337 //Point to the next field 00338 data += tag.totalLength; 00339 length -= tag.totalLength; 00340 00341 //Read the public exponent 00342 error = asn1ReadTag(data, length, &tag); 00343 //Failed to decode ASN.1 tag? 00344 if(error) 00345 break; 00346 00347 //Enforce encoding, class and type 00348 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00349 //The tag does not match the criteria? 00350 if(error) 00351 break; 00352 00353 //Convert the public exponent to a multiple precision integer 00354 error = mpiReadRaw(&key->e, tag.value, tag.length); 00355 //Any error to report? 00356 if(error) 00357 break; 00358 00359 //Point to the next field 00360 data += tag.totalLength; 00361 length -= tag.totalLength; 00362 00363 //Read the private exponent 00364 error = asn1ReadTag(data, length, &tag); 00365 //Failed to decode ASN.1 tag? 00366 if(error) 00367 break; 00368 00369 //Enforce encoding, class and type 00370 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00371 //The tag does not match the criteria? 00372 if(error) 00373 break; 00374 00375 //Convert the private exponent to a multiple precision integer 00376 error = mpiReadRaw(&key->d, tag.value, tag.length); 00377 //Any error to report? 00378 if(error) 00379 break; 00380 00381 //Point to the next field 00382 data += tag.totalLength; 00383 length -= tag.totalLength; 00384 00385 //Read the first factor 00386 error = asn1ReadTag(data, length, &tag); 00387 //Failed to decode ASN.1 tag? 00388 if(error) 00389 break; 00390 00391 //Enforce encoding, class and type 00392 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00393 //The tag does not match the criteria? 00394 if(error) 00395 break; 00396 00397 //Convert the first factor to a multiple precision integer 00398 error = mpiReadRaw(&key->p, tag.value, tag.length); 00399 //Any error to report? 00400 if(error) 00401 break; 00402 00403 //Point to the next field 00404 data += tag.totalLength; 00405 length -= tag.totalLength; 00406 00407 //Read the second factor 00408 error = asn1ReadTag(data, length, &tag); 00409 //Failed to decode ASN.1 tag? 00410 if(error) 00411 break; 00412 00413 //Enforce encoding, class and type 00414 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00415 //The tag does not match the criteria? 00416 if(error) 00417 break; 00418 00419 //Convert the second factor to a multiple precision integer 00420 error = mpiReadRaw(&key->q, tag.value, tag.length); 00421 //Any error to report? 00422 if(error) 00423 break; 00424 00425 //Point to the next field 00426 data += tag.totalLength; 00427 length -= tag.totalLength; 00428 00429 //Read the first exponent 00430 error = asn1ReadTag(data, length, &tag); 00431 //Failed to decode ASN.1 tag? 00432 if(error) 00433 break; 00434 00435 //Enforce encoding, class and type 00436 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00437 //The tag does not match the criteria? 00438 if(error) 00439 break; 00440 00441 //Convert the first exponent to a multiple precision integer 00442 error = mpiReadRaw(&key->dp, tag.value, tag.length); 00443 //Any error to report? 00444 if(error) 00445 break; 00446 00447 //Point to the next field 00448 data += tag.totalLength; 00449 length -= tag.totalLength; 00450 00451 //Read the second exponent 00452 error = asn1ReadTag(data, length, &tag); 00453 //Failed to decode ASN.1 tag? 00454 if(error) 00455 break; 00456 00457 //Enforce encoding, class and type 00458 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00459 //The tag does not match the criteria? 00460 if(error) 00461 break; 00462 00463 //Convert the second exponent to a multiple precision integer 00464 error = mpiReadRaw(&key->dq, tag.value, tag.length); 00465 //Any error to report? 00466 if(error) 00467 break; 00468 00469 //Point to the next field 00470 data += tag.totalLength; 00471 length -= tag.totalLength; 00472 00473 //Read the coefficient 00474 error = asn1ReadTag(data, length, &tag); 00475 //Failed to decode ASN.1 tag? 00476 if(error) 00477 break; 00478 00479 //Enforce encoding, class and type 00480 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00481 //The tag does not match the criteria? 00482 if(error) 00483 break; 00484 00485 //Convert the coefficient to a multiple precision integer 00486 error = mpiReadRaw(&key->qinv, tag.value, tag.length); 00487 //Any error to report? 00488 if(error) 00489 break; 00490 00491 //Debug message 00492 TRACE_DEBUG("RSA private key:\r\n"); 00493 TRACE_DEBUG(" Modulus:\r\n"); 00494 TRACE_DEBUG_MPI(" ", &key->n); 00495 TRACE_DEBUG(" Public exponent:\r\n"); 00496 TRACE_DEBUG_MPI(" ", &key->e); 00497 TRACE_DEBUG(" Private exponent:\r\n"); 00498 TRACE_DEBUG_MPI(" ", &key->d); 00499 TRACE_DEBUG(" Prime 1:\r\n"); 00500 TRACE_DEBUG_MPI(" ", &key->p); 00501 TRACE_DEBUG(" Prime 2:\r\n"); 00502 TRACE_DEBUG_MPI(" ", &key->q); 00503 TRACE_DEBUG(" Prime exponent 1:\r\n"); 00504 TRACE_DEBUG_MPI(" ", &key->dp); 00505 TRACE_DEBUG(" Prime exponent 2:\r\n"); 00506 TRACE_DEBUG_MPI(" ", &key->dq); 00507 TRACE_DEBUG(" Coefficient:\r\n"); 00508 TRACE_DEBUG_MPI(" ", &key->qinv); 00509 00510 //End of exception handling block 00511 } while(0); 00512 00513 //Release previously allocated memory 00514 cryptoFreeMem(buffer); 00515 00516 //Clean up side effects if necessary 00517 if(error) 00518 rsaFreePrivateKey(key); 00519 00520 //Return status code 00521 return error; 00522 #else 00523 //Not implemented 00524 return ERROR_NOT_IMPLEMENTED; 00525 #endif 00526 } 00527 00528 00529 /** 00530 * @brief Decode a PEM file containing a DSA private key 00531 * @param[in] input Pointer to the PEM structure 00532 * @param[in] length Length of the PEM structure 00533 * @param[out] key DSA private key resulting from the parsing process 00534 * @return Error code 00535 **/ 00536 00537 error_t pemReadDsaPrivateKey(const char_t *input, size_t length, DsaPrivateKey *key) 00538 { 00539 #if (DSA_SUPPORT == ENABLED) 00540 error_t error; 00541 size_t i; 00542 size_t j; 00543 int_t k; 00544 char_t *buffer; 00545 const uint8_t *data; 00546 Asn1Tag tag; 00547 00548 //Check parameters 00549 if(input == NULL && length != 0) 00550 return ERROR_INVALID_PARAMETER; 00551 if(key == NULL) 00552 return ERROR_INVALID_PARAMETER; 00553 00554 //Search for the beginning tag 00555 k = pemSearchTag(input, length, "-----BEGIN DSA PRIVATE KEY-----", 31); 00556 //Failed to find the specified tag? 00557 if(k < 0) 00558 return ERROR_INVALID_SYNTAX; 00559 00560 //Advance the pointer over the tag 00561 input += k + 31; 00562 length -= k + 31; 00563 00564 //Search for the end tag 00565 k = pemSearchTag(input, length, "-----END DSA PRIVATE KEY-----", 29); 00566 //Invalid PEM file? 00567 if(k <= 0) 00568 return ERROR_INVALID_SYNTAX; 00569 00570 //Length of the PEM structure 00571 length = k; 00572 00573 //Allocate a memory buffer to hold the decoded data 00574 buffer = cryptoAllocMem(length); 00575 //Failed to allocate memory? 00576 if(buffer == NULL) 00577 return ERROR_OUT_OF_MEMORY; 00578 00579 //Copy the contents of the PEM structure 00580 memcpy(buffer, input, length); 00581 00582 //Remove carriage returns and line feeds 00583 for(i = 0, j = 0; i < length; i++) 00584 { 00585 if(buffer[i] != '\r' && buffer[i] != '\n') 00586 buffer[j++] = buffer[i]; 00587 } 00588 00589 //Start of exception handling block 00590 do 00591 { 00592 //The PEM file is Base64 encoded... 00593 error = base64Decode(buffer, j, buffer, &length); 00594 //Failed to decode the file? 00595 if(error) 00596 break; 00597 00598 //Point to the resulting ASN.1 structure 00599 data = (uint8_t *) buffer; 00600 00601 //Display ASN.1 structure 00602 error = asn1DumpObject(data, length, 0); 00603 //Any error to report? 00604 if(error) 00605 break; 00606 00607 //The DSA private key is encapsulated within a sequence 00608 error = asn1ReadTag(data, length, &tag); 00609 //Failed to decode ASN.1 tag? 00610 if(error) 00611 break; 00612 00613 //Enforce encoding, class and type 00614 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 00615 //The tag does not match the criteria? 00616 if(error) 00617 break; 00618 00619 //Point to the first field of the sequence 00620 data = tag.value; 00621 length = tag.length; 00622 00623 //Read the version 00624 error = asn1ReadTag(data, length, &tag); 00625 //Failed to decode ASN.1 tag? 00626 if(error) 00627 break; 00628 00629 //Enforce encoding, class and type 00630 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00631 //The tag does not match the criteria? 00632 if(error) 00633 break; 00634 00635 //Skip the version field 00636 data += tag.totalLength; 00637 length -= tag.totalLength; 00638 00639 //Read p 00640 error = asn1ReadTag(data, length, &tag); 00641 //Failed to decode ASN.1 tag? 00642 if(error) 00643 break; 00644 00645 //Enforce encoding, class and type 00646 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00647 //The tag does not match the criteria? 00648 if(error) 00649 break; 00650 00651 //Convert p to a multiple precision integer 00652 error = mpiReadRaw(&key->p, tag.value, tag.length); 00653 //Any error to report? 00654 if(error) 00655 break; 00656 00657 //Point to the next field 00658 data += tag.totalLength; 00659 length -= tag.totalLength; 00660 00661 //Read q 00662 error = asn1ReadTag(data, length, &tag); 00663 //Failed to decode ASN.1 tag? 00664 if(error) 00665 break; 00666 00667 //Enforce encoding, class and type 00668 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00669 //The tag does not match the criteria? 00670 if(error) 00671 break; 00672 00673 //Convert q to a multiple precision integer 00674 error = mpiReadRaw(&key->q, tag.value, tag.length); 00675 //Any error to report? 00676 if(error) 00677 break; 00678 00679 //Point to the next field 00680 data += tag.totalLength; 00681 length -= tag.totalLength; 00682 00683 //Read g 00684 error = asn1ReadTag(data, length, &tag); 00685 //Failed to decode ASN.1 tag? 00686 if(error) 00687 break; 00688 00689 //Enforce encoding, class and type 00690 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00691 //The tag does not match the criteria? 00692 if(error) 00693 break; 00694 00695 //Convert g to a multiple precision integer 00696 error = mpiReadRaw(&key->g, tag.value, tag.length); 00697 //Any error to report? 00698 if(error) 00699 break; 00700 00701 //Point to the next field 00702 data += tag.totalLength; 00703 length -= tag.totalLength; 00704 00705 //Read the public value 00706 error = asn1ReadTag(data, length, &tag); 00707 //Failed to decode ASN.1 tag? 00708 if(error) 00709 break; 00710 00711 //Enforce encoding, class and type 00712 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00713 //The tag does not match the criteria? 00714 if(error) 00715 break; 00716 00717 //Point to the next field 00718 data += tag.totalLength; 00719 length -= tag.totalLength; 00720 00721 //Read the private value 00722 error = asn1ReadTag(data, length, &tag); 00723 //Failed to decode ASN.1 tag? 00724 if(error) 00725 break; 00726 00727 //Enforce encoding, class and type 00728 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00729 //The tag does not match the criteria? 00730 if(error) 00731 break; 00732 00733 //Convert the private value to a multiple precision integer 00734 error = mpiReadRaw(&key->x, tag.value, tag.length); 00735 //Any error to report? 00736 if(error) 00737 break; 00738 00739 //Debug message 00740 TRACE_DEBUG("DSA private key:\r\n"); 00741 TRACE_DEBUG(" p:\r\n"); 00742 TRACE_DEBUG_MPI(" ", &key->p); 00743 TRACE_DEBUG(" q:\r\n"); 00744 TRACE_DEBUG_MPI(" ", &key->q); 00745 TRACE_DEBUG(" g:\r\n"); 00746 TRACE_DEBUG_MPI(" ", &key->g); 00747 TRACE_DEBUG(" x:\r\n"); 00748 TRACE_DEBUG_MPI(" ", &key->x); 00749 00750 //End of exception handling block 00751 } while(0); 00752 00753 //Release previously allocated memory 00754 cryptoFreeMem(buffer); 00755 00756 //Clean up side effects if necessary 00757 if(error) 00758 dsaFreePrivateKey(key); 00759 00760 //Return status code 00761 return error; 00762 #else 00763 //Not implemented 00764 return ERROR_NOT_IMPLEMENTED; 00765 #endif 00766 } 00767 00768 00769 /** 00770 * @brief Decode a PEM file containing EC domain parameters 00771 * @param[in] input Pointer to the PEM structure 00772 * @param[in] length Length of the PEM structure 00773 * @param[out] params EC domain parameters 00774 * @return Error code 00775 **/ 00776 00777 error_t pemReadEcParameters(const char_t *input, size_t length, EcDomainParameters *params) 00778 { 00779 #if (EC_SUPPORT == ENABLED) 00780 error_t error; 00781 size_t i; 00782 size_t j; 00783 int_t k; 00784 char_t *buffer; 00785 const uint8_t *data; 00786 Asn1Tag tag; 00787 const EcCurveInfo *curveInfo; 00788 00789 //Check parameters 00790 if(input == NULL && length != 0) 00791 return ERROR_INVALID_PARAMETER; 00792 if(params == NULL) 00793 return ERROR_INVALID_PARAMETER; 00794 00795 //Check the format of the PEM file 00796 if(pemSearchTag(input, length, "-----BEGIN EC PARAMETERS-----", 29) >= 0) 00797 { 00798 //Search for the beginning tag 00799 k = pemSearchTag(input, length, "-----BEGIN EC PARAMETERS-----", 29); 00800 //Failed to find the specified tag? 00801 if(k < 0) 00802 return ERROR_INVALID_SYNTAX; 00803 00804 //Advance the pointer over the tag 00805 input += k + 29; 00806 length -= k + 29; 00807 00808 //Search for the end tag 00809 k = pemSearchTag(input, length, "-----END EC PARAMETERS-----", 27); 00810 //Invalid PEM file? 00811 if(k <= 0) 00812 return ERROR_INVALID_SYNTAX; 00813 00814 //Length of the PEM structure 00815 length = k; 00816 00817 //Allocate a memory buffer to hold the decoded data 00818 buffer = cryptoAllocMem(length); 00819 //Failed to allocate memory? 00820 if(buffer == NULL) 00821 return ERROR_OUT_OF_MEMORY; 00822 00823 //Copy the contents of the PEM structure 00824 memcpy(buffer, input, length); 00825 00826 //Remove carriage returns and line feeds 00827 for(i = 0, j = 0; i < length; i++) 00828 { 00829 if(buffer[i] != '\r' && buffer[i] != '\n') 00830 buffer[j++] = buffer[i]; 00831 } 00832 00833 //Start of exception handling block 00834 do 00835 { 00836 //The PEM file is Base64 encoded... 00837 error = base64Decode(buffer, j, buffer, &length); 00838 //Failed to decode the file? 00839 if(error) 00840 break; 00841 00842 //Point to the resulting ASN.1 structure 00843 data = (uint8_t *) buffer; 00844 00845 //Display ASN.1 structure 00846 error = asn1DumpObject(data, length, 0); 00847 //Any error to report? 00848 if(error) 00849 break; 00850 00851 //Read the curve identifier 00852 error = asn1ReadTag(data, length, &tag); 00853 //Failed to decode ASN.1 tag? 00854 if(error) 00855 break; 00856 00857 //Enforce encoding, class and type 00858 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OBJECT_IDENTIFIER); 00859 //The tag does not match the criteria? 00860 if(error) 00861 break; 00862 00863 //Retrieve EC domain parameters 00864 curveInfo = ecGetCurveInfo(tag.value, tag.length); 00865 //Make sure the specified elliptic curve is supported 00866 if(curveInfo == NULL) 00867 { 00868 //Report an error 00869 error = ERROR_ILLEGAL_PARAMETER; 00870 //Exit immediately 00871 break; 00872 } 00873 00874 //Load EC domain parameters 00875 error = ecLoadDomainParameters(params, curveInfo); 00876 //Any error to report? 00877 if(error) 00878 break; 00879 00880 //End of exception handling block 00881 } while(0); 00882 } 00883 else 00884 { 00885 //Search for the beginning tag 00886 k = pemSearchTag(input, length, "-----BEGIN PRIVATE KEY-----", 27); 00887 //Failed to find the specified tag? 00888 if(k < 0) 00889 return ERROR_INVALID_SYNTAX; 00890 00891 //Advance the pointer over the tag 00892 input += k + 27; 00893 length -= k + 27; 00894 00895 //Search for the end tag 00896 k = pemSearchTag(input, length, "-----END PRIVATE KEY-----", 25); 00897 //Invalid PEM file? 00898 if(k <= 0) 00899 return ERROR_INVALID_SYNTAX; 00900 00901 //Length of the PEM structure 00902 length = k; 00903 00904 //Allocate a memory buffer to hold the decoded data 00905 buffer = cryptoAllocMem(length); 00906 //Failed to allocate memory? 00907 if(buffer == NULL) 00908 return ERROR_OUT_OF_MEMORY; 00909 00910 //Copy the contents of the PEM structure 00911 memcpy(buffer, input, length); 00912 00913 //Remove carriage returns and line feeds 00914 for(i = 0, j = 0; i < length; i++) 00915 { 00916 if(buffer[i] != '\r' && buffer[i] != '\n') 00917 buffer[j++] = buffer[i]; 00918 } 00919 00920 //Start of exception handling block 00921 do 00922 { 00923 //The PEM file is Base64 encoded... 00924 error = base64Decode(buffer, j, buffer, &length); 00925 //Failed to decode the file? 00926 if(error) 00927 break; 00928 00929 //Point to the resulting ASN.1 structure 00930 data = (uint8_t *) buffer; 00931 00932 //Display ASN.1 structure 00933 error = asn1DumpObject(data, length, 0); 00934 //Any error to report? 00935 if(error) 00936 break; 00937 00938 //The private key is encapsulated within a sequence 00939 error = asn1ReadTag(data, length, &tag); 00940 //Failed to decode ASN.1 tag? 00941 if(error) 00942 break; 00943 00944 //Enforce encoding, class and type 00945 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 00946 //The tag does not match the criteria? 00947 if(error) 00948 break; 00949 00950 //Point to the first field of the sequence 00951 data = tag.value; 00952 length = tag.length; 00953 00954 //Read the Version field 00955 error = asn1ReadTag(data, length, &tag); 00956 //Failed to decode ASN.1 tag? 00957 if(error) 00958 break; 00959 00960 //Enforce encoding, class and type 00961 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 00962 //The tag does not match the criteria? 00963 if(error) 00964 break; 00965 00966 //Skip the Version field 00967 data += tag.totalLength; 00968 length -= tag.totalLength; 00969 00970 //Read the PrivateKeyAlgorithmIdentifier field 00971 error = asn1ReadTag(data, length, &tag); 00972 //Failed to decode ASN.1 tag? 00973 if(error) 00974 break; 00975 00976 //Enforce encoding, class and type 00977 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 00978 //The tag does not match the criteria? 00979 if(error) 00980 break; 00981 00982 //Point to the first field of the sequence 00983 data = tag.value; 00984 length = tag.length; 00985 00986 //Read the algorithm identifier (OID) 00987 error = asn1ReadTag(data, length, &tag); 00988 //Failed to decode ASN.1 tag? 00989 if(error) 00990 break; 00991 00992 //Check algorithm identifier 00993 error = asn1CheckOid(&tag, EC_PUBLIC_KEY_OID, sizeof(EC_PUBLIC_KEY_OID)); 00994 //Wrong identifier? 00995 if(error) 00996 break; 00997 00998 //Point to the next field 00999 data += tag.totalLength; 01000 length += tag.totalLength; 01001 01002 //Read namedCurve field 01003 error = asn1ReadTag(data, length, &tag); 01004 //Failed to decode ASN.1 tag? 01005 if(error) 01006 break; 01007 01008 //Enforce encoding, class and type 01009 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OBJECT_IDENTIFIER); 01010 //The tag does not match the criteria? 01011 if(error) 01012 break; 01013 01014 //Retrieve EC domain parameters 01015 curveInfo = ecGetCurveInfo(tag.value, tag.length); 01016 //Make sure the specified elliptic curve is supported 01017 if(curveInfo == NULL) 01018 { 01019 //Report an error 01020 error = ERROR_ILLEGAL_PARAMETER; 01021 //Exit immediately 01022 break; 01023 } 01024 01025 //Load EC domain parameters 01026 error = ecLoadDomainParameters(params, curveInfo); 01027 //Any error to report? 01028 if(error) 01029 break; 01030 01031 //End of exception handling block 01032 } while(0); 01033 } 01034 01035 //Release previously allocated memory 01036 cryptoFreeMem(buffer); 01037 01038 //Clean up side effects if necessary 01039 if(error) 01040 ecFreeDomainParameters(params); 01041 01042 //Return status code 01043 return error; 01044 #else 01045 //Not implemented 01046 return ERROR_NOT_IMPLEMENTED; 01047 #endif 01048 } 01049 01050 01051 /** 01052 * @brief Decode a PEM file containing an EC private key 01053 * @param[in] input Pointer to the PEM structure 01054 * @param[in] length Length of the PEM structure 01055 * @param[out] key EC private key resulting from the parsing process 01056 * @return Error code 01057 **/ 01058 01059 error_t pemReadEcPrivateKey(const char_t *input, size_t length, Mpi *key) 01060 { 01061 #if (EC_SUPPORT == ENABLED) 01062 error_t error; 01063 size_t i; 01064 size_t j; 01065 int_t k; 01066 char_t *buffer; 01067 const uint8_t *data; 01068 Asn1Tag tag; 01069 01070 //Check parameters 01071 if(input == NULL && length != 0) 01072 return ERROR_INVALID_PARAMETER; 01073 if(key == NULL) 01074 return ERROR_INVALID_PARAMETER; 01075 01076 //Check the format of the PEM file 01077 if(pemSearchTag(input, length, "-----BEGIN EC PRIVATE KEY-----", 30) >= 0) 01078 { 01079 //Search for the beginning tag 01080 k = pemSearchTag(input, length, "-----BEGIN EC PRIVATE KEY-----", 30); 01081 //Failed to find the specified tag? 01082 if(k < 0) 01083 return ERROR_INVALID_SYNTAX; 01084 01085 //Advance the pointer over the tag 01086 input += k + 30; 01087 length -= k + 30; 01088 01089 //Search for the end tag 01090 k = pemSearchTag(input, length, "-----END EC PRIVATE KEY-----", 28); 01091 //Invalid PEM file? 01092 if(k <= 0) 01093 return ERROR_INVALID_SYNTAX; 01094 01095 //Length of the PEM structure 01096 length = k; 01097 01098 //Allocate a memory buffer to hold the decoded data 01099 buffer = cryptoAllocMem(length); 01100 //Failed to allocate memory? 01101 if(buffer == NULL) 01102 return ERROR_OUT_OF_MEMORY; 01103 01104 //Copy the contents of the PEM structure 01105 memcpy(buffer, input, length); 01106 01107 //Remove carriage returns and line feeds 01108 for(i = 0, j = 0; i < length; i++) 01109 { 01110 if(buffer[i] != '\r' && buffer[i] != '\n') 01111 buffer[j++] = buffer[i]; 01112 } 01113 01114 //Start of exception handling block 01115 do 01116 { 01117 //The PEM file is Base64 encoded... 01118 error = base64Decode(buffer, j, buffer, &length); 01119 //Failed to decode the file? 01120 if(error) 01121 break; 01122 01123 //Point to the resulting ASN.1 structure 01124 data = (uint8_t *) buffer; 01125 01126 //Display ASN.1 structure 01127 error = asn1DumpObject(data, length, 0); 01128 //Any error to report? 01129 if(error) 01130 break; 01131 01132 //The private key is encapsulated within a sequence 01133 error = asn1ReadTag(data, length, &tag); 01134 //Failed to decode ASN.1 tag? 01135 if(error) 01136 break; 01137 01138 //Enforce encoding, class and type 01139 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 01140 //The tag does not match the criteria? 01141 if(error) 01142 break; 01143 01144 //Point to the first field of the sequence 01145 data = tag.value; 01146 length = tag.length; 01147 01148 //Read the Version field 01149 error = asn1ReadTag(data, length, &tag); 01150 //Failed to decode ASN.1 tag? 01151 if(error) 01152 break; 01153 01154 //Enforce encoding, class and type 01155 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 01156 //The tag does not match the criteria? 01157 if(error) 01158 break; 01159 01160 //Skip the Version field 01161 data += tag.totalLength; 01162 length -= tag.totalLength; 01163 01164 //Read the PrivateKey field 01165 error = asn1ReadTag(data, length, &tag); 01166 //Failed to decode ASN.1 tag? 01167 if(error) 01168 break; 01169 01170 //Enforce encoding, class and type 01171 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OCTET_STRING); 01172 //The tag does not match the criteria? 01173 if(error) 01174 break; 01175 01176 //Read the EC private key 01177 error = mpiReadRaw(key, tag.value, tag.length); 01178 //Any error to report? 01179 if(error) 01180 break; 01181 01182 //Debug message 01183 TRACE_DEBUG("EC private key:\r\n"); 01184 TRACE_DEBUG_MPI(" ", key); 01185 01186 //End of exception handling block 01187 } while(0); 01188 } 01189 else 01190 { 01191 //Search for the beginning tag 01192 k = pemSearchTag(input, length, "-----BEGIN PRIVATE KEY-----", 27); 01193 //Failed to find the specified tag? 01194 if(k < 0) 01195 return ERROR_INVALID_SYNTAX; 01196 01197 //Advance the pointer over the tag 01198 input += k + 27; 01199 length -= k + 27; 01200 01201 //Search for the end tag 01202 k = pemSearchTag(input, length, "-----END PRIVATE KEY-----", 25); 01203 //Invalid PEM file? 01204 if(k <= 0) 01205 return ERROR_INVALID_SYNTAX; 01206 01207 //Length of the PEM structure 01208 length = k; 01209 01210 //Allocate a memory buffer to hold the decoded data 01211 buffer = cryptoAllocMem(length); 01212 //Failed to allocate memory? 01213 if(buffer == NULL) 01214 return ERROR_OUT_OF_MEMORY; 01215 01216 //Copy the contents of the PEM structure 01217 memcpy(buffer, input, length); 01218 01219 //Remove carriage returns and line feeds 01220 for(i = 0, j = 0; i < length; i++) 01221 { 01222 if(buffer[i] != '\r' && buffer[i] != '\n') 01223 buffer[j++] = buffer[i]; 01224 } 01225 01226 //Start of exception handling block 01227 do 01228 { 01229 //The PEM file is Base64 encoded... 01230 error = base64Decode(buffer, j, buffer, &length); 01231 //Failed to decode the file? 01232 if(error) 01233 break; 01234 01235 //Point to the resulting ASN.1 structure 01236 data = (uint8_t *) buffer; 01237 01238 //Display ASN.1 structure 01239 error = asn1DumpObject(data, length, 0); 01240 //Any error to report? 01241 if(error) 01242 break; 01243 01244 //The private key is encapsulated within a sequence 01245 error = asn1ReadTag(data, length, &tag); 01246 //Failed to decode ASN.1 tag? 01247 if(error) 01248 break; 01249 01250 //Enforce encoding, class and type 01251 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 01252 //The tag does not match the criteria? 01253 if(error) 01254 break; 01255 01256 //Point to the first field of the sequence 01257 data = tag.value; 01258 length = tag.length; 01259 01260 //Read the Version field 01261 error = asn1ReadTag(data, length, &tag); 01262 //Failed to decode ASN.1 tag? 01263 if(error) 01264 break; 01265 01266 //Enforce encoding, class and type 01267 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 01268 //The tag does not match the criteria? 01269 if(error) 01270 break; 01271 01272 //Skip the Version field 01273 data += tag.totalLength; 01274 length -= tag.totalLength; 01275 01276 //Read the PrivateKeyAlgorithmIdentifier field 01277 error = asn1ReadTag(data, length, &tag); 01278 //Failed to decode ASN.1 tag? 01279 if(error) 01280 break; 01281 01282 //Enforce encoding, class and type 01283 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 01284 //The tag does not match the criteria? 01285 if(error) 01286 break; 01287 01288 //Skip the PrivateKeyAlgorithmIdentifier field 01289 data += tag.totalLength; 01290 length -= tag.totalLength; 01291 01292 //The PrivateKey field is encapsulated within an octet string 01293 error = asn1ReadTag(data, length, &tag); 01294 //Failed to decode ASN.1 tag? 01295 if(error) 01296 break; 01297 01298 //Enforce encoding, class and type 01299 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OCTET_STRING); 01300 //The tag does not match the criteria? 01301 if(error) 01302 break; 01303 01304 //Display ASN.1 structure 01305 error = asn1DumpObject(tag.value, tag.length, 0); 01306 //Any error to report? 01307 if(error) 01308 break; 01309 01310 //Read the contents of the PrivateKey structure 01311 error = asn1ReadTag(tag.value, tag.length, &tag); 01312 //Failed to decode ASN.1 tag? 01313 if(error) 01314 break; 01315 01316 //Enforce encoding, class and type 01317 error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE); 01318 //The tag does not match the criteria? 01319 if(error) 01320 break; 01321 01322 //Point to the first field of the sequence 01323 data = tag.value; 01324 length = tag.length; 01325 01326 //Read the Version field 01327 error = asn1ReadTag(data, length, &tag); 01328 //Failed to decode ASN.1 tag? 01329 if(error) 01330 break; 01331 01332 //Enforce encoding, class and type 01333 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER); 01334 //The tag does not match the criteria? 01335 if(error) 01336 break; 01337 01338 //Skip the Version field 01339 data += tag.totalLength; 01340 length -= tag.totalLength; 01341 01342 //Read the PrivateKey field 01343 error = asn1ReadTag(data, length, &tag); 01344 //Failed to decode ASN.1 tag? 01345 if(error) 01346 break; 01347 01348 //Enforce encoding, class and type 01349 error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OCTET_STRING); 01350 //The tag does not match the criteria? 01351 if(error) 01352 break; 01353 01354 //Read the EC private key 01355 error = mpiReadRaw(key, tag.value, tag.length); 01356 //Any error to report? 01357 if(error) 01358 break; 01359 01360 //Debug message 01361 TRACE_DEBUG("EC private key:\r\n"); 01362 TRACE_DEBUG_MPI(" ", key); 01363 01364 //End of exception handling block 01365 } while(0); 01366 } 01367 01368 //Release previously allocated memory 01369 cryptoFreeMem(buffer); 01370 01371 //Clean up side effects if necessary 01372 if(error) 01373 mpiFree(key); 01374 01375 //Return status code 01376 return error; 01377 #else 01378 //Not implemented 01379 return ERROR_NOT_IMPLEMENTED; 01380 #endif 01381 } 01382 01383 01384 /** 01385 * @brief Decode a PEM file containing a certificate 01386 * @param[in,out] input Pointer to the PEM structure 01387 * @param[in,out] inputLength Length of the PEM structure 01388 * @param[in,out] output Pointer to the DER encoded certificate 01389 * @param[in,out] outputSize Size of the memory block that holds the DER certificate 01390 * @param[out] outputLength Length of the DER encoded certificate 01391 * @return Error code 01392 **/ 01393 01394 error_t pemReadCertificate(const char_t **input, size_t *inputLength, 01395 uint8_t **output, size_t *outputSize, size_t *outputLength) 01396 { 01397 error_t error; 01398 size_t length; 01399 size_t i; 01400 size_t j; 01401 int_t k; 01402 01403 //Check parameters 01404 if(input == NULL || inputLength == NULL) 01405 return ERROR_INVALID_PARAMETER; 01406 if(output == NULL || outputSize == NULL || outputLength == NULL) 01407 return ERROR_INVALID_PARAMETER; 01408 01409 //Search for the beginning tag 01410 k = pemSearchTag(*input, *inputLength, "-----BEGIN CERTIFICATE-----", 27); 01411 //Failed to find the specified tag? 01412 if(k < 0) 01413 return ERROR_END_OF_FILE; 01414 01415 //Advance the input pointer over the tag 01416 *input += k + 27; 01417 *inputLength -= k + 27; 01418 01419 //Search for the end tag 01420 k = pemSearchTag(*input, *inputLength, "-----END CERTIFICATE-----", 25); 01421 //Invalid PEM file? 01422 if(k <= 0) 01423 return ERROR_INVALID_SYNTAX; 01424 01425 //Length of the PEM structure 01426 length = k; 01427 01428 //Increase buffer size? 01429 if(length > *outputSize) 01430 { 01431 //Release previously allocated buffer if necessary 01432 if(*output != NULL) 01433 { 01434 cryptoFreeMem(*output); 01435 *output = NULL; 01436 *outputSize = 0; 01437 } 01438 01439 //Allocate a memory buffer to hold the decoded data 01440 *output = cryptoAllocMem(length); 01441 //Failed to allocate memory? 01442 if(*output == NULL) 01443 return ERROR_OUT_OF_MEMORY; 01444 01445 //Record the size of the buffer 01446 *outputSize = length; 01447 } 01448 01449 //Copy the contents of the PEM structure 01450 memcpy(*output, *input, length); 01451 01452 //Advance the input pointer over the certificate 01453 *input += length + 25; 01454 *inputLength -= length + 25; 01455 01456 //Remove carriage returns and line feeds 01457 for(i = 0, j = 0; i < length; i++) 01458 { 01459 if((*output)[i] != '\r' && (*output)[i] != '\n') 01460 (*output)[j++] = (*output)[i]; 01461 } 01462 01463 //Start of exception handling block 01464 do 01465 { 01466 //The PEM file is Base64 encoded... 01467 error = base64Decode((char_t *) *output, j, *output, &length); 01468 //Failed to decode the file? 01469 if(error) 01470 break; 01471 01472 //Display ASN.1 structure 01473 error = asn1DumpObject(*output, length, 0); 01474 //Any error to report? 01475 if(error) 01476 break; 01477 01478 //End of exception handling block 01479 } while(0); 01480 01481 //Clean up side effects 01482 if(error) 01483 { 01484 //Release previously allocated memory 01485 cryptoFreeMem(*output); 01486 *output = NULL; 01487 *outputSize = 0; 01488 } 01489 01490 //Size of the decoded certificate 01491 *outputLength = length; 01492 //Return status code 01493 return error; 01494 } 01495 01496 01497 /** 01498 * @brief Search a string for a given tag 01499 * @param[in] s String to search 01500 * @param[in] sLen Length of the string to search 01501 * @param[in] tag String containing the tag to search for 01502 * @param[in] tagLen Length of the tag 01503 * @return The index of the first occurrence of the tag in the string, 01504 * or -1 if the tag does not appear in the string 01505 **/ 01506 01507 int_t pemSearchTag(const char_t *s, size_t sLen, const char_t *tag, size_t tagLen) 01508 { 01509 size_t i; 01510 size_t j; 01511 01512 //Loop through input string 01513 for(i = 0; (i + tagLen) <= sLen; i++) 01514 { 01515 //Compare current substring with the given tag 01516 for(j = 0; j < tagLen; j++) 01517 { 01518 if(s[i + j] != tag[j]) 01519 break; 01520 } 01521 01522 //Check whether the tag has been found 01523 if(j == tagLen) 01524 return i; 01525 } 01526 01527 //The tag does not appear in the string 01528 return -1; 01529 } 01530 01531 #endif 01532
Generated on Tue Jul 12 2022 17:10:15 by
