|
|
/*******************************************************************************
* Copyright (c) 1998 Gemplus Development * * Name : COMPCERT.C * * Description : Programme de compression de certificat X.509 * * Author : Christophe Clavier * * Modify : Laurent CASSIER * * Compiler : Microsoft Visual C 5.0 * * Host : IBM PC and compatible machines under Windows 95. * * Release : 1.10.001 * * Last Modif : 04/03/98: V1.10.001 - Change dictionary management and add * CC_Init(), CC_Exit() functions. * 30/01/98: V1.00.005 - Cancel (_OPT_HEADER) the modification in * the length of subjectPKInfo and signature * made in the previous version. * 28/01/98: V1.00.004 - Allows up to 32767 entries in the dictionary * and stores the length of the subjectPKInfo * and signature on one byte instead of two if * it is less than 128. * 13/01/98: V1.00.003 - Modify for meta-compression and dictionary * version ascending compatibility. * 11/12/97: V1.00.002 - Modify for new dictionary format * and compatible with CSP and PKCS. * 27/08/97: V1.00.001 - First implementation. * ******************************************************************************** * * Warning : * * Remark : Flags de compilations : * * - _STUDY : Lorsqu'il est d�fini, des fichiers de log utiles * lors de l'�tude de l'efficacit� des algos * de compression. sont g�n�r�s. * * - _TRICKY_COMPRESSION : Lorsqu'il est d�fini, on ne tente pas * de compresser les champs * 'subjectPublicKey' et 'signature' qui * sont essentiellement al�atoires. * * - _OPT_HEADER : Lorsqu'il est d�fini, et si _TRICKY_COMPRESSION * est d�fini �galement, le header de longueur des * compress�s de subjectPKInfo et de signature * sont optimis�s pour ne tenir sur un seul octet * si la longueur est inf�rieure � 128 au lieu de * deux octets dans tous les cas sinon. * Ne pas d�finir ce flag permet d'�tre compatible * avec les versions inf�rieures � 1.00.005 * * - _GLOBAL_COMPRESSION : Lorsqu'il est d�fini, le compress� du * certificat est lui m�me envoy� � la * fonction CC_RawEncode afin d'y appliquer * le meilleur algo de compression dispo. * * - _OPT_HEADER : Lorsqu'il est d�fini, l * certificat est lui m�me envoy� � la * fonction CC_RawEncode afin d'y appliquer * le meilleur algo de compression dispo. * * - _ALGO_x (x de 1 � 7) : Lorsqu'il est d�fini, l'algo de * compression num�ro x est utilis�. * * Conseils pour la version release de GemPASS : * * - _STUDY : non d�fini * - _TRICKY_COMPRESSION : d�fini * - _OPT_HEADER : non d�fini * - _GLOBAL_COMPRESSION : non d�fini * - _ALGO_1 : d�fini * - _ALGO_2 : d�fini * - _ALGO_x (x>2) : non d�fini * *******************************************************************************/
/*------------------------------------------------------------------------------
Includes files ------------------------------------------------------------------------------*/ #ifdef _WINDOWS
#include <windows.h>
#endif
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "ccdef.h"
#include "ac.h"
#include "compcert.h"
#include "gmem.h"
#include "resource.h"
extern HINSTANCE g_hInstRes;
/*------------------------------------------------------------------------------
Information section ------------------------------------------------------------------------------*/ #define G_NAME "COMPCERT"
#define G_RELEASE "1.10.001"
/*------------------------------------------------------------------------------
Static Variables ------------------------------------------------------------------------------*/ USHORT NbDaysInMonth[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
char* AlgorithmTypeDict[] = { /* x9-57 */ "\x2A\x86\x48\xCE\x38\x02\x01", /*x9.57-holdinstruction-none (1 2 840 10040 2 1) */ "\x2A\x86\x48\xCE\x38\x02\x02", /*x9.57-holdinstruction-callissuer (1 2 840 10040 2 2) */ "\x2A\x86\x48\xCE\x38\x02\x03", /*x9.57-holdinstruction-reject (1 2 840 10040 2 3) */ "\x2A\x86\x48\xCE\x38\x04\x01", /*x9.57-dsa (1 2 840 10040 4 1) */ "\x2A\x86\x48\xCE\x38\x04\x03", /*x9.57-dsaWithSha1 (1 2 840 10040 4 3) */ /* x9-42 */ "\x2A\x86\x48\xCE\x3E\x02\x01", /*x9.42-dhPublicNumber (1 2 840 10046 2 1) */ /* Nortel Secure Networks */ "\x2A\x86\x48\x86\xF6\x7D\x07\x42", /*nsn-alg (1 2 840 113533 7 66) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0A", /*nsn-alg-cast5CBC (1 2 840 113533 7 66 10) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0B", /*nsn-alg-cast5MAC (1 2 840 113533 7 66 11) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0C", /*nsn-alg-pbeWithMD5AndCAST5-CBC (1 2 840 113533 7 66 12) */ /* PKCS #1 */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01", /*pkcs-1 (1 2 840 113549 1 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01", /*pkcs-1-rsaEncryption (1 2 840 113549 1 1 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x02", /*pkcs-1-MD2withRSAEncryption (1 2 840 113549 1 1 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x03", /*pkcs-1-MD4withRSAEncryption (1 2 840 113549 1 1 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x04", /*pkcs-1-MD5withRSAEncryption (1 2 840 113549 1 1 4) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05", /*pkcs-1-SHA1withRSAEncryption (1 2 840 113549 1 1 5) */ /*need to determine which of the following 2 is correct */ /*"\x2A\x86\x48\x86\xF7\x0D\x01\x01\x06", pkcs-1-ripemd160WithRSAEncryption (1 2 840 113549 1 1 6) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x06", /*pkcs-1-rsaOAEPEncryptionSET (1 2 840 113549 1 1 6) */ /* PKCS #3 */ "\x2A\x86\x48\x86\xF7\x0D\x01\x03", /*pkcs-3 (1 2 840 113549 1 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x03\x01", /*pkcs-3-dhKeyAgreement (1 2 840 113549 1 3 1) */ /* PKCS #5 */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05", /*pkcs-5 (1 2 840 113549 1 5) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x01", /*pkcs-5-pbeWithMD2AndDES-CBC (1 2 840 113549 1 5 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x03", /*pkcs-5-pbeWithMD5AndDES-CBC (1 2 840 113549 1 5 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x04", /*pkcs-5-pbeWithMD2AndRC2-CBC (1 2 840 113549 1 5 4) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x06", /*pkcs-5-pbeWithMD5AndRC2-CBC (1 2 840 113549 1 5 6) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x09", /*pkcs-5-pbeWithMD5AndXOR (1 2 840 113549 1 5 9) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x0A", /*pkcs-5-pbeWithSHA1AndDES-CBC (1 2 840 113549 1 5 10) */ /* PKCS #12 */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C", /*pkcs-12 (1 2 840 113549 1 12) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01", /*pkcs-12-modeID (1 2 840 113549 1 12 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x01", /*pkcs-12-OfflineTransportMode (1 2 840 113549 1 12 1 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x02", /*pkcs-12-OnlineTransportMode (1 2 840 113549 1 12 1 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x02", /*pkcs-12-ESPVKID (1 2 840 113549 1 12 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x02\x01", /*pkcs-12-PKCS8KeyShrouding (1 2 840 113549 1 12 2 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03", /*pkcs-12-BagID (1 2 840 113549 1 12 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x01", /*pkcs-12-KeyBagID (1 2 840 113549 1 12 3 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x02", /*pkcs-12-CertAndCRLBagID (1 2 840 113549 1 12 3 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x03", /*pkcs-12-SecretBagID (1 2 840 113549 1 12 3 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04", /*pkcs-12-CertBagID (1 2 840 113549 1 12 4) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04\x01", /*pkcs-12-X509CertCRLBag (1 2 840 113549 1 12 4 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04\x02", /*pkcs-12-SDSICertBag (1 2 840 113549 1 12 4 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05", /*pkcs-12-OID (1 2 840 113549 1 12 5) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01", /*pkcs-12-PBEID (1 2 840 113549 1 12 5 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x01", /*pkcs-12-PBEWithSha1And128BitRC4 (1 2 840 113549 1 12 5 1 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x02", /*pkcs-12-PBEWithSha1And40BitRC4 (1 2 840 113549 1 12 5 1 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x03", /*pkcs-12-PBEWithSha1AndTripleDESCBC (1 2 840 113549 1 12 5 1 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x04", /*pkcs-12-PBEWithSha1And128BitRC2CBC (1 2 840 113549 1 12 5 1 4) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x05", /*pkcs-12-PBEWithSha1And40BitRC2CBC (1 2 840 113549 1 12 5 1 5) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x06", /*pkcs-12-PBEWithSha1AndRC4 (1 2 840 113549 1 12 5 1 6) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x07", /*pkcs-12-PBEWithSha1AndRC2CBC (1 2 840 113549 1 12 5 1 7) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02", /*pkcs-12-EnvelopingID (1 2 840 113549 1 12 5 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x01", /*pkcs-12-RSAEncryptionWith128BitRC4 (1 2 840 113549 1 12 5 2 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x02", /*pkcs-12-RSAEncryptionWith40BitRC4 (1 2 840 113549 1 12 5 2 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x03", /*pkcs-12-RSAEncryptionWithTripleDES (1 2 840 113549 1 12 5 2 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x03", /*pkcs-12-SignatureID (1 2 840 113549 1 12 5 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x03\x01", /*pkcs-12-RSASignatureWithSHA1Digest (1 2 840 113549 1 12 5 3 1) */
/* RSADSI digest algorithms */ "\x2A\x86\x48\x86\xF7\x0D\x02", /*RSADSI-digestAlgorithm (1 2 840 113549 2) */ "\x2A\x86\x48\x86\xF7\x0D\x02\x02", /*RSADSI-md2 (1 2 840 113549 2 2) */ "\x2A\x86\x48\x86\xF7\x0D\x02\x04", /*RSADSI-md4 (1 2 840 113549 2 4) */ "\x2A\x86\x48\x86\xF7\x0D\x02\x05", /*RSADSI-md5 (1 2 840 113549 2 5) */ /* RSADSI encryption algorithms */ "\x2A\x86\x48\x86\xF7\x0D\x03", /*RSADSI-encryptionAlgorithm (1 2 840 113549 3) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x02", /*RSADSI-rc2CBC (1 2 840 113549 3 2) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x03", /*RSADSI-rc2ECB (1 2 840 113549 3 3) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x04", /*RSADSI-rc4 (1 2 840 113549 3 4) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x05", /*RSADSI-rc4WithMAC (1 2 840 113549 3 5) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x06", /*RSADSI-DESX-CBC (1 2 840 113549 3 6) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x07", /*RSADSI-DES-EDE3-CBC (1 2 840 113549 3 7) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x08", /*RSADSI-RC5CBC (1 2 840 113549 3 8) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x09", /*RSADSI-RC5CBCPad (1 2 840 113549 3 9) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x0A", /*RSADSI-CDMFCBCPad (1 2 840 113549 3 10) */ /* cryptlib */ "\x2B\x06\x01\x04\x01\x97\x55\x20\x01", /*cryptlibEnvelope (1 3 6 1 4 1 3029 32 1) */
/* Not sure about these ones: */ /*"\x2B\x0E\x02\x1A\x05", sha (1 3 14 2 26 5) */ /*"\x2B\x0E\x03\x02\x01\x01", rsa (1 3 14 3 2 1 1) */ //X-509
/*"\x2B\x0E\x03\x02\x02\x01", sqmod-N (1 3 14 3 2 2 1) */ //X-509
/*"\x2B\x0E\x03\x02\x03\x01", sqmod-NwithRSA (1 3 14 3 2 3 1) */ //X-509
/* Miscellaneous partially-defunct OIW semi-standards aka algorithms */ "\x2B\x0E\x03\x02\x02", /*ISO-algorithm-md4WitRSA (1 3 14 3 2 2) */ "\x2B\x0E\x03\x02\x03", /*ISO-algorithm-md5WithRSA (1 3 14 3 2 3) */ "\x2B\x0E\x03\x02\x04", /*ISO-algorithm-md4WithRSAEncryption (1 3 14 3 2 4) */ "\x2B\x0E\x03\x02\x06", /*ISO-algorithm-desECB (1 3 14 3 2 6) */ "\x2B\x0E\x03\x02\x07", /*ISO-algorithm-desCBC (1 3 14 3 2 7) */ "\x2B\x0E\x03\x02\x08", /*ISO-algorithm-desOFB (1 3 14 3 2 8) */ "\x2B\x0E\x03\x02\x09", /*ISO-algorithm-desCFB (1 3 14 3 2 9) */ "\x2B\x0E\x03\x02\x0A", /*ISO-algorithm-desMAC (1 3 14 3 2 10) */ "\x2B\x0E\x03\x02\x0B", /*ISO-algorithm-rsaSignature (1 3 14 3 2 11) */ //ISO 9796
"\x2B\x0E\x03\x02\x0C", /*ISO-algorithm-dsa (1 3 14 3 2 12) */ "\x2B\x0E\x03\x02\x0D", /*ISO-algorithm-dsaWithSHA (1 3 14 3 2 13) */ "\x2B\x0E\x03\x02\x0E", /*ISO-algorithm-mdc2WithRSASignature (1 3 14 3 2 14) */ "\x2B\x0E\x03\x02\x0F", /*ISO-algorithm-shaWithRSASignature (1 3 14 3 2 15) */ "\x2B\x0E\x03\x02\x10", /*ISO-algorithm-dhWithCommonModulus (1 3 14 3 2 16) */ "\x2B\x0E\x03\x02\x11", /*ISO-algorithm-desEDE (1 3 14 3 2 17) */ "\x2B\x0E\x03\x02\x12", /*ISO-algorithm-sha (1 3 14 3 2 18) */ "\x2B\x0E\x03\x02\x13", /*ISO-algorithm-mdc-2 (1 3 14 3 2 19) */ "\x2B\x0E\x03\x02\x14", /*ISO-algorithm-dsaCommon (1 3 14 3 2 20) */ "\x2B\x0E\x03\x02\x15", /*ISO-algorithm-dsaCommonWithSHA (1 3 14 3 2 21) */ "\x2B\x0E\x03\x02\x16", /*ISO-algorithm-rsaKeyTransport (1 3 14 3 2 22) */ "\x2B\x0E\x03\x02\x17", /*ISO-algorithm-keyed-hash-seal (1 3 14 3 2 23) */ "\x2B\x0E\x03\x02\x18", /*ISO-algorithm-md2WithRSASignature (1 3 14 3 2 24) */ "\x2B\x0E\x03\x02\x19", /*ISO-algorithm-md5WithRSASignature (1 3 14 3 2 25) */ "\x2B\x0E\x03\x02\x1A", /*ISO-algorithm-sha1 (1 3 14 3 2 26) */ "\x2B\x0E\x03\x02\x1B", /*ISO-algorithm-ripemd160 (1 3 14 3 2 27) */ "\x2B\x0E\x03\x02\x1D", /*ISO-algorithm-sha-1WithRSAEncryption (1 3 14 3 2 29) */ "\x2B\x0E\x03\x03\x01", /*ISO-algorithm-simple-strong-auth-mechanism (1 3 14 3 3 1) */ /* Not sure about these ones:
/*"\x2B\x0E\x07\x02\x01\x01", ElGamal (1 3 14 7 2 1 1) */ /*"\x2B\x0E\x07\x02\x03\x01", md2WithRSA (1 3 14 7 2 3 1) */ /*"\x2B\x0E\x07\x02\x03\x02", md2WithElGamal (1 3 14 7 2 3 2) */ /* X500 algorithms */ "\x55\x08", /*X500-Algorithms (2 5 8) */ "\x55\x08\x01", /*X500-Alg-Encryption (2 5 8 1) */ "\x55\x08\x01\x01", /*rsa (2 5 8 1 1) */ /* DMS-SDN-702 */ "\x60\x86\x48\x01\x65\x02\x01\x01\x01", /*id-sdnsSignatureAlgorithm (2 16 840 1 101 2 1 1 1) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x02", /*id-mosaicSignatureAlgorithm (2 16 840 1 101 2 1 1 2) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x03", /*id-sdnsConfidentialityAlgorithm (2 16 840 1 101 2 1 1 3) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x04", /*id-mosaicConfidentialityAlgorithm (2 16 840 1 101 2 1 1 4) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x05", /*id-sdnsIntegrityAlgorithm (2 16 840 1 101 2 1 1 5) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x06", /*id-mosaicIntegrityAlgorithm (2 16 840 1 101 2 1 1 6) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x07", /*id-sdnsTokenProtectionAlgorithm (2 16 840 1 101 2 1 1 7) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x08", /*id-mosaicTokenProtectionAlgorithm (2 16 840 1 101 2 1 1 8) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x09", /*id-sdnsKeyManagementAlgorithm (2 16 840 1 101 2 1 1 9) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0A", /*id-mosaicKeyManagementAlgorithm (2 16 840 1 101 2 1 1 10) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0B", /*id-sdnsKMandSigAlgorithm (2 16 840 1 101 2 1 1 11) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0C", /*id-mosaicKMandSigAlgorithm (2 16 840 1 101 2 1 1 12) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0D", /*id-SuiteASignatureAlgorithm (2 16 840 1 101 2 1 1 13) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0E", /*id-SuiteAConfidentialityAlgorithm (2 16 840 1 101 2 1 1 14) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0F", /*id-SuiteAIntegrityAlgorithm (2 16 840 1 101 2 1 1 15) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x10", /*id-SuiteATokenProtectionAlgorithm (2 16 840 1 101 2 1 1 16) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x11", /*id-SuiteAKeyManagementAlgorithm (2 16 840 1 101 2 1 1 17) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x12", /*id-SuiteAKMandSigAlgorithm (2 16 840 1 101 2 1 1 18) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x13", /*id-mosaicUpdatedSigAlgorithm (2 16 840 1 101 2 1 1 19) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x14", /*id-mosaicKMandUpdSigAlgorithms (2 16 840 1 101 2 1 1 20) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x15", /*id-mosaicUpdatedIntegAlgorithm (2 16 840 1 101 2 1 1 21) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x16", /*id-mosaicKeyEncryptionAlgorithm (2 16 840 1 101 2 1 1 22) */ NULL };
char* AttributeTypeDict[] = { /* x9-57 */ "\x2A\x86\x48\xCE\x38\x02\x01", /*x9.57-holdinstruction-none (1 2 840 10040 2 1) */ "\x2A\x86\x48\xCE\x38\x02\x02", /*x9.57-holdinstruction-callissuer (1 2 840 10040 2 2) */ "\x2A\x86\x48\xCE\x38\x02\x03", /*x9.57-holdinstruction-reject (1 2 840 10040 2 3) */ "\x2A\x86\x48\xCE\x38\x04\x01", /*x9.57-dsa (1 2 840 10040 4 1) */ "\x2A\x86\x48\xCE\x38\x04\x03", /*x9.57-dsaWithSha1 (1 2 840 10040 4 3) */ /* x9-42 */ "\x2A\x86\x48\xCE\x3E\x02\x01", /*x9.42-dhPublicNumber (1 2 840 10046 2 1) */ /* Nortel Secure Networks */ "\x2A\x86\x48\x86\xF6\x7D\x07", /*nsn (1 2 840 113533 7) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x41\x00", /*nsn-ce-entrustVersInfo (1 2 840 113533 7 65 0) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x41", /*nsn-ce (1 2 840 113533 7 65) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x42", /*nsn-alg (1 2 840 113533 7 66) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0A", /*nsn-alg-cast5CBC (1 2 840 113533 7 66 10) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0B", /*nsn-alg-cast5MAC (1 2 840 113533 7 66 11) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0C", /*nsn-alg-pbeWithMD5AndCAST5-CBC (1 2 840 113533 7 66 12) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x43", /*nsn-oc (1 2 840 113533 7 67) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x43\x0C", /*nsn-oc-entrustUser (1 2 840 113533 7 67 0) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x44\x00", /*nsn-at-entrustCAInfo (1 2 840 113533 7 68 0) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x44\x0A", /*nsn-at-attributeCertificate (1 2 840 113533 7 68 10) */ "\x2A\x86\x48\x86\xF6\x7D\x07\x44", /*nsn-at (1 2 840 113533 7 68) */ /* PKCS #1 */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01", /*pkcs-1 (1 2 840 113549 1 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01", /*pkcs-1-rsaEncryption (1 2 840 113549 1 1 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x02", /*pkcs-1-MD2withRSAEncryption (1 2 840 113549 1 1 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x03", /*pkcs-1-MD4withRSAEncryption (1 2 840 113549 1 1 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x04", /*pkcs-1-MD5withRSAEncryption (1 2 840 113549 1 1 4) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05", /*pkcs-1-SHA1withRSAEncryption (1 2 840 113549 1 1 5) */ /*need to determine which of the following 2 is correct */ /*"\x2A\x86\x48\x86\xF7\x0D\x01\x01\x06", pkcs-1-ripemd160WithRSAEncryption (1 2 840 113549 1 1 6) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x06", /*pkcs-1-rsaOAEPEncryptionSET (1 2 840 113549 1 1 6) */ /* PKCS #3 */ "\x2A\x86\x48\x86\xF7\x0D\x01\x03", /*pkcs-3 (1 2 840 113549 1 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x03\x01", /*pkcs-3-dhKeyAgreement (1 2 840 113549 1 3 1) */ /* PKCS #5 */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05", /*pkcs-5 (1 2 840 113549 1 5) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x01", /*pkcs-5-pbeWithMD2AndDES-CBC (1 2 840 113549 1 5 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x03", /*pkcs-5-pbeWithMD5AndDES-CBC (1 2 840 113549 1 5 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x04", /*pkcs-5-pbeWithMD2AndRC2-CBC (1 2 840 113549 1 5 4) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x06", /*pkcs-5-pbeWithMD5AndRC2-CBC (1 2 840 113549 1 5 6) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x09", /*pkcs-5-pbeWithMD5AndXOR (1 2 840 113549 1 5 9) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x05\x0A", /*pkcs-5-pbeWithSHA1AndDES-CBC (1 2 840 113549 1 5 10) */ /* PKCS #7 */ "\x2A\x86\x48\x86\xF7\x0D\x01\x07", /*pkcs-7 (1 2 840 113549 1 7) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x01", /*pkcs-7-data (1 2 840 113549 1 7 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02", /*pkcs-7-signedData (1 2 840 113549 1 7 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x03", /*pkcs-7-envelopedData (1 2 840 113549 1 7 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x04", /*pkcs-7-signedAndEnvelopedData (1 2 840 113549 1 7 4) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x05", /*pkcs-7-digestData (1 2 840 113549 1 7 5) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x06", /*pkcs-7-encryptedData (1 2 840 113549 1 7 6) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x07", /*pkcs-7-dataWithAttributes (1 2 840 113549 1 7 7) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x08", /*pkcs-7-encryptedPrivateKeyInfo (1 2 840 113549 1 7 8) */ /* PKCS #9 */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09", /*pkcs-9 (1 2 840 113549 1 9) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01", /*pkcs-9-emailAddress (1 2 840 113549 1 9 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x02", /*pkcs-9-unstructuredName (1 2 840 113549 1 9 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03", /*pkcs-9-contentType (1 2 840 113549 1 9 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04", /*pkcs-9-messageDigest (1 2 840 113549 1 9 4) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x05", /*pkcs-9-signingTime (1 2 840 113549 1 9 5) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x06", /*pkcs-9-countersignature (1 2 840 113549 1 9 6) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x07", /*pkcs-9-challengePassword (1 2 840 113549 1 9 7) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x08", /*pkcs-9-unstructuredAddress (1 2 840 113549 1 9 8) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x09", /*pkcs-9-extendedCertificateAttributes (1 2 840 113549 1 9 9) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0A", /*pkcs-9-issuerAndSerialNumber (1 2 840 113549 1 9 10) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0B", /*pkcs-9-passwordCheck (1 2 840 113549 1 9 11) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0C", /*pkcs-9-publicKey (1 2 840 113549 1 9 12) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0D", /*pkcs-9-signingDescription (1 2 840 113549 1 9 13) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0E", /*pkcs-9-X.509 extension (1 2 840 113549 1 9 14) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0F", /*pkcs-9-SMIMECapabilities (1 2 840 113549 1 9 15) */ /* PKCS #12 */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C", /*pkcs-12 (1 2 840 113549 1 12) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01", /*pkcs-12-modeID (1 2 840 113549 1 12 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x01", /*pkcs-12-OfflineTransportMode (1 2 840 113549 1 12 1 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x02", /*pkcs-12-OnlineTransportMode (1 2 840 113549 1 12 1 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x02", /*pkcs-12-ESPVKID (1 2 840 113549 1 12 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x02\x01", /*pkcs-12-PKCS8KeyShrouding (1 2 840 113549 1 12 2 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03", /*pkcs-12-BagID (1 2 840 113549 1 12 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x01", /*pkcs-12-KeyBagID (1 2 840 113549 1 12 3 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x02", /*pkcs-12-CertAndCRLBagID (1 2 840 113549 1 12 3 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x03\x03", /*pkcs-12-SecretBagID (1 2 840 113549 1 12 3 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04", /*pkcs-12-CertBagID (1 2 840 113549 1 12 4) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04\x01", /*pkcs-12-X509CertCRLBag (1 2 840 113549 1 12 4 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x04\x02", /*pkcs-12-SDSICertBag (1 2 840 113549 1 12 4 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05", /*pkcs-12-OID (1 2 840 113549 1 12 5) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01", /*pkcs-12-PBEID (1 2 840 113549 1 12 5 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x01", /*pkcs-12-PBEWithSha1And128BitRC4 (1 2 840 113549 1 12 5 1 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x02", /*pkcs-12-PBEWithSha1And40BitRC4 (1 2 840 113549 1 12 5 1 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x03", /*pkcs-12-PBEWithSha1AndTripleDESCBC (1 2 840 113549 1 12 5 1 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x04", /*pkcs-12-PBEWithSha1And128BitRC2CBC (1 2 840 113549 1 12 5 1 4) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x05", /*pkcs-12-PBEWithSha1And40BitRC2CBC (1 2 840 113549 1 12 5 1 5) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x06", /*pkcs-12-PBEWithSha1AndRC4 (1 2 840 113549 1 12 5 1 6) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x01\x07", /*pkcs-12-PBEWithSha1AndRC2CBC (1 2 840 113549 1 12 5 1 7) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02", /*pkcs-12-EnvelopingID (1 2 840 113549 1 12 5 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x01", /*pkcs-12-RSAEncryptionWith128BitRC4 (1 2 840 113549 1 12 5 2 1) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x02", /*pkcs-12-RSAEncryptionWith40BitRC4 (1 2 840 113549 1 12 5 2 2) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x02\x03", /*pkcs-12-RSAEncryptionWithTripleDES (1 2 840 113549 1 12 5 2 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x03", /*pkcs-12-SignatureID (1 2 840 113549 1 12 5 3) */ "\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x05\x03\x01", /*pkcs-12-RSASignatureWithSHA1Digest (1 2 840 113549 1 12 5 3 1) */
/* RSADSI digest algorithms */ "\x2A\x86\x48\x86\xF7\x0D\x02", /*RSADSI-digestAlgorithm (1 2 840 113549 2) */ "\x2A\x86\x48\x86\xF7\x0D\x02\x02", /*RSADSI-md2 (1 2 840 113549 2 2) */ "\x2A\x86\x48\x86\xF7\x0D\x02\x04", /*RSADSI-md4 (1 2 840 113549 2 4) */ "\x2A\x86\x48\x86\xF7\x0D\x02\x05", /*RSADSI-md5 (1 2 840 113549 2 5) */ /* RSADSI encryption algorithms */ "\x2A\x86\x48\x86\xF7\x0D\x03", /*RSADSI-encryptionAlgorithm (1 2 840 113549 3) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x02", /*RSADSI-rc2CBC (1 2 840 113549 3 2) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x03", /*RSADSI-rc2ECB (1 2 840 113549 3 3) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x04", /*RSADSI-rc4 (1 2 840 113549 3 4) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x05", /*RSADSI-rc4WithMAC (1 2 840 113549 3 5) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x06", /*RSADSI-DESX-CBC (1 2 840 113549 3 6) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x07", /*RSADSI-DES-EDE3-CBC (1 2 840 113549 3 7) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x08", /*RSADSI-RC5CBC (1 2 840 113549 3 8) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x09", /*RSADSI-RC5CBCPad (1 2 840 113549 3 9) */ "\x2A\x86\x48\x86\xF7\x0D\x03\x0A", /*RSADSI-CDMFCBCPad (1 2 840 113549 3 10) */ /* Microsoft OIDs */ "\x2A\x86\x48\x86\xF7\x14\x04\x03", /*microsoftExcel (1 2 840 113556 4 3) */ "\x2A\x86\x48\x86\xF7\x14\x04\x04", /*titledWithOID (1 2 840 113556 4 4) */ "\x2A\x86\x48\x86\xF7\x14\x04\x05", /*microsoftPowerPoint (1 2 840 113556 4 5) */
/* cryptlib */ "\x2B\x06\x01\x04\x01\x97\x55\x20\x01", /*cryptlibEnvelope (1 3 6 1 4 1 3029 32 1) */
/* PKIX */ "\x2B\x06\x01\x05\x05\x07", /*pkix-oid (1 3 6 1 5 5 7) */ "\x2B\x06\x01\x05\x05\x07\x01", /*pkix-subjectInfoAccess (1 3 6 1 5 5 7 1) */ "\x2B\x06\x01\x05\x05\x07\x02", /*pkix-authorityInfoAccess (1 3 6 1 5 5 7 2) */ "\x2B\x06\x01\x05\x05\x07\x04", /*pkix-cps (1 3 6 1 5 5 7 4) */ "\x2B\x06\x01\x05\x05\x07\x05", /*pkix-userNotice (1 3 6 1 5 5 7 5) */
/* Not sure about these ones: */ /*"\x2B\x0E\x02\x1A\x05", sha (1 3 14 2 26 5) */ /*"\x2B\x0E\x03\x02\x01\x01", rsa (1 3 14 3 2 1 1) */ //X-509
/*"\x2B\x0E\x03\x02\x02\x01", sqmod-N (1 3 14 3 2 2 1) */ //X-509
/*"\x2B\x0E\x03\x02\x03\x01", sqmod-NwithRSA (1 3 14 3 2 3 1) */ //X-509
/* Miscellaneous partially-defunct OIW semi-standards aka algorithms */ "\x2B\x0E\x03\x02\x02", /*ISO-algorithm-md4WitRSA (1 3 14 3 2 2) */ "\x2B\x0E\x03\x02\x03", /*ISO-algorithm-md5WithRSA (1 3 14 3 2 3) */ "\x2B\x0E\x03\x02\x04", /*ISO-algorithm-md4WithRSAEncryption (1 3 14 3 2 4) */ "\x2B\x0E\x03\x02\x06", /*ISO-algorithm-desECB (1 3 14 3 2 6) */ "\x2B\x0E\x03\x02\x07", /*ISO-algorithm-desCBC (1 3 14 3 2 7) */ "\x2B\x0E\x03\x02\x08", /*ISO-algorithm-desOFB (1 3 14 3 2 8) */ "\x2B\x0E\x03\x02\x09", /*ISO-algorithm-desCFB (1 3 14 3 2 9) */ "\x2B\x0E\x03\x02\x0A", /*ISO-algorithm-desMAC (1 3 14 3 2 10) */ "\x2B\x0E\x03\x02\x0B", /*ISO-algorithm-rsaSignature (1 3 14 3 2 11) */ //ISO 9796
"\x2B\x0E\x03\x02\x0C", /*ISO-algorithm-dsa (1 3 14 3 2 12) */ "\x2B\x0E\x03\x02\x0D", /*ISO-algorithm-dsaWithSHA (1 3 14 3 2 13) */ "\x2B\x0E\x03\x02\x0E", /*ISO-algorithm-mdc2WithRSASignature (1 3 14 3 2 14) */ "\x2B\x0E\x03\x02\x0F", /*ISO-algorithm-shaWithRSASignature (1 3 14 3 2 15) */ "\x2B\x0E\x03\x02\x10", /*ISO-algorithm-dhWithCommonModulus (1 3 14 3 2 16) */ "\x2B\x0E\x03\x02\x11", /*ISO-algorithm-desEDE (1 3 14 3 2 17) */ "\x2B\x0E\x03\x02\x12", /*ISO-algorithm-sha (1 3 14 3 2 18) */ "\x2B\x0E\x03\x02\x13", /*ISO-algorithm-mdc-2 (1 3 14 3 2 19) */ "\x2B\x0E\x03\x02\x14", /*ISO-algorithm-dsaCommon (1 3 14 3 2 20) */ "\x2B\x0E\x03\x02\x15", /*ISO-algorithm-dsaCommonWithSHA (1 3 14 3 2 21) */ "\x2B\x0E\x03\x02\x16", /*ISO-algorithm-rsaKeyTransport (1 3 14 3 2 22) */ "\x2B\x0E\x03\x02\x17", /*ISO-algorithm-keyed-hash-seal (1 3 14 3 2 23) */ "\x2B\x0E\x03\x02\x18", /*ISO-algorithm-md2WithRSASignature (1 3 14 3 2 24) */ "\x2B\x0E\x03\x02\x19", /*ISO-algorithm-md5WithRSASignature (1 3 14 3 2 25) */ "\x2B\x0E\x03\x02\x1A", /*ISO-algorithm-sha1 (1 3 14 3 2 26) */ "\x2B\x0E\x03\x02\x1B", /*ISO-algorithm-ripemd160 (1 3 14 3 2 27) */ "\x2B\x0E\x03\x02\x1D", /*ISO-algorithm-sha-1WithRSAEncryption (1 3 14 3 2 29) */ "\x2B\x0E\x03\x03\x01", /*ISO-algorithm-simple-strong-auth-mechanism (1 3 14 3 3 1) */ /* Not sure about these ones:
/*"\x2B\x0E\x07\x02\x01\x01", ElGamal (1 3 14 7 2 1 1) */ /*"\x2B\x0E\x07\x02\x03\x01", md2WithRSA (1 3 14 7 2 3 1) */ /*"\x2B\x0E\x07\x02\x03\x02", md2WithElGamal (1 3 14 7 2 3 2) */ /* X.520 id-at = 2 5 4*/ "\x55\x04\x00", /*X.520-at-objectClass (2 5 4 0) */ "\x55\x04\x01", /*X.520-at-aliasObjectName (2 5 4 1) */ "\x55\x04\x02", /*X.520-at-knowledgeInformation (2 5 4 2) */ "\x55\x04\x03", /*X.520-at-commonName (2 5 4 3) */ "\x55\x04\x04", /*X.520-at-surname (2 5 4 4) */ "\x55\x04\x05", /*X.520-at-serialNumber (2 5 4 5) */ "\x55\x04\x06", /*X.520-at-countryName (2 5 4 6) */ "\x55\x04\x07", /*X.520-at-localityName (2 5 4 7) */ "\x55\x04\x08", /*X.520-at-stateOrProvinceName (2 5 4 8) */ "\x55\x04\x09", /*X.520-at-streetAddress (2 5 4 9) */ "\x55\x04\x0A", /*X.520-at-organizationName (2 5 4 10) */ "\x55\x04\x0B", /*X.520-at-organizationalUnitName (2 5 4 11) */ "\x55\x04\x0C", /*X.520-at-title (2 5 4 12) */ "\x55\x04\x0D", /*X.520-at-description (2 5 4 13) */ "\x55\x04\x0E", /*X.520-at-searchGuide (2 5 4 14) */ "\x55\x04\x0F", /*X.520-at-businessCategory (2 5 4 15) */ "\x55\x04\x10", /*X.520-at-postalAddress (2 5 4 16) */ "\x55\x04\x11", /*X.520-at-postalCode (2 5 4 17) */ "\x55\x04\x12", /*X.520-at-postOfficeBox (2 5 4 18) */ "\x55\x04\x13", /*X.520-at-physicalDeliveryOfficeName (2 5 4 19) */ "\x55\x04\x14", /*X.520-at-telephoneNumber (2 5 4 20) */ "\x55\x04\x15", /*X.520-at-telexNumber (2 5 4 21) */ "\x55\x04\x16", /*X.520-at-teletexTerminalIdentifier (2 5 4 22) */ "\x55\x04\x17", /*X.520-at-facsimileTelephoneNumber (2 5 4 23) */ "\x55\x04\x18", /*X.520-at-x121AddreX.520-at-ss (2 5 4 24) */ "\x55\x04\x19", /*X.520-at-internationalISNNumber (2 5 4 25) */ "\x55\x04\x1A", /*X.520-at-registeredAddress (2 5 4 26) */ "\x55\x04\x1B", /*X.520-at-destinationIndicator (2 5 4 27) */ "\x55\x04\x1C", /*X.520-at-preferredDeliveryMehtod (2 5 4 28) */ "\x55\x04\x1D", /*X.520-at-presentationAddress (2 5 4 29) */ "\x55\x04\x1E", /*X.520-at-supportedApplicationContext (2 5 4 30) */ "\x55\x04\x1F", /*X.520-at-member (2 5 4 31) */ "\x55\x04\x20", /*X.520-at-owner (2 5 4 32) */ "\x55\x04\x21", /*X.520-at-roleOccupant (2 5 4 33) */ "\x55\x04\x22", /*X.520-at-seeAlso (2 5 4 34) */ "\x55\x04\x23", /*X.520-at-userPassword (2 5 4 35) */ "\x55\x04\x24", /*X.520-at-userCertificate (2 5 4 36) */ "\x55\x04\x25", /*X.520-at-CAcertificate (2 5 4 37) */ "\x55\x04\x26", /*X.520-at-authorityRevocationList (2 5 4 38) */ "\x55\x04\x27", /*X.520-at-certifcateRevocationList (2 5 4 39) */ "\x55\x04\x28", /*X.520-at-crossCertificatePair (2 5 4 40) */ "\x55\x04\x34", /*X.520-at-supportedAlgorithms (2 5 4 52) */ "\x55\x04\x35", /*X.520-at-deltaRevocationList (2 5 4 53) */ "\x55\x04\x3A", /*X.520-at-crossCertificatePair (2 5 4 58) */ /* X500 algorithms */ "\x55\x08", /*X500-Algorithms (2 5 8) */ "\x55\x08\x01", /*X500-Alg-Encryption (2 5 8 1) */ "\x55\x08\x01\x01", /*rsa (2 5 8 1 1) */ /* X.509 id-ce = 2 5 29*/ "\x55\x1D\x01", /*X.509-ce-authorityKeyIdentifier (2 5 29 1) */ "\x55\x1D\x02", /*X.509-ce-keyAttributes (2 5 29 2) */ "\x55\x1D\x03", /*X.509-ce-certificatePolicies (2 5 29 3) */ "\x55\x1D\x04", /*X.509-ce-keyUsageRestriction (2 5 29 4) */ "\x55\x1D\x05", /*X.509-ce-policyMapping (2 5 29 5) */ "\x55\x1D\x06", /*X.509-ce-subtreesConstraint (2 5 29 6) */ "\x55\x1D\x07", /*X.509-ce-subjectAltName (2 5 29 7) */ "\x55\x1D\x08", /*X.509-ce-issuerAltName (2 5 29 8) */ "\x55\x1D\x09", /*X.509-ce-subjectDirectoryAttributes (2 5 29 9) */ "\x55\x1D\x0A", /*X.509-ce-basicConstraints x.509 (2 5 29 10) */ "\x55\x1D\x0B", /*X.509-ce-nameConstraints (2 5 29 11) */ "\x55\x1D\x0C", /*X.509-ce-policyConstraints (2 5 29 12) */ "\x55\x1D\x0D", /*X.509-ce-basicConstraints 9.55 (2 5 29 13) */ "\x55\x1D\x0E", /*X.509-ce-subjectKeyIdentifier (2 5 29 14) */ "\x55\x1D\x0F", /*X.509-ce-keyUsage (2 5 29 15) */ "\x55\x1D\x10", /*X.509-ce-privateKeyUsagePeriod (2 5 29 16) */ "\x55\x1D\x11", /*X.509-ce-subjectAltName (2 5 29 17) */ "\x55\x1D\x12", /*X.509-ce-issuerAltName (2 5 29 18) */ "\x55\x1D\x13", /*X.509-ce-basicConstraints (2 5 29 19) */ "\x55\x1D\x14", /*X.509-ce-cRLNumber (2 5 29 20) */ "\x55\x1D\x15", /*X.509-ce-reasonCode (2 5 29 21) */ "\x55\x1D\x17", /*X.509-ce-instructionCode (2 5 29 23) */ "\x55\x1D\x18", /*X.509-ce-invalidityDate (2 5 29 24) */ "\x55\x1D\x1B", /*X.509-ce-deltaCRLIndicator (2 5 29 27) */ "\x55\x1D\x1C", /*X.509-ce-issuingDistributionPoint (2 5 29 28) */ "\x55\x1D\x1D", /*X.509-ce-certificateIssuer (2 5 29 29) */ "\x55\x1D\x1E", /*X.509-ce-nameConstraints (2 5 29 30) */ "\x55\x1D\x1F", /*X.509-ce-cRLDistPoints (2 5 29 31) */ "\x55\x1D\x20", /*X.509-ce-certificatePolicies (2 5 29 32) */ "\x55\x1D\x21", /*X.509-ce-policyMappings (2 5 29 33) */ "\x55\x1D\x23", /*X.509-ce-authorityKeyIdentifier (2 5 29 35) */ "\x55\x1D\x24", /*X.509-ce-policyConstraints (2 5 29 36) */ /* DMS-SDN-702 */ "\x60\x86\x48\x01\x65\x02\x01\x01\x01", /*id-sdnsSignatureAlgorithm (2 16 840 1 101 2 1 1 1) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x02", /*id-mosaicSignatureAlgorithm (2 16 840 1 101 2 1 1 2) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x03", /*id-sdnsConfidentialityAlgorithm (2 16 840 1 101 2 1 1 3) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x04", /*id-mosaicConfidentialityAlgorithm (2 16 840 1 101 2 1 1 4) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x05", /*id-sdnsIntegrityAlgorithm (2 16 840 1 101 2 1 1 5) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x06", /*id-mosaicIntegrityAlgorithm (2 16 840 1 101 2 1 1 6) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x07", /*id-sdnsTokenProtectionAlgorithm (2 16 840 1 101 2 1 1 7) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x08", /*id-mosaicTokenProtectionAlgorithm (2 16 840 1 101 2 1 1 8) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x09", /*id-sdnsKeyManagementAlgorithm (2 16 840 1 101 2 1 1 9) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0A", /*id-mosaicKeyManagementAlgorithm (2 16 840 1 101 2 1 1 10) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0B", /*id-sdnsKMandSigAlgorithm (2 16 840 1 101 2 1 1 11) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0C", /*id-mosaicKMandSigAlgorithm (2 16 840 1 101 2 1 1 12) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0D", /*id-SuiteASignatureAlgorithm (2 16 840 1 101 2 1 1 13) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0E", /*id-SuiteAConfidentialityAlgorithm (2 16 840 1 101 2 1 1 14) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x0F", /*id-SuiteAIntegrityAlgorithm (2 16 840 1 101 2 1 1 15) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x10", /*id-SuiteATokenProtectionAlgorithm (2 16 840 1 101 2 1 1 16) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x11", /*id-SuiteAKeyManagementAlgorithm (2 16 840 1 101 2 1 1 17) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x12", /*id-SuiteAKMandSigAlgorithm (2 16 840 1 101 2 1 1 18) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x13", /*id-mosaicUpdatedSigAlgorithm (2 16 840 1 101 2 1 1 19) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x14", /*id-mosaicKMandUpdSigAlgorithms (2 16 840 1 101 2 1 1 20) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x15", /*id-mosaicUpdatedIntegAlgorithm (2 16 840 1 101 2 1 1 21) */ "\x60\x86\x48\x01\x65\x02\x01\x01\x16", /*id-mosaicKeyEncryptionAlgorithm (2 16 840 1 101 2 1 1 22) */
/* Netscape */ "\x60\x86\x48\x01\x86\xF8\x42\x01\x01", /*netscape-cert-type (2 16 840 1 113730 1 1) */ "\x60\x86\x48\x01\x86\xF8\x42\x01\x02", /*netscape-base-url (2 16 840 1 113730 1 2) */ "\x60\x86\x48\x01\x86\xF8\x42\x01\x03", /*netscape-revocation-url (2 16 840 1 113730 1 3) */ "\x60\x86\x48\x01\x86\xF8\x42\x01\x04", /*netscape-ca-revocation-url (2 16 840 1 113730 1 4) */ "\x60\x86\x48\x01\x86\xF8\x42\x02\x05", /*netscape-cert-sequence (2 16 840 1 113730 2 5) */ "\x60\x86\x48\x01\x86\xF8\x42\x02\x06", /*netscape-cert-url (2 16 840 1 113730 2 6) */ "\x60\x86\x48\x01\x86\xF8\x42\x01\x07", /*netscape-renewal-url (2 16 840 1 113730 1 7) */ "\x60\x86\x48\x01\x86\xF8\x42\x01\x08", /*netscape-ca-policy-url (2 16 840 1 113730 1 8) */ "\x60\x86\x48\x01\x86\xF8\x42\x01\x09", /*netscape-HomePage-url (2 16 840 1 113730 1 9) */ "\x60\x86\x48\x01\x86\xF8\x42\x01\x0A", /*netscape-EntityLogo (2 16 840 1 113730 1 10) */ "\x60\x86\x48\x01\x86\xF8\x42\x01\x0B", /*netscape-UserPicture (2 16 840 1 113730 1 11) */ "\x60\x86\x48\x01\x86\xF8\x42\x01\x0C", /*netscape-ssl-server-name (2 16 840 1 113730 1 12) */ "\x60\x86\x48\x01\x86\xF8\x42\x01\x0D", /*netscape-comment (2 16 840 1 113730 1 13) */ "\x60\x86\x48\x01\x86\xF8\x42\x02", /*netscape-data-type (2 16 840 1 113730 2) */ "\x60\x86\x48\x01\x86\xF8\x42\x02\x01", /*netscape-dt-GIF (2 16 840 1 113730 2 1) */ "\x60\x86\x48\x01\x86\xF8\x42\x02\x02", /*netscape-dt-JPEG (2 16 840 1 113730 2 2) */ "\x60\x86\x48\x01\x86\xF8\x42\x02\x03", /*netscape-dt-URL (2 16 840 1 113730 2 3) */ "\x60\x86\x48\x01\x86\xF8\x42\x02\x04", /*netscape-dt-HTML (2 16 840 1 113730 2 4) */ "\x60\x86\x48\x01\x86\xF8\x42\x02\x05", /*netscape-dt-CertSeq (2 16 840 1 113730 2 5) */ "\x60\x86\x48\x01\x86\xF8\x42\x03", /*netscape-directory (2 16 840 1 113730 3) */ /* SET */ "\x86\x8D\x6F\x02", /*hashedRootKey (2 54 1775 2) */ "\x86\x8D\x6F\x03", /*certificateType (2 54 1775 3) */ "\x86\x8D\x6F\x04", /*merchantData (2 54 1775 4) */ "\x86\x8D\x6F\x05", /*cardCertRequired (2 54 1775 5) */ "\x86\x8D\x6F\x06", /*tunneling (2 54 1775 6) */ "\x86\x8D\x6F\x07", /*setQualifier (2 54 1775 7) */ "\x86\x8D\x6F\x63", /*set-data (2 54 1775 99) */ NULL }; /*------------------------------------------------------------------------------
Global Variables ------------------------------------------------------------------------------*/
BYTE *pDictMemory = NULL_PTR, DictVersion = 0;
BYTE* dwPtrMax = 0;
USHORT usDictCount = 0;
#ifdef _STUDY
FILE *pfdLog, *pfdLogFreq, *pfdBinAc256, *pfdBinAc16, *pfdBinAc4, *pfdBinAc2; int sum, i, Ac256[256], Ac16[16], Ac4[4], Ac2[2]; #endif
/*------------------------------------------------------------------------------
Static Functions Declaration ------------------------------------------------------------------------------*/
static int CC_Comp(BLOC *pCertificate, BLOC *pCompressedCertificate );
static int CC_Uncomp(BLOC *pCompressedCertificate, BLOC *pUncompressedCertificate );
static int CC_ExtractContent(ASN1 *pAsn1 );
static int CC_BuildAsn1(ASN1 *pAsn1 );
static int SearchDataByIndex(USHORT usIndex, BYTE *pDict, BLOC *pOutBloc );
static int CC_RawEncode(BLOC *pInBloc, BLOC *pOutBloc, BOOL bUseDictionnary );
static int CC_RawDecode(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength, BOOL bUseDictionnary );
static int CC_GenericCompress(BLOC *pUncompBloc, BLOC *pCompBloc, BYTE AlgoID );
static int CC_GenericUncompress(BLOC *pCompBloc, BLOC *pUncompBloc, BYTE AlgoID );
static int CC_Encode_TBSCertificate(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Encode_CertificateSerialNumber(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Encode_AlgorithmIdentifier(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Encode_Name(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Encode_RDN(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Encode_AVA(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Encode_Validity(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Encode_UTCTime(BLOC *pInBloc, BLOC *pOutBloc, BYTE *pFormat );
static int CC_Encode_SubjectPKInfo(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Encode_UniqueIdentifier(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Encode_Extensions(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Encode_Extension(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Encode_Signature(BLOC *pInBloc, BLOC *pOutBloc );
static int CC_Decode_TBSCertificate(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_CertificateSerialNumber(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_AlgorithmIdentifier(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_Name(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_RDN(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_AVA(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_Validity(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_UTCTime(BYTE *pInData, BYTE Format, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_SubjectPKInfo(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_UniqueIdentifier(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_Extensions(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_Extension(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
static int CC_Decode_Signature(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength );
/*------------------------------------------------------------------------------
* static DWORD get_file_len(BYTE *lpszFileName) * * Description : Get length of file. * * Remarks : Nothing. * * In : lpszFileName = Name of file. * * Out : Nothing. * * Responses : size of file, -1 if error occur. * ------------------------------------------------------------------------------*/ static DWORD get_file_len(BYTE *lpszFileName) { int fp; DWORD nLen;
fp = _open(lpszFileName, O_RDONLY); if (fp != 0) { nLen = _filelength(fp); _close(fp); } else { nLen = -1; }
return(nLen); }
/*******************************************************************************
* int CC_Init(BYTE bDictMode, BYTE *pszDictName) * * Description : Lit le dictionnaire et son num�ro de version depuis la base de * registre vers la m�moire. * * Remarks : * * In : * * Out : * * Responses : * *******************************************************************************/ int CC_Init(BYTE bDictMode, BYTE *pszDictName) { switch (bDictMode) { #ifndef _STATIC
/* Dictionary read as resource data GPK_X509_DICTIONARY */ case DICT_STANDARD: { LPBYTE pbDict; DWORD cbDict; HRSRC hRsrc; HGLOBAL hDict;
hRsrc = FindResource(g_hInstRes, //MAKEINTRESOURCE(GPK_X509_DICTIONARY),
TEXT("GPK_X509_DICTIONARY"), RT_RCDATA ); if (NULL == hRsrc) { goto ERROR_INIT; } cbDict = SizeofResource(g_hInstRes, hRsrc); if (0 == cbDict) { goto ERROR_INIT; } hDict = LoadResource(g_hInstRes, hRsrc); if (NULL == hDict) { goto ERROR_INIT; } pbDict = LockResource(hDict); if (NULL == pbDict) { goto ERROR_INIT; }
DictVersion = *pbDict; usDictCount = (WORD)cbDict - 1; pDictMemory = GMEM_Alloc(usDictCount); if (pDictMemory == NULL) { goto ERROR_INIT; } memcpy(pDictMemory, &pbDict[1], usDictCount); return(RV_SUCCESS); } break; #endif
/* Dictionary read as registyry entry in HKEY_LOCAL_MACHINE with key as */ /* pszDictName parameter */ case DICT_REGISTRY: { DWORD err, dwIgn; HKEY hRegKey; BYTE *ptr;
if (pszDictName == NULL_PTR) { goto ERROR_INIT; }
err = RegCreateKeyEx(HKEY_LOCAL_MACHINE, (const char *) pszDictName, 0L, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hRegKey, &dwIgn ); if(err != ERROR_SUCCESS) { goto ERROR_INIT; } dwIgn = 0; err = RegQueryValueEx(hRegKey, "X509 Dictionary", NULL, NULL, NULL, &dwIgn ); if(err != ERROR_SUCCESS) { RegCloseKey(hRegKey); goto ERROR_INIT; }
ptr = GMEM_Alloc(dwIgn); if (ptr == NULL) { RegCloseKey(hRegKey); goto ERROR_INIT; }
err = RegQueryValueEx(hRegKey, "X509 Dictionary", NULL, NULL, ptr, &dwIgn ); if(err != ERROR_SUCCESS) { RegCloseKey(hRegKey); GMEM_Free(ptr); goto ERROR_INIT; }
DictVersion = (BYTE)ptr[0];
usDictCount = (WORD)dwIgn - 1; pDictMemory = GMEM_Alloc(usDictCount);
if (pDictMemory == NULL) { RegCloseKey(hRegKey); GMEM_Free(ptr); goto ERROR_INIT; }
memcpy(pDictMemory, &ptr[1], usDictCount);
RegCloseKey(hRegKey); GMEM_Free(ptr); return(RV_SUCCESS); } break;
/* Dictionary read as file in path pszDictName parameter */ case DICT_FILE: { DWORD dwFileLen; BYTE *ptr; FILE *fp;
if (pszDictName == NULL_PTR) { goto ERROR_INIT; } dwFileLen = get_file_len(pszDictName); ptr = GMEM_Alloc(dwFileLen); if (ptr == NULL) { goto ERROR_INIT; } fp = fopen(pszDictName, "rb"); if (fp == NULL) { GMEM_Free(ptr); goto ERROR_INIT; }
if (!fread(ptr, dwFileLen, 1, fp)) { fclose(fp); GMEM_Free(ptr); goto ERROR_INIT; } fclose(fp); DictVersion = (BYTE)ptr[0];
usDictCount = (WORD)dwFileLen - 1; pDictMemory = GMEM_Alloc(usDictCount);
if (pDictMemory == NULL) { GMEM_Free(ptr); goto ERROR_INIT; }
memcpy(pDictMemory, &ptr[1], usDictCount);
GMEM_Free(ptr);
return(RV_SUCCESS); } break;
default: break; }
ERROR_INIT: DictVersion = 0; usDictCount = 0; pDictMemory = NULL_PTR; return(RV_BAD_DICTIONARY); }
/*******************************************************************************
* int CC_Exit(void) * * Description : Free dictionary. * * Remarks : * * In : * * Out : * * Responses : * *******************************************************************************/ int CC_Exit(void) { DictVersion = 0; usDictCount = 0; if (pDictMemory != NULL_PTR) { GMEM_Free(pDictMemory); } pDictMemory = NULL_PTR; return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Compress(BLOC *pCertificate, * BLOC *pCompressedCertificate * ) * * Description : Fonction de m�ta-compression visible depuis l'ext�rieur. * Adapte la sortie en fonction de la faisabilit� d'une compression * suivie d'une d�compression. * * Remarks : Le champ pData du bloc d'entr�e a �t� allou� par la fonction appelant. * Le champ pData du bloc de sortie est allou� ici. Il doit �tre * d�sallou� par la fonction appelant (sauf si RV_MALLOC_FAILED). * * In : *pCert : Bloc � m�ta-compresser * * Out : *pCompCert : Bloc 'meta-compress�' * Si probl�me lors de la compression/decompression : Renvoie le bloc * d'entr�e pr�c�d� d'un tag sp�cifique. * Sinon : Renvoie le bloc compress� pr�c�d� du num�ro de version * du dictionnaire. * * Responses : RV_SUCCESS : All is OK. * RV_COMPRESSION_FAILED : Un probl�me a eu lieu lors de l'�tape * de compression/d�compression donc le * bloc de sortie contient le bloc d'entr�e * pr�c�d� du tag TAG_COMPRESSION_FAILED. * RV_BLOC_TOO_LONG : Le bloc d'entr�e *commence* par un certificat * dont la compression a pu �tre invers�e. * Le bloc de sortie contient donc le compress� * de cette partie initiale seulement. * RV_MALLOC_FAILED : Un malloc a �chou� au niveau 'm�ta'. C'est le * seul r�el retour d'erreur. * *******************************************************************************/ int CC_Compress(BLOC *pCert, BLOC *pCompCert )
{ BLOC TryCompCert, TryUncompCert;
TryCompCert.pData = NULL_PTR; TryCompCert.usLen = 0; TryUncompCert.pData = NULL_PTR; TryUncompCert.usLen = 0;
#ifdef _STUDY
/* Ouverture des fichiers de log */
if ((pfdLog = fopen("CompCert.log", "a+")) == 0) { return(RV_FILE_OPEN_FAILED); } fprintf(pfdLog, "\n*****************************************************\n");
if ((pfdBinAc256 = fopen("Freq256.bin", "r+b")) == 0) { if ((pfdBinAc256 = fopen("Freq256.bin", "w+b")) == 0) { return(RV_FILE_OPEN_FAILED); } memset(Ac256, 0x00, 256 * sizeof(int)); } else { fread(Ac256, sizeof(int), 256, pfdBinAc256); }
if ((pfdBinAc16 = fopen("Freq016.bin", "r+b")) == 0) { if ((pfdBinAc16 = fopen("Freq016.bin", "w+b")) == 0) { return(RV_FILE_OPEN_FAILED); } memset(Ac16, 0x00, 16 * sizeof(int)); } else { fread(Ac16, sizeof(int), 16, pfdBinAc16); }
if ((pfdBinAc4 = fopen("Freq004.bin", "r+b")) == 0) { if ((pfdBinAc4 = fopen("Freq004.bin", "w+b")) == 0) { return(RV_FILE_OPEN_FAILED); } memset(Ac4, 0x00, 4 * sizeof(int)); } else { fread(Ac4, sizeof(int), 4, pfdBinAc4); }
if ((pfdBinAc2 = fopen("Freq002.bin", "r+b")) == 0) { if ((pfdBinAc2 = fopen("Freq002.bin", "w+b")) == 0) { return(RV_FILE_OPEN_FAILED); } memset(Ac2, 0x00, 2 * sizeof(int)); } else { fread(Ac2, sizeof(int), 2, pfdBinAc2); }
#endif
if (CC_Comp(pCert, &TryCompCert) != RV_SUCCESS) { /* Si la compression s'est mal pass�e alors on renvoie le fichier
d'entr�e en indiquant que le fichier n'est pas compress� */
if (TryCompCert.pData) { GMEM_Free(TryCompCert.pData); TryCompCert.pData = NULL_PTR; }
/* Allocation de la m�moire pour le certificat compress� */ if (pCompCert->usLen < pCert->usLen + 1) { pCompCert->usLen = pCert->usLen + 1; if (pCompCert->pData) { return(RV_BUFFER_TOO_SMALL); } else { return(RV_SUCCESS); } }
pCompCert->usLen = pCert->usLen + 1; pCompCert->pData[0] = TAG_COMPRESSION_FAILED; if (pCompCert->pData) { memcpy(&pCompCert->pData[1], pCert->pData, pCert->usLen); } return(RV_COMPRESSION_FAILED); }
if ( ( (CC_Uncomp(&TryCompCert, &TryUncompCert) != RV_SUCCESS) || (pCert->usLen != TryUncompCert.usLen) || (memcmp(TryUncompCert.pData, pCert->pData, pCert->usLen) != 0) ) && (memcmp(TryUncompCert.pData, pCert->pData, TryUncompCert.usLen) != 0) ) { /* Si la d�compression s'est mal pass�e ou bien si elle n'est pas fid�le
alors on renvoie le fichier d'entr�e en indiquant que le fichier n'est pas compress� */
if (TryCompCert.pData) { GMEM_Free(TryCompCert.pData); TryCompCert.pData = NULL_PTR; } if (TryUncompCert.pData) { GMEM_Free(TryUncompCert.pData); TryUncompCert.pData = NULL_PTR; }
/* Allocation de la m�moire pour le certificat */ if (pCompCert->usLen < pCert->usLen + 1) { pCompCert->usLen = pCert->usLen + 1; if (pCompCert->pData) { return(RV_BUFFER_TOO_SMALL); } else { return(RV_SUCCESS); } }
pCompCert->usLen = pCert->usLen + 1; pCompCert->pData[0] = TAG_COMPRESSION_FAILED; if (pCompCert->pData) { memcpy(&pCompCert->pData[1], pCert->pData, pCert->usLen); } return(RV_COMPRESSION_FAILED); }
#ifdef _STUDY
fseek(pfdBinAc256, 0, SEEK_SET); fwrite(Ac256, sizeof(int), 256, pfdBinAc256); fseek(pfdBinAc16, 0, SEEK_SET); fwrite(Ac16, sizeof(int), 16, pfdBinAc16); fseek(pfdBinAc4, 0, SEEK_SET); fwrite(Ac4, sizeof(int), 4, pfdBinAc4); fseek(pfdBinAc2, 0, SEEK_SET); fwrite(Ac2, sizeof(int), 2, pfdBinAc2);
if ((pfdLogFreq = fopen("Freq.log", "w")) == 0) { return(RV_FILE_OPEN_FAILED); }
for (sum = 0, i = 0; i < 256; sum += Ac256[i], i++) ;
fprintf(pfdLogFreq, "\nTotal = %d\n\n", sum * 8); for (i = 0; i < 2; i++) { fprintf(pfdLogFreq, "0x%02X (%03d) '%c' : %8d - %04.2f %%\n", i, i, (isgraph(i) ? i : ' '), Ac2[i], ((float) 100 * Ac2[i] / (sum * 8))); }
fprintf(pfdLogFreq, "\nTotal = %d\n\n", sum * 4); for (i = 0; i < 4; i++) { fprintf(pfdLogFreq, "0x%02X (%03d) '%c' : %8d - %04.2f %%\n", i, i, (isgraph(i) ? i : ' '), Ac4[i], ((float) 100 * Ac4[i] / (sum * 4))); }
fprintf(pfdLogFreq, "\nTotal = %d\n\n", sum * 2); for (i = 0; i < 16; i++) { fprintf(pfdLogFreq, "0x%02X (%03d) '%c' : %8d - %04.2f %%\n", i, i, (isgraph(i) ? i : ' '), Ac16[i], ((float) 100 * Ac16[i] / (sum * 2))); }
fprintf(pfdLogFreq, "\nTotal = %d\n\n", sum); for (i = 0; i < 256; i++) { fprintf(pfdLogFreq, "0x%02X (%03d) '%c' : %8d - %04.2f %%\n", i, i, (isgraph(i) ? i : ' '), Ac256[i], ((float) 100 * Ac256[i] / sum)); }
fclose(pfdBinAc256); fclose(pfdBinAc16); fclose(pfdBinAc4); fclose(pfdBinAc2);
fclose(pfdLogFreq); fclose(pfdLog);
#endif
/* Si tout s'est bien pass�, on renvoie le r�sultat en indiquant
qu'il est compress� (DictVersion != 0xFF) */ /* Allocation de la m�moire pour le certificat */ if (pCompCert->usLen < TryCompCert.usLen + 1) { if (TryCompCert.pData) { GMEM_Free(TryCompCert.pData); TryCompCert.pData = NULL_PTR; } if (TryUncompCert.pData) { GMEM_Free(TryUncompCert.pData); TryUncompCert.pData = NULL_PTR; }
pCompCert->usLen = TryCompCert.usLen + 1; if (pCompCert->pData) { return(RV_BUFFER_TOO_SMALL); } else { return(RV_SUCCESS); } }
pCompCert->usLen = TryCompCert.usLen + 1; if (pCompCert->pData) { pCompCert->pData[0] = DictVersion; memcpy(&pCompCert->pData[1], TryCompCert.pData, TryCompCert.usLen); } if (TryCompCert.pData) { GMEM_Free(TryCompCert.pData); TryCompCert.pData = NULL_PTR; } if (TryUncompCert.pData) { GMEM_Free(TryUncompCert.pData); TryUncompCert.pData = NULL_PTR; }
if (pCert->usLen != TryUncompCert.usLen) { return(RV_BLOC_TOO_LONG); } return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Uncompress(BLOC *pCompCert, * BLOC *pUncompCert * ) * * Description : Fonction de m�ta-d�compression visible depuis l'ext�rieur. * Retourne le bloc original (entr�e de la fonction CC_Compress) * sous r�serve toutefois d'une version ad�quate du dictionnaire. * * Remarks : Le champ pData du bloc d'entr�e a �t� allou� par la fonction appelant. * Le champ pData du bloc de sortie est allou� ici. Il doit �tre * d�sallou� par la fonction appelant (sauf si erreur). * Le comportement est impr�visible dans le cas o� le bloc d'entr�e * n'est pas le bloc de sortie d'un appel � la fonction CC_Compress. * * In : *pCompCert : Bloc � m�ta-d�compresser * * Out : *pUncompCert : Bloc 'm�ta-d�compress�' * (ou vide si RV_BAD_DICTIONARY) * * Responses : RV_SUCCESS : All is OK. * RV_BAD_DICTIONARY : La version du dictionnaire utilis�e pour la * d�compression est plus ancienne que celle * utilis�e pour la compression. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s lors de * la d�compression. * *******************************************************************************/ int CC_Uncompress(BLOC *pCompCert, BLOC *pUncompCert )
{ int resp;
BLOC TempCompCert, TempUncompCert;
if (pCompCert->pData[0] == TAG_COMPRESSION_FAILED) { /* Allocation de la m�moire pour le certificat
On pourrait se contenter de ne retourner que la zone m�moire � partir de l'octet 1 mais la fonction de d�compression est sens�e toujours allouer la zone dans laquelle elle renvoie le d�compress� */
if(pUncompCert->usLen < pCompCert->usLen - 1) { pUncompCert->usLen = pCompCert->usLen - 1; if (pUncompCert->pData) { return(RV_BUFFER_TOO_SMALL); } else { return(RV_SUCCESS); } }
pUncompCert->usLen = pCompCert->usLen - 1; if (pUncompCert->pData) { memcpy(pUncompCert->pData, &pCompCert->pData[1], pUncompCert->usLen); } return (RV_SUCCESS); } else if (pCompCert->pData[0] <= DictVersion) { TempCompCert.pData = &pCompCert->pData[1]; TempCompCert.usLen = pCompCert->usLen - 1;
TempUncompCert.usLen = 0; resp = CC_Uncomp(&TempCompCert, &TempUncompCert); if (resp == RV_SUCCESS) { if(pUncompCert->usLen < TempUncompCert.usLen) { GMEM_Free(TempUncompCert.pData);
pUncompCert->usLen = TempUncompCert.usLen; if (pUncompCert->pData) { return(RV_BUFFER_TOO_SMALL); } else { return(RV_SUCCESS); } }
pUncompCert->usLen = TempUncompCert.usLen; if (pUncompCert->pData) { memcpy(pUncompCert->pData, TempUncompCert.pData, TempUncompCert.usLen); } GMEM_Free(TempUncompCert.pData); } return (resp); } else { return (RV_BAD_DICTIONARY); } }
/*******************************************************************************
* int CC_Comp(BLOC *pCertificate, * BLOC *pCompressedCertificate * ) * * Description : Fonction interne de compression d'un certificat. * * Remarks : Le champ pData du bloc d'entr�e a �t� allou� par la fonction appelant. * Le champ pData du bloc de sortie est allou� ici. Il doit �tre * d�sallou� par la fonction appelant (sauf si erreur). * * In : *pCertificate : Bloc � compresser * * Out : *pCompressedCertificate : Bloc compress� * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Comp(BLOC *pCertificate, BLOC *pCompressedCertificate )
{ ASN1 Cert, tbsCert, signatureAlgo, signature; BLOC TmpCompCert, tbsCertEncoded, signatureAlgoEncoded, signatureEncoded; BYTE *pCurrent; int rv;
/* Eclatement du certificat en ses trois composants principaux */ dwPtrMax = pCertificate->pData + pCertificate->usLen; Cert.Asn1.pData = pCertificate->pData; rv = CC_ExtractContent(&Cert); if (rv != RV_SUCCESS) return rv; if (Cert.Asn1.usLen != pCertificate->usLen) { return(RV_INVALID_DATA); }
tbsCert.Asn1.pData = Cert.Content.pData; rv = CC_ExtractContent(&tbsCert); if (rv != RV_SUCCESS) return rv;
signatureAlgo.Asn1.pData = tbsCert.Content.pData + tbsCert.Content.usLen; rv = CC_ExtractContent(&signatureAlgo); if (rv != RV_SUCCESS) return rv;
signature.Asn1.pData = signatureAlgo.Content.pData + signatureAlgo.Content.usLen; rv = CC_ExtractContent(&signature); if (rv != RV_SUCCESS) return rv;
ASSERT(signature.Content.pData + signature.Content.usLen == Cert.Content.pData + Cert.Content.usLen);
/* Elaboration des composants principaux compress�s */
/* Les pData des blocs *Encoded sont allou�s par les fonctions CC_Encode_*.
Ils sont lib�r�s dans cette fonction apr�s usage */
tbsCertEncoded.pData = NULL; signatureAlgoEncoded.pData = NULL; signatureEncoded.pData = NULL;
rv = CC_Encode_TBSCertificate(&tbsCert.Content, &tbsCertEncoded); if (rv != RV_SUCCESS) goto err;
rv = CC_Encode_AlgorithmIdentifier(&signatureAlgo.Content, &signatureAlgoEncoded); if (rv != RV_SUCCESS) goto err;
rv = CC_Encode_Signature(&signature.Content, &signatureEncoded); if (rv != RV_SUCCESS) goto err;
/* Reconstruction du certificat compress� � partir de ses composants */
TmpCompCert.usLen = tbsCertEncoded.usLen + signatureAlgoEncoded.usLen + signatureEncoded.usLen;
/* A d�sallouer par le programme appelant */ if ((TmpCompCert.pData = GMEM_Alloc(TmpCompCert.usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
pCurrent = TmpCompCert.pData;
memcpy(pCurrent, tbsCertEncoded.pData, tbsCertEncoded.usLen); GMEM_Free(tbsCertEncoded.pData); pCurrent += tbsCertEncoded.usLen;
memcpy(pCurrent, signatureAlgoEncoded.pData, signatureAlgoEncoded.usLen); GMEM_Free(signatureAlgoEncoded.pData); pCurrent += signatureAlgoEncoded.usLen;
memcpy(pCurrent, signatureEncoded.pData, signatureEncoded.usLen); GMEM_Free(signatureEncoded.pData); pCurrent += signatureEncoded.usLen;
/* Et maintenant on compresse le certificat compress� !! */
#ifdef _GLOBAL_COMPRESSION
rv = CC_RawEncode(&TmpCompCert, pCompressedCertificate, FALSE); GMEM_Free(TmpCompCert.pData); if (rv != RV_SUCCESS) goto err; #else
*pCompressedCertificate = TmpCompCert; #endif
return(RV_SUCCESS);
err: GMEM_Free(tbsCertEncoded.pData); GMEM_Free(signatureAlgoEncoded.pData); GMEM_Free(signatureEncoded.pData);
return (rv);
}
/*******************************************************************************
* int CC_Uncomp(BLOC *pCompressedCertificate, * BLOC *pUncompressedCertificate * ) * * Description : Fonction interne de d�compression d'un certificat. * * Remarks : Le champ pData du bloc d'entr�e a �t� allou� par la fonction appelant. * Le champ pData du bloc de sortie est allou� ici. Il doit �tre * d�sallou� par la fonction appelant (sauf si erreur). * * In : *pCertificate : Bloc � compresser * * Out : *pCompressedCertificate : Bloc compress� * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Uncomp(BLOC *pCompressedCertificate, BLOC *pUncompressedCertificate )
{ ASN1 Cert, tbsCert, signatureAlgo, signature; BLOC TmpCompCert; BYTE *pCurrent; int rv; USHORT Length;
tbsCert.Asn1.pData = NULL; signatureAlgo.Asn1.pData = NULL; signature.Asn1.pData = NULL;
#ifdef _GLOBAL_COMPRESSION
/* Length est ici inutile */ rv = CC_RawDecode(pCompressedCertificate->pData, &TmpCompCert, &Length, FALSE); if (rv != RV_SUCCESS) return rv; #else
TmpCompCert = *pCompressedCertificate; #endif
/* D�codage des diff�rents composants du certificat */ /* CC_Decode_* et cc_BuildAsn1 allouent les pData de leurs arguments de
sortie. Ces zones sont � d�sallouer � ce niveau apr�s usage. */
pCurrent = TmpCompCert.pData;
rv = CC_Decode_TBSCertificate(pCurrent, &tbsCert.Content, &Length); if (rv != RV_SUCCESS) goto err; tbsCert.Tag = TAG_SEQUENCE; rv = CC_BuildAsn1(&tbsCert); GMEM_Free(tbsCert.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length; rv = CC_Decode_AlgorithmIdentifier(pCurrent, &signatureAlgo.Content, &Length); if (rv != RV_SUCCESS) goto err; signatureAlgo.Tag = TAG_SEQUENCE; rv = CC_BuildAsn1(&signatureAlgo); GMEM_Free(signatureAlgo.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length; rv = CC_Decode_Signature(pCurrent, &signature.Content, &Length); if (rv != RV_SUCCESS) goto err; signature.Tag = TAG_BIT_STRING; rv = CC_BuildAsn1(&signature); GMEM_Free(signature.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
ASSERT(pCurrent == TmpCompCert.pData + TmpCompCert.usLen);
#ifdef _GLOBAL_COMPRESSION
GMEM_Free(TmpCompCert.pData); #endif
/* Reconstruction de l'enveloppe Asn1 du certificat */
/* A d�sallouer � ce niveau apr�s usage */ Cert.Content.usLen = tbsCert.Asn1.usLen + signatureAlgo.Asn1.usLen + signature.Asn1.usLen;
if ((Cert.Content.pData = GMEM_Alloc(Cert.Content.usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
pCurrent = Cert.Content.pData;
memcpy(pCurrent, tbsCert.Asn1.pData, tbsCert.Asn1.usLen); GMEM_Free(tbsCert.Asn1.pData); pCurrent += tbsCert.Asn1.usLen;
memcpy(pCurrent, signatureAlgo.Asn1.pData, signatureAlgo.Asn1.usLen); GMEM_Free(signatureAlgo.Asn1.pData); pCurrent += signatureAlgo.Asn1.usLen;
memcpy(pCurrent, signature.Asn1.pData, signature.Asn1.usLen); GMEM_Free(signature.Asn1.pData); pCurrent += signature.Asn1.usLen;
Cert.Tag = TAG_SEQUENCE; rv = CC_BuildAsn1(&Cert); GMEM_Free(Cert.Content.pData); if (rv != RV_SUCCESS) return rv;
*pUncompressedCertificate = Cert.Asn1;
return(RV_SUCCESS);
err: GMEM_Free(tbsCert.Asn1.pData); GMEM_Free(signatureAlgo.Asn1.pData); GMEM_Free(signature.Asn1.pData);
return(rv); }
/*******************************************************************************
* int CC_ExtractContent(ASN1 *pAsn1) * * Description : Extrait d'un bloc Asn1 (pAsn1->Asn1) son contenu en �laguant son * enrobage (identifier bytes, length bytes) et le place dans le * bloc pAsn1->Content. * * Remarks : Le champ Asn1.pData a �t� allou� par la fonction appelant. * * In : pAsn1->Asn1.pData * * Out : Les champs suivants sont renseign�s (si RV_SUCCESS) : * - Tag * - Asn1.usLen * - Content.usLen * - Content.pData (pas d'allocation : on fait pointer sur la partie * ad�quate du contenu de Asn1.pData) * * Responses : RV_SUCCESS : All is OK. * RV_INVALID_DATA : Le format du bloc Asn1 n'est pas support�. * *******************************************************************************/ int CC_ExtractContent(ASN1 *pAsn1)
{ BYTE *pData; int NbBytes, i;
pData = pAsn1->Asn1.pData;
if ((pData[0] & 0x1F) == 0x1F) { /* High-tag-number : non support� */ return(RV_INVALID_DATA); } else { pAsn1->Tag = pData[0]; }
if (pData[1] == 0x80) { /* Constructed, indefinite-length method : non support� */ return(RV_INVALID_DATA); } else if (pData[1] > 0x82) { /* Constructed, definite-length method : longueur trop grande */ return(RV_INVALID_DATA); } else if (pData[1] < 0x80) { /* Primitive, definite-length method */ pAsn1->Content.usLen = pData[1]; pAsn1->Content.pData = &pData[2];
pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2;
/* Looking for memory violation */ if (pData + pAsn1->Content.usLen + 2 > dwPtrMax) { return(RV_INVALID_DATA); } } else { /* Constructed, definite-length method */
NbBytes = pData[1] & 0x7F; ASSERT(NbBytes <= 2);
pAsn1->Content.usLen = 0; for (i = 0; i < NbBytes; i++) { pAsn1->Content.usLen = (pAsn1->Content.usLen << 8) + pData[2+i]; }
/* Looking for memory violation */ if (pData + pAsn1->Content.usLen+2+NbBytes > dwPtrMax) { return(RV_INVALID_DATA); }
pAsn1->Content.pData = &pData[2+NbBytes];
pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2 + NbBytes; }
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_BuildAsn1(ASN1 *pAsn1) * * Description : Reconstruit un bloc Asn1 (pAsn1->Asn1) � partir de son contenu * (pAsn1->Content) et de son Tag suppos� sp�cifi� (pAsn1->Tag) * en synth�tisant son enrobage (identifier bytes, length bytes). * * Remarks : Le champ Content.pData a �t� allou� par la fonction appelant. * Seulement la forme 'low-tag-number' (tag sur un seul octet) est * support�e. * * In : pAsn1->Content.usLen * pAsn1->Content.pData * pAsn1->Tag * * Out : Les champs suivants sont renseign�s (si RV_SUCCESS) : * - Asn1.usLen * - Asn1.pData (allou� ici, � lib�rer par la fonction appelant) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * *******************************************************************************/ int CC_BuildAsn1(ASN1 *pAsn1)
{ if (pAsn1->Content.usLen < 0x0080) { pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2;
if ((pAsn1->Asn1.pData = GMEM_Alloc(pAsn1->Asn1.usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); }
pAsn1->Asn1.pData[0] = (BYTE) pAsn1->Tag; pAsn1->Asn1.pData[1] = (BYTE) pAsn1->Content.usLen; memcpy(&(pAsn1->Asn1.pData[2]), pAsn1->Content.pData, pAsn1->Content.usLen); } else { if (pAsn1->Content.usLen < 0x0100) { pAsn1->Asn1.usLen = pAsn1->Content.usLen + 3;
if ((pAsn1->Asn1.pData = GMEM_Alloc(pAsn1->Asn1.usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); }
pAsn1->Asn1.pData[0] = pAsn1->Tag; pAsn1->Asn1.pData[1] = 0x81; pAsn1->Asn1.pData[2] = (BYTE)pAsn1->Content.usLen; memcpy(&(pAsn1->Asn1.pData[3]), pAsn1->Content.pData, pAsn1->Content.usLen); } else { pAsn1->Asn1.usLen = pAsn1->Content.usLen + 4;
if ((pAsn1->Asn1.pData = GMEM_Alloc(pAsn1->Asn1.usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); }
pAsn1->Asn1.pData[0] = pAsn1->Tag; pAsn1->Asn1.pData[1] = 0x82; pAsn1->Asn1.pData[2] = pAsn1->Content.usLen >> 8; pAsn1->Asn1.pData[3] = pAsn1->Content.usLen & 0x00FF; memcpy(&(pAsn1->Asn1.pData[4]), pAsn1->Content.pData, pAsn1->Content.usLen); } }
return(RV_SUCCESS); }
/*******************************************************************************
* int SearchDataByIndex(USHORT usIndex, * BYTE *pDict, * BLOC *pOutBloc * ) * * Description : Recherche l'entr�e (mot/phrase) dans le dictionnaire dont * l'index est sp�cifi� en entr�e. * * Remarks : Le format du dictionnaire est le suivant : * * - 2 octets : le nombre d'entr�es * - 2 octets : la longueur totale du dictionnaire * * - 2 octets : I0, l'index de l'entr�e 0 * - 2 octets : L0, la longueur de l'entr�e 0 * - L0 octets : l'entr�e 0 * * - 2 octets : I1, l'index de l'entr�e 1 * - 2 octets : L1, la longueur de l'entr�e 1 * - L1 octets : l'entr�e 1 * * - ........ * * In : usIndex : l'index du mot/phrase recherch� * pDict : pointe sur le dictionnaire charg� en m�moire * * Out : pOutBloc : l'entr�e correspondant � l'index * * Responses : RV_SUCCESS : All is OK. * RV_BAD_DICTIONARY : Aucune entr�e ayant le bon index n'a �t� * trouv�e dans le dictionnaire. * *******************************************************************************/ int SearchDataByIndex(USHORT usIndex, BYTE *pDict, BLOC *pOutBloc )
{ BYTE *pCurrent; BOOL bFound = FALSE; USHORT i, usLength, usCount, usCurrent;
usCount = *(USHORT *)pDict; //memcpy(&usCount, pDict, sizeof(usCount));
pCurrent = pDict + 4;
bFound = FALSE;
for (i = 0; i < usCount; i++) { usCurrent = *(USHORT UNALIGNED *)pCurrent; //memcpy(&usCurrent, (USHORT *) pCurrent, 2);
pCurrent += 2; if (usCurrent == usIndex) { bFound = TRUE; break; } usLength = *(USHORT UNALIGNED *)pCurrent; //memcpy(&usLength, (USHORT *) pCurrent, 2);
pCurrent += (2 + usLength); } if (!bFound) { return(RV_BAD_DICTIONARY); }
usLength = *(USHORT UNALIGNED *)pCurrent; //memcpy(&usLength, (USHORT *) pCurrent, 2);
pCurrent += 2;
pOutBloc->pData = pCurrent; pOutBloc->usLen = usLength;
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_RawEncode(BLOC *pInBloc, * BLOC *pOutBloc, * BOOL bUseDictionary * ) * * Description : Traite le bloc d'entr�e comme une donn�e terminale dans le * processus d'extractions successives des enrobages Asn1. * Le but est ici de compresser au maximum ce bloc sans faire * aucune hypoth�se sur sa structure Asn1. Pour ce faire, on * commence (si bUseDictionary == TRUE) par remplacer chaque * mot/phrase du dictionnaire rencontr� par son index pr�c�d� d'un * caract�re d'�chappement, puis on applique � la donn�e r�siduelle * successivement chaque algorithme de compression statistique pour * n'en retenir que le meilleur. La sortie est le meilleur * compress� du r�sidu pr�c�d� d'un header codant le num�ro de * l'algo ainsi que la longueur du compress�. * * Remarks : * * In : pInBloc : le bloc � encoder * bUseDictionary : on peut ne pas utiliser le dictionnaire * * Out : pOutBloc : le bloc encod� (m�moire allou�e ici � lib�rer par le * programme appelant) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * RV_INVALID_DATA : Le meilleur compress� du r�sidu est trop long. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_RawEncode(BLOC *pInBloc, BLOC *pOutBloc, BOOL bUseDictionary )
{ BLOC OldBloc, NewBloc, CompBloc, BestBloc; BOOL bFound; BYTE *pCurrent, *pToCurrent, *pFromCurrent, *pData, BestAlgoId; int // value,
rv; USHORT pos, usEscapeCount, usIndex, usLength, usCount, usCurrent;
/* Il peut �tre int�ressant de ne pas utiliser le dictionnaire si on sait
qu'il ne va pas servir car cela evite de doubler les 0xFF pour rien */
if (bUseDictionary == FALSE) { OldBloc.usLen = pInBloc->usLen; if ((OldBloc.pData = GMEM_Alloc(OldBloc.usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); } memcpy(OldBloc.pData, pInBloc->pData, OldBloc.usLen); } else { /* On recopie le bloc d'entr�e dans un bloc de travail en doublant les 'escape' */
pCurrent = pInBloc->pData; usEscapeCount = 0; for (pos = 0; pos < pInBloc->usLen; pos++) { if (*pCurrent == ESCAPE_CHAR) { usEscapeCount++; } pCurrent++; }
OldBloc.usLen = pInBloc->usLen + usEscapeCount; if ((OldBloc.pData = GMEM_Alloc(OldBloc.usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); }
pFromCurrent = pInBloc->pData; pToCurrent = OldBloc.pData; for (pos = 0; pos < pInBloc->usLen; pos++) { if ((*pToCurrent = *pFromCurrent) == ESCAPE_CHAR) { pToCurrent++; *pToCurrent = ESCAPE_CHAR; } pFromCurrent++; pToCurrent++; }
/* Si un dictionnaire existe, on l'utilise pour coder ses entr�es rencontr�es */
if (pDictMemory != NULL_PTR) { pCurrent = pDictMemory;
memcpy(&usCount, pCurrent, sizeof(usCount)); pCurrent += 4;
for (usCurrent = 0; usCurrent < usCount; usCurrent++) { memcpy(&usIndex, pCurrent, sizeof(usIndex)); pCurrent += 2;
memcpy(&usLength, pCurrent, sizeof(usLength)); pCurrent += 2;
if (usLength <= OldBloc.usLen) { bFound = FALSE; for (pos = 0; pos < OldBloc.usLen - usLength + 1; pos++) { if (memcmp(pCurrent, OldBloc.pData + pos, usLength) == 0) { bFound = TRUE; break; } }
if (bFound) { if (usIndex < 0x80) { NewBloc.usLen = OldBloc.usLen - usLength + 2; if ((NewBloc.pData = GMEM_Alloc(NewBloc.usLen)) == NULL_PTR) { GMEM_Free(OldBloc.pData); return(RV_MALLOC_FAILED); } memcpy(NewBloc.pData, OldBloc.pData, pos); NewBloc.pData[pos] = ESCAPE_CHAR; NewBloc.pData[pos + 1] = (BYTE) usIndex; memcpy(NewBloc.pData + pos + 2, OldBloc.pData + pos + usLength, OldBloc.usLen - pos - usLength); GMEM_Free(OldBloc.pData); } else { NewBloc.usLen = OldBloc.usLen - usLength + 3; if ((NewBloc.pData = GMEM_Alloc(NewBloc.usLen)) == NULL_PTR) { GMEM_Free(OldBloc.pData); return(RV_MALLOC_FAILED); } memcpy(NewBloc.pData, OldBloc.pData, pos); NewBloc.pData[pos] = ESCAPE_CHAR; NewBloc.pData[pos + 1] = (BYTE) (usIndex >> 8) | 0x80; NewBloc.pData[pos + 2] = (BYTE) (usIndex & 0x00FF); memcpy(NewBloc.pData + pos + 3, OldBloc.pData + pos + usLength, OldBloc.usLen - pos - usLength); GMEM_Free(OldBloc.pData); }
OldBloc = NewBloc; } }
pCurrent += usLength; } } }
#ifdef _STUDY
for (i = 0; i < OldBloc.usLen; i++) { value = OldBloc.pData[i]; Ac256[value]++;
Ac16[value & 0x0F]++; Ac16[(value & 0xF0) >> 4]++;
Ac4[value & 0x03]++; Ac4[(value & 0x0C) >> 2]++; Ac4[(value & 0x30) >> 4]++; Ac4[(value & 0xC0) >> 6]++;
Ac2[value & 0x01]++; value >>= 1; Ac2[value & 0x01]++; value >>= 1; Ac2[value & 0x01]++; value >>= 1; Ac2[value & 0x01]++; value >>= 1; Ac2[value & 0x01]++; value >>= 1; Ac2[value & 0x01]++; value >>= 1; Ac2[value & 0x01]++; value >>= 1; Ac2[value & 0x01]++; value >>= 1; }
fprintf(pfdLog, "\n"); for (i = 0; i < (OldBloc.usLen <= 8 ? OldBloc.usLen : 8); i++) { fprintf(pfdLog, "%02X", OldBloc.pData[i]); } fprintf(pfdLog, " ("); for (i = 0; i < (OldBloc.usLen <= 8 ? OldBloc.usLen : 8); i++) { fprintf(pfdLog, "%c", OldBloc.pData[i]); } fprintf(pfdLog, ")\n");
#endif
BestBloc = OldBloc; BestAlgoId = ALGO_NONE;
#ifdef _ALGO_1
rv = CC_GenericCompress(&OldBloc, &CompBloc, ALGO_ACFX8); if (rv == RV_MALLOC_FAILED) return rv; // The compression algorithm may return RV_COMPRESSION_FAILED when
// the compression algorithm wants to use MORE space than the input data.
// In such a case, the algorithm returns the raw data in the compressed block
if (CompBloc.usLen < BestBloc.usLen) { /* On pr�serve OldBloc.pData qui sert pour les autres algos */ if (BestBloc.pData != OldBloc.pData) { GMEM_Free(BestBloc.pData); } BestBloc = CompBloc; BestAlgoId = ALGO_ACFX8; } else { GMEM_Free(CompBloc.pData); } #endif
#ifdef _ALGO_2
rv = CC_GenericCompress(&OldBloc, &CompBloc, ALGO_ACAD8); if (rv == RV_MALLOC_FAILED) return rv; // The compression algorithm may return RV_COMPRESSION_FAILED when
// the compression algorithm wants to use MORE space than the input data.
// In such a case, the algorithm returns the raw data in the compressed block
if (CompBloc.usLen < BestBloc.usLen) { /* On pr�serve OldBloc.pData qui sert pour les autres algos */ if (BestBloc.pData != OldBloc.pData) { GMEM_Free(BestBloc.pData); } BestBloc = CompBloc; BestAlgoId = ALGO_ACAD8; } else { GMEM_Free(CompBloc.pData); } #endif
if (BestBloc.usLen < 0x1F) /* La valeur 0x1F peut engendrer 0xFF = ESCAPE_CHAR */ { if ((pData = GMEM_Alloc(BestBloc.usLen + 1)) == NULL_PTR) { GMEM_Free(BestBloc.pData); return(RV_MALLOC_FAILED); } else { pData[0] = (BestAlgoId << 5) | BestBloc.usLen; memcpy(&pData[1], BestBloc.pData, BestBloc.usLen);
pOutBloc->usLen = BestBloc.usLen + 1; pOutBloc->pData = pData;
GMEM_Free(BestBloc.pData); } } else if (BestBloc.usLen < 0x2000) { if ((pData = GMEM_Alloc(BestBloc.usLen + 3)) == NULL_PTR) { GMEM_Free(BestBloc.pData); return(RV_MALLOC_FAILED); } else { pData[0] = ESCAPE_CHAR; pData[1] = (BestAlgoId << 5) | (BestBloc.usLen >> 8); pData[2] = BestBloc.usLen & 0xFF; memcpy(&pData[3], BestBloc.pData, BestBloc.usLen);
pOutBloc->usLen = BestBloc.usLen + 3; pOutBloc->pData = pData;
GMEM_Free(BestBloc.pData); } } else { GMEM_Free(BestBloc.pData); return(RV_INVALID_DATA); }
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_RawDecode(BYTE *pInBloc, * BLOC *pOutBloc, * USHORT *pLength, * BOOL bUseDictionnary * ) * * Description : Transformation inverse de 'CC_RawEncode'. * * Remarks : * * In : pInBloc : le bloc � d�coder * bUseDictionary : on peut ne pas utiliser le dictionnaire (doit * �tre consistent avec l'encodage) * * Out : pOutBloc : le bloc d�cod� (m�moire allou�e ici � lib�rer par le * programme appelant) * pLength : la longueur de donn�es encod�s utilis�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_RawDecode(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength, BOOL bUseDictionary )
{ BLOC OldBloc, NewBloc, RecordBloc, CompData; BYTE AlgoId; int rv; USHORT pos, usIndex;
if (pInData[0] == ESCAPE_CHAR) { AlgoId = pInData[1] >> 5; CompData.usLen = ((pInData[1] & 0x1F) << 8) + pInData[2]; CompData.pData = &(pInData[3]); *pLength = CompData.usLen + 3; } else { AlgoId = pInData[0] >> 5; CompData.usLen = pInData[0] & 0x1F; CompData.pData = &(pInData[1]); *pLength = CompData.usLen + 1; }
rv = CC_GenericUncompress(&CompData, &OldBloc, AlgoId); if (rv != RV_SUCCESS) return rv;
if (bUseDictionary) { pos = 0; while (pos < OldBloc.usLen) { if (OldBloc.pData[pos] == ESCAPE_CHAR) { if (OldBloc.pData[pos + 1] == ESCAPE_CHAR) { NewBloc.usLen = OldBloc.usLen - 1; if ((NewBloc.pData = GMEM_Alloc(NewBloc.usLen)) == NULL_PTR) { GMEM_Free(OldBloc.pData); return(RV_MALLOC_FAILED); }
memcpy(NewBloc.pData, OldBloc.pData, pos); NewBloc.pData[pos] = ESCAPE_CHAR; memcpy(NewBloc.pData + pos + 1, OldBloc.pData + pos + 2, OldBloc.usLen - pos - 2);
GMEM_Free(OldBloc.pData); OldBloc = NewBloc;
pos++; } else if (OldBloc.pData[pos + 1] < 0x80) { usIndex = OldBloc.pData[pos + 1];
rv = SearchDataByIndex(usIndex, pDictMemory, &RecordBloc); if (rv != RV_SUCCESS) { GMEM_Free(OldBloc.pData); return rv; }
NewBloc.usLen = OldBloc.usLen - 2 + RecordBloc.usLen; if ((NewBloc.pData = GMEM_Alloc(NewBloc.usLen)) == NULL_PTR) { GMEM_Free(OldBloc.pData); return(RV_MALLOC_FAILED); }
memcpy(NewBloc.pData, OldBloc.pData, pos); memcpy(NewBloc.pData + pos, RecordBloc.pData, RecordBloc.usLen); memcpy(NewBloc.pData + pos + RecordBloc.usLen, OldBloc.pData + pos + 2, OldBloc.usLen - pos - 2);
GMEM_Free(OldBloc.pData); OldBloc = NewBloc;
pos += RecordBloc.usLen; } else { usIndex = ((OldBloc.pData[pos + 1] & 0x7F) << 8) + OldBloc.pData[pos + 2];
rv = SearchDataByIndex(usIndex, pDictMemory, &RecordBloc); if (rv != RV_SUCCESS) { GMEM_Free(OldBloc.pData); return rv; }
NewBloc.usLen = OldBloc.usLen - 3 + RecordBloc.usLen; if ((NewBloc.pData = GMEM_Alloc(NewBloc.usLen)) == NULL_PTR) { GMEM_Free(OldBloc.pData); return(RV_MALLOC_FAILED); }
memcpy(NewBloc.pData, OldBloc.pData, pos); memcpy(NewBloc.pData + pos, RecordBloc.pData, RecordBloc.usLen); memcpy(NewBloc.pData + pos + RecordBloc.usLen, OldBloc.pData + pos + 3, OldBloc.usLen - pos - 3);
GMEM_Free(OldBloc.pData); OldBloc = NewBloc;
pos += RecordBloc.usLen; } } else { pos++; } } }
*pOutBloc = OldBloc;
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_GenericCompress(BLOC *pUncompBloc, * BLOC *pCompBloc, * BYTE AlgoId * ) * * Description : Effectue une compression statistique sur la donn�e d'entr�e en * utilisant l'algorithme sp�cifi� dans AlgoId. * * Remarks : Si l'algorithme sp�cifi� n'est pas impl�ment�, renvoie la donn�e * originale. * * In : pUncompBloc : la donn�e � compresser * AlgoId : num�ro de l'algorithme � employer * * Out : pCompBloc : la donn�e compress�e (m�moire allou�e ici � lib�rer * par la fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * *******************************************************************************/ int CC_GenericCompress(BLOC *pUncompBloc, BLOC *pCompBloc, BYTE AlgoId )
{ switch(AlgoId) { #ifdef _ALGO_1
case ALGO_ACFX8 : /* Arithmetic coding, byte oriented, fixed model */ { if (AcFx8_Encode(pUncompBloc, pCompBloc) != RV_SUCCESS) { return(RV_INVALID_DATA); } break; } #endif
#ifdef _ALGO_2
case ALGO_ACAD8 : /* Arithmetic coding, byte oriented, adaptative model */ { if (AcAd8_Encode(pUncompBloc, pCompBloc) != RV_SUCCESS) { return(RV_INVALID_DATA); } break; } #endif
default : { if ((pCompBloc->pData = GMEM_Alloc(pUncompBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); } pCompBloc->usLen = pUncompBloc->usLen; memcpy(pCompBloc->pData, pUncompBloc->pData, pCompBloc->usLen); break; } }
#ifdef _STUDY
fprintf(pfdLog, "Algo : %d | 0x%04x (%04d) -> 0x%04x (%04d)", AlgoId, pUncompBloc->usLen, pUncompBloc->usLen, pCompBloc->usLen, pCompBloc->usLen ); if (pUncompBloc->usLen > pCompBloc->usLen) { fprintf(pfdLog, " | %d", pCompBloc->usLen - pUncompBloc->usLen); } fprintf(pfdLog, "\n"); #endif
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_GenericUncompress(BLOC *pCompBloc, * BLOC *pUncompBloc, * BYTE AlgoID * ) * * Description : Effectue une d�compression statistique sur la donn�e d'entr�e en * utilisant l'algorithme sp�cifi� dans AlgoId. * * Remarks : * * In : pUncompBloc : la donn�e � d�compresser * AlgoId : num�ro de l'algorithme � employer * * Out : pCompBloc : la donn�e d�compress�e (m�moire allou�e ici � * lib�rer par la fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * RV_INVALID_DATA : L'algorithme sp�cifi� n'existe pas. * *******************************************************************************/ int CC_GenericUncompress(BLOC *pCompBloc, BLOC *pUncompBloc, BYTE AlgoId )
{ switch(AlgoId) { case ALGO_NONE : pUncompBloc->usLen = pCompBloc->usLen; if ((pUncompBloc->pData = GMEM_Alloc(pUncompBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); } memcpy(pUncompBloc->pData, pCompBloc->pData, pUncompBloc->usLen); break;
#ifdef _ALGO_1
case ALGO_ACFX8 : if (AcFx8_Decode(pCompBloc, pUncompBloc) != RV_SUCCESS) { return(RV_INVALID_DATA); } break; #endif
#ifdef _ALGO_2
case ALGO_ACAD8 : if (AcAd8_Decode(pCompBloc, pUncompBloc) != RV_SUCCESS) { return(RV_INVALID_DATA); } break; #endif
default : return(RV_INVALID_DATA); break; }
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Encode_TBSCertificate(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode une donn�e de type TBSCertificate. * Ceci consiste en l'�clatement en ses diff�rents composants, * leurs d�senrobages Asn1 et leurs encodages respectifs, et la * concat�nation de ces r�sultats. * * Remarks : Certaines parties d'un TBSCertificate sont optionnelles. On * d�tecte pour chacune d'elles si elle est pr�sente et on * l'indique dans des bits r�serv�s d'un octet de contr�le plac� * en d�but du r�sultat encod�. Cet octet de contr�le contient * �galement le num�ro de version X.509 du certificat. * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_TBSCertificate(BLOC *pInBloc, BLOC *pOutBloc )
{ ASN1 serialNumberPart, signaturePart, issuerPart, validityPart, subjectPart, subjectPKInfoPart, issuerUIDPart, subjectUIDPart, extensionsPart; BLOC serialNumberEncoded, signatureEncoded, issuerEncoded, validityEncoded, subjectEncoded, subjectPKInfoEncoded, issuerUIDEncoded, subjectUIDEncoded, extensionsEncoded; BOOL bVersionPresent = FALSE, bIssuerUIDPresent = FALSE, bSubjectUIDPresent = FALSE, bExtensionsPresent = FALSE; BYTE *pCurrent; int rv; USHORT usVersion = 0;
/* D�composition du tbsCertificate en ses diff�rents composants */ pCurrent = pInBloc->pData;
if (pCurrent[0] == TAG_OPTION_VERSION) { /* On a alors A0 03 02 01 vv o� vv est la version */ bVersionPresent = TRUE; usVersion = pCurrent[4]; pCurrent += 5; }
serialNumberPart.Asn1.pData = pCurrent; rv = CC_ExtractContent(&serialNumberPart); if (rv != RV_SUCCESS) return rv; pCurrent = serialNumberPart.Content.pData + serialNumberPart.Content.usLen;
signaturePart.Asn1.pData = pCurrent; rv = CC_ExtractContent(&signaturePart); if (rv != RV_SUCCESS) return rv; pCurrent = signaturePart.Content.pData + signaturePart.Content.usLen;
issuerPart.Asn1.pData = pCurrent; rv = CC_ExtractContent(&issuerPart); if (rv != RV_SUCCESS) return rv; pCurrent = issuerPart.Content.pData + issuerPart.Content.usLen;
validityPart.Asn1.pData = pCurrent; rv = CC_ExtractContent(&validityPart); if (rv != RV_SUCCESS) return rv; pCurrent = validityPart.Content.pData + validityPart.Content.usLen;
subjectPart.Asn1.pData = pCurrent; rv = CC_ExtractContent(&subjectPart); #ifdef _STUDY
// fprintf(pfdLog, "Subject : %d octets\n", subjectPart.Asn1.usLen);
#endif
if (rv != RV_SUCCESS) return rv; pCurrent = subjectPart.Content.pData + subjectPart.Content.usLen;
subjectPKInfoPart.Asn1.pData = pCurrent; rv = CC_ExtractContent(&subjectPKInfoPart); if (rv != RV_SUCCESS) return rv; pCurrent = subjectPKInfoPart.Content.pData + subjectPKInfoPart.Content.usLen;
if (pCurrent[0] == TAG_OPTION_ISSUER_UID) { bIssuerUIDPresent = TRUE;
issuerUIDPart.Asn1.pData = pCurrent; rv = CC_ExtractContent(&issuerUIDPart); if (rv != RV_SUCCESS) return rv; pCurrent = issuerUIDPart.Content.pData + issuerUIDPart.Content.usLen; }
if (pCurrent[0] == TAG_OPTION_SUBJECT_UID) { bSubjectUIDPresent = TRUE;
subjectUIDPart.Asn1.pData = pCurrent; rv = CC_ExtractContent(&subjectUIDPart); if (rv != RV_SUCCESS) return rv; pCurrent = subjectUIDPart.Content.pData + subjectUIDPart.Content.usLen; }
if (pCurrent[0] == TAG_OPTION_EXTENSIONS) { bExtensionsPresent = TRUE;
extensionsPart.Asn1.pData = pCurrent; rv = CC_ExtractContent(&extensionsPart); if (rv != RV_SUCCESS) return rv; pCurrent = extensionsPart.Content.pData + extensionsPart.Content.usLen; }
/* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
/* Les pData des blocs *Encoded sont allou�s par les fonctions CC_Encode_*.
Ils sont lib�r�s dans cette fonction apr�s usage */
serialNumberEncoded.pData = NULL; signatureEncoded.pData = NULL; issuerEncoded.pData = NULL; validityEncoded.pData = NULL; subjectEncoded.pData = NULL; subjectPKInfoEncoded.pData= NULL; issuerUIDEncoded.pData = NULL; subjectUIDEncoded.pData = NULL; extensionsEncoded.pData = NULL;
pOutBloc->usLen = 1;
rv = CC_Encode_CertificateSerialNumber(&serialNumberPart.Content, &serialNumberEncoded); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += serialNumberEncoded.usLen;
rv = CC_Encode_AlgorithmIdentifier(&signaturePart.Content, &signatureEncoded); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += signatureEncoded.usLen;
rv = CC_Encode_Name(&issuerPart.Content, &issuerEncoded); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += issuerEncoded.usLen;
rv = CC_Encode_Validity(&validityPart.Content, &validityEncoded); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += validityEncoded.usLen;
rv = CC_Encode_Name(&subjectPart.Content, &subjectEncoded); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += subjectEncoded.usLen;
rv = CC_Encode_SubjectPKInfo(&subjectPKInfoPart.Content, &subjectPKInfoEncoded); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += subjectPKInfoEncoded.usLen;
if (bIssuerUIDPresent == TRUE) { rv = CC_Encode_UniqueIdentifier(&issuerUIDPart.Content, &issuerUIDEncoded); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += issuerUIDEncoded.usLen; }
if (bSubjectUIDPresent == TRUE) { rv = CC_Encode_UniqueIdentifier(&subjectUIDPart.Content, &subjectUIDEncoded); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += subjectUIDEncoded.usLen; }
if (bExtensionsPresent == TRUE) { rv = CC_Encode_Extensions(&extensionsPart.Content, &extensionsEncoded); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += extensionsEncoded.usLen; }
/* Reconstruction � partir des composants */
/* A d�sallouer par le programme appelant */ if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
pCurrent = pOutBloc->pData;
*pCurrent = 0x80 * (bVersionPresent == TRUE) + 0x40 * (bIssuerUIDPresent == TRUE) + 0x20 * (bSubjectUIDPresent == TRUE) + 0x10 * (bExtensionsPresent == TRUE) + usVersion; pCurrent++;
memcpy(pCurrent, serialNumberEncoded.pData, serialNumberEncoded.usLen); GMEM_Free(serialNumberEncoded.pData); pCurrent += serialNumberEncoded.usLen;
memcpy(pCurrent, signatureEncoded.pData, signatureEncoded.usLen); GMEM_Free(signatureEncoded.pData); pCurrent += signatureEncoded.usLen;
memcpy(pCurrent, issuerEncoded.pData, issuerEncoded.usLen); GMEM_Free(issuerEncoded.pData); pCurrent += issuerEncoded.usLen;
memcpy(pCurrent, validityEncoded.pData, validityEncoded.usLen); GMEM_Free(validityEncoded.pData); pCurrent += validityEncoded.usLen;
memcpy(pCurrent, subjectEncoded.pData, subjectEncoded.usLen); GMEM_Free(subjectEncoded.pData); pCurrent += subjectEncoded.usLen;
memcpy(pCurrent, subjectPKInfoEncoded.pData, subjectPKInfoEncoded.usLen); GMEM_Free(subjectPKInfoEncoded.pData); pCurrent += subjectPKInfoEncoded.usLen;
if (bIssuerUIDPresent == TRUE) { memcpy(pCurrent, issuerUIDEncoded.pData, issuerUIDEncoded.usLen); GMEM_Free(issuerUIDEncoded.pData); pCurrent += issuerUIDEncoded.usLen; }
if (bSubjectUIDPresent == TRUE) { memcpy(pCurrent, subjectUIDEncoded.pData, subjectUIDEncoded.usLen); GMEM_Free(subjectUIDEncoded.pData); pCurrent += subjectUIDEncoded.usLen; }
if (bExtensionsPresent == TRUE) { memcpy(pCurrent, extensionsEncoded.pData, extensionsEncoded.usLen); GMEM_Free(extensionsEncoded.pData); pCurrent += extensionsEncoded.usLen; }
return(RV_SUCCESS);
err: GMEM_Free(serialNumberEncoded.pData); GMEM_Free(signatureEncoded.pData); GMEM_Free(issuerEncoded.pData); GMEM_Free(validityEncoded.pData); GMEM_Free(subjectEncoded.pData); GMEM_Free(subjectPKInfoEncoded.pData); GMEM_Free(issuerUIDEncoded.pData); GMEM_Free(subjectUIDEncoded.pData); GMEM_Free(extensionsEncoded.pData); return rv; }
/*******************************************************************************
* int CC_Encode_CertificateSerialNumber(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode une donn�e de type CertificateSerialNumber. * Ceci consiste seulement en l'encodage brute (CC_RawEncode) de la * donn�e d'entr�e. * * Remarks : * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_CertificateSerialNumber(BLOC *pInBloc, BLOC *pOutBloc )
{ int rv;
rv = CC_RawEncode(pInBloc, pOutBloc, TRUE); if (rv != RV_SUCCESS) return rv;
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Encode_AlgorithmIdentifier(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode une donn�e de type AlgorithmIdentifier. * Ceci consiste en l'�clatement en ses diff�rents composants, * leurs d�senrobages Asn1 et leurs encodages respectifs, et la * concat�nation de ces r�sultats. * * Remarks : bNullParam sert � coder sur un bit l'information qu'il n'y a pas * de param�tre � l'algorithme. Cette information occupe toujours * deux octets dans le certificat est vaut toujours {0x05, 0x00}. * On utilise un dictionnaire statique (d�fini au d�but de ce * source) pour remplacer le type d'algorithme par un index. * Un octet de contr�le (en d�but du r�sultat) indique, ou bien que * l'on n'a pas trouv� le type d'algo dans le dico (valeur 0xFF -> * Encodage brut de la donn�e d'entr�e int�grale), ou bien un flag * pr�cisant s'il y a des param�tres et l'index du type d'algo. * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_AlgorithmIdentifier(BLOC *pInBloc, BLOC *pOutBloc )
{ ASN1 AlgorithmPart, ParametersPart; BLOC AlgorithmIdentifierEncoded, ParametersAsn1Encoded; BOOL bFound, bNoParam = FALSE, bNullParam = FALSE; int rv; USHORT Index, AlgoIndex;
AlgorithmPart.Asn1.pData = pInBloc->pData; rv = CC_ExtractContent(&AlgorithmPart); if (rv != RV_SUCCESS) return rv;
if (AlgorithmPart.Asn1.usLen == pInBloc->usLen) { bNoParam = TRUE; bNullParam = FALSE; } else { ParametersPart.Asn1.pData = AlgorithmPart.Content.pData + AlgorithmPart.Content.usLen; rv = CC_ExtractContent(&ParametersPart); if (rv != RV_SUCCESS) return rv;
if (ParametersPart.Content.usLen == 0) { bNoParam = TRUE; bNullParam = TRUE; } }
/* Recherche de l'identifiant de l'algorithme dans le dictionnaire */
Index = 0; bFound = FALSE; while ((bFound == FALSE) && (AlgorithmTypeDict[Index] != NULL)) { if (!memcmp(AlgorithmTypeDict[Index], AlgorithmPart.Content.pData, AlgorithmPart.Content.usLen)) { bFound = TRUE; AlgoIndex = Index; } Index++; }
/* Construction de l'encodage */
if (bFound == TRUE) { if (bNoParam == TRUE) { if (bNullParam == TRUE) { /* Si on a trouv� l'algorithme et il n'y a pas de param�tre */
pOutBloc->usLen = 1; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return (RV_MALLOC_FAILED); }
pOutBloc->pData[0] = (AlgoIndex | 0x80); } else { pOutBloc->usLen = 2; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return (RV_MALLOC_FAILED); }
pOutBloc->pData[0] = ABSENT_PARAMETER_CHAR; pOutBloc->pData[1] = (BYTE) AlgoIndex; } } else {
/* Si on a trouv� l'algorithme et il y a des param�tres */ /* On RawEncode non pas le contenu des param�tres mais l'Asn1 entier
car on n'est pas s�r de l'encapsulage */
rv = CC_RawEncode(&(ParametersPart.Asn1), &ParametersAsn1Encoded, TRUE); if (rv != RV_SUCCESS) return rv;
pOutBloc->usLen = 1 + ParametersAsn1Encoded.usLen; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { GMEM_Free(ParametersAsn1Encoded.pData); return (RV_MALLOC_FAILED); }
pOutBloc->pData[0] = (BYTE) AlgoIndex; memcpy(&(pOutBloc->pData[1]), ParametersAsn1Encoded.pData, ParametersAsn1Encoded.usLen);
GMEM_Free(ParametersAsn1Encoded.pData); } } else { /* Si on n'a pas trouv� l'algorithme dans le dictionnaire */ /* On RawEncode le contenu de AlgorithmIdentifier c'est � dire la
concat�nation du asn1 de AlgorithmPart et du asn1 de ParametersPart */
rv = CC_RawEncode(pInBloc, &AlgorithmIdentifierEncoded, TRUE); if (rv != RV_SUCCESS) return rv;
pOutBloc->usLen = 1 + AlgorithmIdentifierEncoded.usLen; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { GMEM_Free(AlgorithmIdentifierEncoded.pData); return (RV_MALLOC_FAILED); }
pOutBloc->pData[0] = ESCAPE_CHAR; memcpy(&(pOutBloc->pData[1]), AlgorithmIdentifierEncoded.pData, AlgorithmIdentifierEncoded.usLen);
GMEM_Free(AlgorithmIdentifierEncoded.pData); }
return (RV_SUCCESS); }
/*******************************************************************************
* int CC_Encode_Name(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode une donn�e de type Name. * Ceci consiste en l'�clatement en ses diff�rents composants, * leurs d�senrobages Asn1 et leurs encodages respectifs, et la * concat�nation de ces r�sultats. * * Remarks : Un octet de contr�le (en d�but du r�sultat) indique le nombre * de RelativeDistinguishedName dont est compos� le Name. * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_Name(BLOC *pInBloc, BLOC *pOutBloc )
{ ASN1 RDN[MAX_RDN]; BLOC RDNEncoded[MAX_RDN]; BYTE *pCurrent; USHORT i, usNbRDN; int rv;
/* D�composition du Name en ses diff�rents RelativeDistinguishedName */
pCurrent = pInBloc->pData; usNbRDN = 0;
while (pCurrent < pInBloc->pData + pInBloc->usLen) { RDN[usNbRDN].Asn1.pData = pCurrent; rv = CC_ExtractContent(&(RDN[usNbRDN])); if (rv != RV_SUCCESS) return rv; pCurrent = RDN[usNbRDN].Content.pData + RDN[usNbRDN].Content.usLen; usNbRDN++; }
ASSERT(pCurrent == pInBloc->pData + pInBloc->usLen);
/* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
for (i = 0; i < usNbRDN; i++) { RDNEncoded[i].pData = NULL; }
pOutBloc->usLen = 1; for (i = 0; i < usNbRDN; i++) { rv = CC_Encode_RDN(&RDN[i].Content, &RDNEncoded[i]); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += RDNEncoded[i].usLen; }
/* Reconstruction � partir des composants */
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
pCurrent = pOutBloc->pData;
*pCurrent = (BYTE) usNbRDN; pCurrent++;
for (i = 0; i < usNbRDN; i++) { memcpy(pCurrent, RDNEncoded[i].pData, RDNEncoded[i].usLen); GMEM_Free(RDNEncoded[i].pData); pCurrent += RDNEncoded[i].usLen; }
return(RV_SUCCESS);
err: for (i = 0; i < usNbRDN; i++) { GMEM_Free(RDNEncoded[i].pData); } return (rv); }
/*******************************************************************************
* int CC_Encode_RDN(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode une donn�e de type RelativeDistinguishedName (RDN). * Ceci consiste en l'�clatement en ses diff�rents composants, * leurs d�senrobages Asn1 et leurs encodages respectifs, et la * concat�nation de ces r�sultats. * * Remarks : Un octet de contr�le (en d�but du r�sultat) indique le nombre * de AttributeValueAssertion dont est compos� le RDN. * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_RDN(BLOC *pInBloc, BLOC *pOutBloc )
{ ASN1 AVA[MAX_AVA]; BLOC AVAEncoded[MAX_AVA]; BYTE *pCurrent; USHORT i, usNbAVA; int rv;
/* D�composition du RDN en ses diff�rents AVA */
pCurrent = pInBloc->pData; usNbAVA = 0;
while (pCurrent < pInBloc->pData + pInBloc->usLen) { AVA[usNbAVA].Asn1.pData = pCurrent; rv = CC_ExtractContent(&(AVA[usNbAVA])); if (rv != RV_SUCCESS) return rv; pCurrent = AVA[usNbAVA].Content.pData + AVA[usNbAVA].Content.usLen; usNbAVA++; }
ASSERT(pCurrent == pInBloc->pData + pInBloc->usLen);
/* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
for (i = 0; i < usNbAVA; i++) { AVAEncoded[i].pData = NULL; }
pOutBloc->usLen = 1; for (i = 0; i < usNbAVA; i++) { rv = CC_Encode_AVA(&AVA[i].Content, &AVAEncoded[i]); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += AVAEncoded[i].usLen; }
/* Reconstruction � partir des composants */
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
pCurrent = pOutBloc->pData;
*pCurrent = (BYTE) usNbAVA; pCurrent++;
for (i = 0; i < usNbAVA; i++) { memcpy(pCurrent, AVAEncoded[i].pData, AVAEncoded[i].usLen); GMEM_Free(AVAEncoded[i].pData); pCurrent += AVAEncoded[i].usLen; }
return(RV_SUCCESS);
err: for (i = 0; i < usNbAVA; i++) { GMEM_Free(AVAEncoded[i].pData); }
return(rv);
}
/*******************************************************************************
* int CC_Encode_AVA(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode une donn�e de type AttributeValueAssertion (AVA). * Ceci consiste en l'�clatement en ses diff�rents composants, * leurs d�senrobages Asn1 et leurs encodages respectifs, et la * concat�nation de ces r�sultats. * * Remarks : On utilise un dictionnaire statique (d�fini au d�but de ce * source) pour remplacer le type d'attribut par un index. * Un octet de contr�le (en d�but du r�sultat) indique, ou bien que * l'on n'a pas trouv� le type d'attribut dans le dico (0xFF) * ou l'index du type d'attribut. * On ne code pas le Content de AttributeValue mais son Asn1 car on * n'est pas s�r du tag employ�. * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_AVA(BLOC *pInBloc, BLOC *pOutBloc )
{ ASN1 AttributeTypePart, AttributeValuePart; BLOC AttributeTypeEncoded, AttributeValueEncoded; BOOL bFound; USHORT Index, AttributeTypeIndex; int rv;
/* D�composition */
AttributeTypePart.Asn1.pData = pInBloc->pData; rv = CC_ExtractContent(&AttributeTypePart); if (rv != RV_SUCCESS) return rv;
AttributeValuePart.Asn1.pData = AttributeTypePart.Content.pData + AttributeTypePart.Content.usLen; rv = CC_ExtractContent(&AttributeValuePart); /* Pas n�cessaire */ if (rv != RV_SUCCESS) return rv;
/* Recherche de l'identifiant de l'AttributeType dans le dictionnaire */
Index = 0; bFound = FALSE; while((bFound == FALSE) && (AttributeTypeDict[Index] != NULL)) { if (!memcmp(AttributeTypeDict[Index], AttributeTypePart.Content.pData, AttributeTypePart.Content.usLen)) { bFound = TRUE; AttributeTypeIndex = Index; } Index++; }
/* Construction de l'encodage */
/* Attention : on encode aussi l'enrobage de AttributeValue ! */
if (bFound == TRUE) { /* Il nous faut la longueur enrobage compris mais cette ligne est-elle
vraiment n�cessaire ? */ AttributeValuePart.Asn1.usLen = (unsigned short) (DWORD)((pInBloc->pData + pInBloc->usLen) - AttributeValuePart.Asn1.pData);
rv = CC_RawEncode(&(AttributeValuePart.Asn1), &AttributeValueEncoded, TRUE); if (rv != RV_SUCCESS) return rv;
pOutBloc->usLen = 1 + AttributeValueEncoded.usLen; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { GMEM_Free(AttributeValueEncoded.pData); return(RV_MALLOC_FAILED); }
pOutBloc->pData[0] = (BYTE) AttributeTypeIndex; memcpy(&(pOutBloc->pData[1]), AttributeValueEncoded.pData, AttributeValueEncoded.usLen);
GMEM_Free(AttributeValueEncoded.pData); } else { /* Si on n'a pas trouv� l'attribut dans le dictionnaire */
rv = CC_RawEncode(&(AttributeTypePart.Content), &AttributeTypeEncoded, TRUE); if (rv != RV_SUCCESS) return rv;
rv = CC_RawEncode(&(AttributeValuePart.Asn1), &AttributeValueEncoded, TRUE); if (rv != RV_SUCCESS) { GMEM_Free(AttributeTypeEncoded.pData); return rv; }
pOutBloc->usLen = 1 + AttributeTypeEncoded.usLen + AttributeValueEncoded.usLen;
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { GMEM_Free(AttributeTypeEncoded.pData); GMEM_Free(AttributeValueEncoded.pData); return(RV_MALLOC_FAILED); }
pOutBloc->pData[0] = ESCAPE_CHAR; memcpy(&(pOutBloc->pData[1]), AttributeTypeEncoded.pData, AttributeTypeEncoded.usLen); memcpy(&(pOutBloc->pData[1 + AttributeTypeEncoded.usLen]), AttributeValueEncoded.pData, AttributeValueEncoded.usLen);
GMEM_Free(AttributeTypeEncoded.pData); GMEM_Free(AttributeValueEncoded.pData); }
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Encode_Validity(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode une donn�e de type Validity. * Ceci consiste en l'�clatement en ses diff�rents composants, * leurs d�senrobages Asn1 et leurs encodages respectifs, et la * concat�nation de ces r�sultats. * * Remarks : Un octet de contr�le (en d�but du r�sultat) indique les formats * des deux parties notBefore et notAfter. * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_Validity(BLOC *pInBloc, BLOC *pOutBloc )
{ ASN1 notBeforePart, notAfterPart; BLOC notBeforeEncoded, notAfterEncoded; BYTE notBeforeFormat, notAfterFormat, *pCurrent; int rv;
/* D�composition */ pCurrent = pInBloc->pData;
notBeforePart.Asn1.pData = pCurrent; rv = CC_ExtractContent(¬BeforePart); if (rv != RV_SUCCESS) return rv; pCurrent = notBeforePart.Content.pData + notBeforePart.Content.usLen;
notAfterPart.Asn1.pData = pCurrent; rv = CC_ExtractContent(¬AfterPart); if (rv != RV_SUCCESS) return rv; pCurrent = notAfterPart.Content.pData + notAfterPart.Content.usLen;
/* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
pOutBloc->usLen = 1;
rv = CC_Encode_UTCTime(¬BeforePart.Content, ¬BeforeEncoded, ¬BeforeFormat); if (rv != RV_SUCCESS) return rv; pOutBloc->usLen += notBeforeEncoded.usLen;
rv = CC_Encode_UTCTime(¬AfterPart.Content, ¬AfterEncoded, ¬AfterFormat); if (rv != RV_SUCCESS) { GMEM_Free(notBeforeEncoded.pData); return rv; } pOutBloc->usLen += notAfterEncoded.usLen;
/* Reconstruction � partir des composants */
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { GMEM_Free(notBeforeEncoded.pData); GMEM_Free(notAfterEncoded.pData); return(RV_MALLOC_FAILED); }
pCurrent = pOutBloc->pData;
*pCurrent = (notBeforeFormat << 4) + notAfterFormat; pCurrent++;
memcpy(pCurrent, notBeforeEncoded.pData, notBeforeEncoded.usLen); GMEM_Free(notBeforeEncoded.pData); pCurrent += notBeforeEncoded.usLen;
memcpy(pCurrent, notAfterEncoded.pData, notAfterEncoded.usLen); GMEM_Free(notAfterEncoded.pData); pCurrent += notAfterEncoded.usLen;
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Encode_UTCTime(BLOC *pInBloc, * BLOC *pOutBloc, * BYTE *pFormat * ) * * Description : Encode une donn�e de type UTCTime. * Suivant le format d�tect�, l'encodage consiste en : * - sur 32 bits : le nombre de minutes ou de secondes depuis une * date de r�f�rence. * - sur 16 bits : le nombre de minutes de d�calage UTC * s'il y a lieu. * * Remarks : * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * pFormat : indique au quel format �tait la donn�e d'entr�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_UTCTime(BLOC *pInBloc, BLOC *pOutBloc, BYTE *pFormat )
{ BYTE *pData; ULONG ulNbMinute, ulNbSecond; USHORT usNbDeltaMinute, usYear, usMonth, usDay, usHour, usMinute, usSecond, usDeltaHour, usDeltaMinute, usDayInYear;
pData = pInBloc->pData;
/* Calcul du nombre de minutes */
usYear = 10 * (pData[0] - '0') + (pData[1] - '0'); usMonth = 10 * (pData[2] - '0') + (pData[3] - '0'); usDay = 10 * (pData[4] - '0') + (pData[5] - '0'); usHour = 10 * (pData[6] - '0') + (pData[7] - '0'); usMinute = 10 * (pData[8] - '0') + (pData[9] - '0');
ASSERT((usYear >= 0) && (usYear <= 99)); ASSERT((usMonth >= 1) && (usMonth <= 12)); ASSERT((usDay >= 1) && (usDay <= 31)); ASSERT((usHour >= 0) && (usHour <= 23)); ASSERT((usMinute >= 0) && (usMinute <= 59));
/* Le nombre de jours dans l'ann�e vaut 0 le 1er janvier */
usDayInYear = NbDaysInMonth[usMonth - 1] + (usDay - 1); if (((usYear % 4) == 0) && (usMonth >= 3)) usDayInYear++;
/* L'ann�e 00 est compt�e bissextile ci-dessous */ /* L'ann�e courante si elle l'est a d�j� �t� compt�e dans usDayInYear */
/*
Probl�me sur l'�valuation de (usYear - 1) / 4 : usYear = 8 -> 1 usYear = 4 -> 0 usYear = 0 -> 0 !!
ulNbMinute = usYear * UTCT_MINUTE_IN_YEAR + (1 + (usYear - 1) / 4) * UTCT_MINUTE_IN_DAY + usDayInYear * UTCT_MINUTE_IN_DAY + usHour * UTCT_MINUTE_IN_HOUR + usMinute; */
ulNbMinute = usYear * UTCT_MINUTE_IN_YEAR + (usYear + 3) / 4 * UTCT_MINUTE_IN_DAY // Ann�es bissextiles
+ usDayInYear * UTCT_MINUTE_IN_DAY + usHour * UTCT_MINUTE_IN_HOUR + usMinute;
/* Le format et la suite des calculs en fonction de la longueur */
switch(pInBloc->usLen) { case 11 : *pFormat = UTCT_YYMMDDhhmmZ;
ASSERT(pData[10] == 'Z');
pOutBloc->usLen = 4; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); } *(ULONG *)pOutBloc->pData = ulNbMinute;
break;
case 13 : *pFormat = UTCT_YYMMDDhhmmssZ;
usSecond = 10 * (pData[10] - '0') + (pData[11] - '0'); ASSERT((usSecond >= 0) && (usSecond <= 59)); ASSERT(pData[12] == 'Z');
ulNbSecond = 60 * ulNbMinute + usSecond; pOutBloc->usLen = 4; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); } *(ULONG *)pOutBloc->pData = ulNbSecond;
break;
case 15 : if (pData[10] == '+') { *pFormat = UTCT_YYMMDDhhmmphhmm; } else if (pData[10] == '-') { *pFormat = UTCT_YYMMDDhhmmmhhmm; } else { return(RV_INVALID_DATA); }
usDeltaHour = 10 * (pData[11] - '0') + (pData[12] - '0'); usDeltaMinute = 10 * (pData[13] - '0') + (pData[14] - '0'); ASSERT((usDeltaHour >= 0) && (usDeltaHour <= 23)); ASSERT((usDeltaMinute >= 0) && (usDeltaMinute <= 59));
usNbDeltaMinute = 60 * usDeltaHour + usDeltaMinute; pOutBloc->usLen = 4 + 2; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); } *(ULONG *)pOutBloc->pData = ulNbMinute; *(USHORT *)(pOutBloc->pData + sizeof(ulNbMinute)) = usNbDeltaMinute;
break;
case 17 : if (pData[12] == '+') { *pFormat = UTCT_YYMMDDhhmmphhmm; } else if (pData[12] == '-') { *pFormat = UTCT_YYMMDDhhmmmhhmm; } else { return(RV_INVALID_DATA); }
usSecond = 10 * (pData[10] - '0') + (pData[11] - '0'); ASSERT((usSecond >= 0) && (usSecond <= 59));
ulNbSecond = 60 * ulNbMinute + usSecond; usDeltaHour = 10 * (pData[13] - '0') + (pData[14] - '0'); usDeltaMinute = 10 * (pData[15] - '0') + (pData[16] - '0'); ASSERT((usDeltaHour >= 0) && (usDeltaHour <= 23)); ASSERT((usDeltaMinute >= 0) && (usDeltaMinute <= 59));
usNbDeltaMinute = 60 * usDeltaHour + usDeltaMinute; pOutBloc->usLen = 4 + 2; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); } *(ULONG *)pOutBloc->pData = ulNbSecond; *(USHORT *)(pOutBloc->pData + sizeof(ulNbSecond)) = usNbDeltaMinute;
break;
default : return(RV_INVALID_DATA); }
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Encode_SubjectPKInfo(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode une donn�e de type SubjectPublicKeyInfo. * Ceci consiste en l'�clatement en ses diff�rents composants, * leurs d�senrobages Asn1 et leurs encodages respectifs, et la * concat�nation de ces r�sultats. * * Remarks : * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_SubjectPKInfo(BLOC *pInBloc, BLOC *pOutBloc )
{ ASN1 algorithmPart, subjectPKPart; BLOC algorithmEncoded, subjectPKEncoded; BYTE // *pData,
*pCurrent; int rv;
/* D�composition du SubjectPKInfo en ses diff�rents composants */ pCurrent = pInBloc->pData;
algorithmPart.Asn1.pData = pCurrent; rv = CC_ExtractContent(&algorithmPart); if (rv != RV_SUCCESS) return rv; pCurrent = algorithmPart.Content.pData + algorithmPart.Content.usLen;
subjectPKPart.Asn1.pData = pCurrent; rv = CC_ExtractContent(&subjectPKPart); if (rv != RV_SUCCESS) return rv; pCurrent = subjectPKPart.Content.pData + subjectPKPart.Content.usLen;
/* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
pOutBloc->usLen = 0;
rv = CC_Encode_AlgorithmIdentifier(&algorithmPart.Content, &algorithmEncoded); if (rv != RV_SUCCESS) return rv; pOutBloc->usLen += algorithmEncoded.usLen;
#ifdef _TRICKY_COMPRESSION
/* Ne pas faire le RawEncode permet de gagner l'octet 0xFF et �ventuellement plus */ #ifdef _OPT_HEADER
if (subjectPKPart.Content.usLen < 0x80) { if ((pData = GMEM_Alloc(pInBloc->usLen + 1)) == NULL_PTR) { return(RV_MALLOC_FAILED); } else { pData[0] = subjectPKPart.Content.usLen; memcpy(&pData[1], subjectPKPart.Content.pData, subjectPKPart.Content.usLen);
subjectPKEncoded.usLen = subjectPKPart.Content.usLen + 1; subjectPKEncoded.pData = pData; } pOutBloc->usLen += subjectPKEncoded.usLen; } else { if ((pData = GMEM_Alloc(pInBloc->usLen + 2)) == NULL_PTR) { return(RV_MALLOC_FAILED); } else { pData[0] = 0x80 | (subjectPKPart.Content.usLen >> 8); pData[1] = subjectPKPart.Content.usLen & 0x00FF; memcpy(&pData[2], subjectPKPart.Content.pData, subjectPKPart.Content.usLen);
subjectPKEncoded.usLen = subjectPKPart.Content.usLen + 2; subjectPKEncoded.pData = pData; } pOutBloc->usLen += subjectPKEncoded.usLen; } #else /* _OPT_HEADER */
if ((pData = GMEM_Alloc(pInBloc->usLen + 2)) == NULL_PTR) { return(RV_MALLOC_FAILED); } else { pData[0] = subjectPKPart.Content.usLen >> 8; pData[1] = subjectPKPart.Content.usLen & 0x00FF; memcpy(&pData[2], subjectPKPart.Content.pData, subjectPKPart.Content.usLen);
subjectPKEncoded.usLen = subjectPKPart.Content.usLen + 2; subjectPKEncoded.pData = pData; } pOutBloc->usLen += subjectPKEncoded.usLen; #endif
#else /* _TRICKY_COMPRESSION */
rv = CC_RawEncode(&subjectPKPart.Content, &subjectPKEncoded, FALSE); if (rv != RV_SUCCESS) { GMEM_Free(algorithmEncoded.pData); return rv; } pOutBloc->usLen += subjectPKEncoded.usLen; #endif
/* Reconstruction � partir des composants */
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { GMEM_Free(algorithmEncoded.pData); GMEM_Free(subjectPKEncoded.pData); return(RV_MALLOC_FAILED); }
pCurrent = pOutBloc->pData;
memcpy(pCurrent, algorithmEncoded.pData, algorithmEncoded.usLen); GMEM_Free(algorithmEncoded.pData); pCurrent += algorithmEncoded.usLen;
memcpy(pCurrent, subjectPKEncoded.pData, subjectPKEncoded.usLen); GMEM_Free(subjectPKEncoded.pData); pCurrent += subjectPKEncoded.usLen;
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Encode_UniqueIdentifier(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode une donn�e de type UniqueIdentifier. * Ceci consiste seulement en l'encodage brute (CC_RawEncode) de la * donn�e d'entr�e. * * Remarks : * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_UniqueIdentifier(BLOC *pInBloc, BLOC *pOutBloc )
{ int rv;
rv = CC_RawEncode(pInBloc, pOutBloc, TRUE); if (rv != RV_SUCCESS) return rv;
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Encode_Extensions(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode une donn�e de type Extensions. * Ceci consiste seulement en l'encodage brute (CC_RawEncode) de la * donn�e d'entr�e. * * Remarks : Un d�senrobage suppl�mentaire (context specific) est requis. * Un octet de contr�le (en d�but du r�sultat) indique le nombre * de Extension dont est compos� le Extensions. * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_Extensions(BLOC *pInBloc, BLOC *pOutBloc )
{ ASN1 ExtensionPart[MAX_EXTENSION], InInAsn1; BLOC ExtensionEncoded[MAX_EXTENSION], *pInInBloc; BYTE *pCurrent; int rv; USHORT i, usNbExtension;
/* On enl�ve l'enrobage 'context specific' suppl�mentaire */ /* et on travaille avec pInInBloc au lieu de pInBloc */
InInAsn1.Asn1.pData = pInBloc->pData; rv = CC_ExtractContent(&InInAsn1); if (rv != RV_SUCCESS) return rv;
pInInBloc = &(InInAsn1.Content);
/* D�composition de Extensions en ses diff�rents Extension */
pCurrent = pInInBloc->pData; usNbExtension = 0;
while (pCurrent < pInInBloc->pData + pInInBloc->usLen) { ExtensionPart[usNbExtension].Asn1.pData = pCurrent; rv = CC_ExtractContent(&(ExtensionPart[usNbExtension])); if (rv != RV_SUCCESS) return rv; pCurrent = ExtensionPart[usNbExtension].Content.pData + ExtensionPart[usNbExtension].Content.usLen; usNbExtension++; }
ASSERT(pCurrent == pInInBloc->pData + pInInBloc->usLen);
/* Encodages des diff�rents composants et calcul de la longueur n�cessaire */
for (i = 0; i < usNbExtension; i++) { ExtensionEncoded[i].pData = NULL; }
pOutBloc->usLen = 1; for (i = 0; i < usNbExtension; i++) { rv = CC_Encode_Extension(&ExtensionPart[i].Content, &ExtensionEncoded[i]); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += ExtensionEncoded[i].usLen; }
/* Reconstruction � partir des composants */
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
pCurrent = pOutBloc->pData;
*pCurrent = (BYTE) usNbExtension; pCurrent++;
for (i = 0; i < usNbExtension; i++) { memcpy(pCurrent, ExtensionEncoded[i].pData, ExtensionEncoded[i].usLen); GMEM_Free(ExtensionEncoded[i].pData); pCurrent += ExtensionEncoded[i].usLen; }
return(RV_SUCCESS);
err: for (i = 0; i < usNbExtension; i++) { GMEM_Free(ExtensionEncoded[i].pData); }
return(rv); }
/*******************************************************************************
* int CC_Encode_Extension(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode une donn�e de type Extension. * Ceci consiste seulement en l'encodage brute (CC_RawEncode) de la * donn�e d'entr�e. * * Remarks : * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_Extension(BLOC *pInBloc, BLOC *pOutBloc )
{ int rv;
rv = CC_RawEncode(pInBloc, pOutBloc, TRUE); if (rv != RV_SUCCESS) return rv;
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Encode_Signature(BLOC *pInBloc, * BLOC *pOutBloc * ) * * Description : Encode la signature du certificat. * Ceci consiste seulement en l'encodage brute (CC_RawEncode) de la * donn�e d'entr�e. * * Remarks : On peut �viter de tenter de compresser (CC_RawEncode) si on * estime que cela ne sera pas efficace (donn�e al�atoire). * Cela permet de gagner un octet (0xFF) pour les donn�es de taille * sup�rieure � 30 octets (cas g�n�ral). * * In : pInBloc : la partie � encoder (champ Content) * * Out : pOutBloc : l'encod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Encode_Signature(BLOC *pInBloc, BLOC *pOutBloc )
{ // BYTE
// *pData;
int rv;
#ifdef _TRICKY_COMPRESSION
/* Ne pas faire le RawEncode permet de gagner l'octet 0xFF */ #ifdef _OPT_HEADER
if (pInBloc->usLen < 0x80) { if ((pData = GMEM_Alloc(pInBloc->usLen + 1)) == NULL_PTR) { return(RV_MALLOC_FAILED); } else { pData[0] = pInBloc->usLen; memcpy(&pData[1], pInBloc->pData, pInBloc->usLen);
pOutBloc->usLen = pInBloc->usLen + 1; pOutBloc->pData = pData; } } else { if ((pData = GMEM_Alloc(pInBloc->usLen + 2)) == NULL_PTR) { return(RV_MALLOC_FAILED); } else { pData[0] = 0x80 | (pInBloc->usLen >> 8); pData[1] = pInBloc->usLen & 0x00FF; memcpy(&pData[2], pInBloc->pData, pInBloc->usLen);
pOutBloc->usLen = pInBloc->usLen + 2; pOutBloc->pData = pData; } } #else /* _OPT_HEADER */
if ((pData = GMEM_Alloc(pInBloc->usLen + 2)) == NULL_PTR) { return(RV_MALLOC_FAILED); } else { pData[0] = pInBloc->usLen >> 8; pData[1] = pInBloc->usLen & 0x00FF; memcpy(&pData[2], pInBloc->pData, pInBloc->usLen);
pOutBloc->usLen = pInBloc->usLen + 2; pOutBloc->pData = pData; } #endif
#else /* _TRICKY_COMPRESSION */
rv = CC_RawEncode(pInBloc, pOutBloc, TRUE); if (rv != RV_SUCCESS) return rv; #endif
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Decode_TBSCertificate(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type TBSCertificate. * Ceci consiste en le d�codage des diff�rentes parties encod�es * successives, leurs enrobages respectifs (tags uniquement * par la spec X.509), et la concat�nation de ces r�sultats. * * Remarks : * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * pLength : la longueur de donn�es encod�s utilis�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_TBSCertificate(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ ASN1 serialNumberPart, signaturePart, issuerPart, validityPart, subjectPart, subjectPKInfoPart, issuerUIDPart, subjectUIDPart, extensionsPart; BOOL bVersionPresent, bIssuerUIDPresent, bSubjectUIDPresent, bExtensionsPresent; BYTE *pCurrent; int rv; USHORT usVersion = 0, Length;
serialNumberPart.Asn1.pData = NULL; signaturePart.Asn1.pData = NULL; issuerPart.Asn1.pData = NULL; validityPart.Asn1.pData = NULL; subjectPart.Asn1.pData = NULL; subjectPKInfoPart.Asn1.pData = NULL; issuerUIDPart.Asn1.pData = NULL; subjectUIDPart.Asn1.pData = NULL; extensionsPart.Asn1.pData = NULL;
pCurrent = pInData; bVersionPresent = ((*pCurrent & 0x80) != 0); bIssuerUIDPresent = ((*pCurrent & 0x40) != 0); bSubjectUIDPresent = ((*pCurrent & 0x20) != 0); bExtensionsPresent = ((*pCurrent & 0x10) != 0); usVersion = *pCurrent & 0x03; pCurrent++;
rv = CC_Decode_CertificateSerialNumber(pCurrent, &(serialNumberPart.Content), &Length); if (rv != RV_SUCCESS) goto err; serialNumberPart.Tag = TAG_INTEGER; rv = CC_BuildAsn1(&serialNumberPart); GMEM_Free(serialNumberPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
rv = CC_Decode_AlgorithmIdentifier(pCurrent, &(signaturePart.Content), &Length); if (rv != RV_SUCCESS) goto err; signaturePart.Tag = TAG_SEQUENCE; rv = CC_BuildAsn1(&signaturePart); GMEM_Free(signaturePart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
rv = CC_Decode_Name(pCurrent, &(issuerPart.Content), &Length); if (rv != RV_SUCCESS) goto err; issuerPart.Tag = TAG_SEQUENCE_OF; rv = CC_BuildAsn1(&issuerPart); GMEM_Free(issuerPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
rv = CC_Decode_Validity(pCurrent, &(validityPart.Content), &Length); if (rv != RV_SUCCESS) goto err; validityPart.Tag = TAG_SEQUENCE; rv = CC_BuildAsn1(&validityPart); GMEM_Free(validityPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
rv = CC_Decode_Name(pCurrent, &(subjectPart.Content), &Length); if (rv != RV_SUCCESS) goto err; subjectPart.Tag = TAG_SEQUENCE_OF; rv = CC_BuildAsn1(&subjectPart); GMEM_Free(subjectPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
rv = CC_Decode_SubjectPKInfo(pCurrent, &(subjectPKInfoPart.Content), &Length); if (rv != RV_SUCCESS) goto err; subjectPKInfoPart.Tag = TAG_SEQUENCE; rv = CC_BuildAsn1(&subjectPKInfoPart); GMEM_Free(subjectPKInfoPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
if (bIssuerUIDPresent == TRUE) { rv = CC_Decode_UniqueIdentifier(pCurrent, &(issuerUIDPart.Content), &Length); if (rv != RV_SUCCESS) goto err; issuerUIDPart.Tag = TAG_OPTION_ISSUER_UID; rv = CC_BuildAsn1(&issuerUIDPart); GMEM_Free(issuerUIDPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length; }
if (bSubjectUIDPresent == TRUE) { rv = CC_Decode_UniqueIdentifier(pCurrent, &(subjectUIDPart.Content), &Length); if (rv != RV_SUCCESS) goto err; subjectUIDPart.Tag = TAG_OPTION_SUBJECT_UID; rv = CC_BuildAsn1(&subjectUIDPart); GMEM_Free(subjectUIDPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length; }
if (bExtensionsPresent == TRUE) { rv = CC_Decode_Extensions(pCurrent, &(extensionsPart.Content), &Length); if (rv != RV_SUCCESS) goto err; extensionsPart.Tag = TAG_OPTION_EXTENSIONS; rv = CC_BuildAsn1(&extensionsPart); GMEM_Free(extensionsPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length; }
*pLength = (unsigned short)(DWORD) (pCurrent - pInData);
/* Calcul de la longueur du tbsCertificate d�cod� et allocation */ pOutBloc->usLen = (bVersionPresent ? 5 : 0) + serialNumberPart.Asn1.usLen + signaturePart.Asn1.usLen + issuerPart.Asn1.usLen + validityPart.Asn1.usLen + subjectPart.Asn1.usLen + subjectPKInfoPart.Asn1.usLen + (bIssuerUIDPresent ? issuerUIDPart.Asn1.usLen : 0) + (bSubjectUIDPresent ? subjectUIDPart.Asn1.usLen : 0) + (bExtensionsPresent ? extensionsPart.Asn1.usLen : 0);
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
/* Reconstruction du tbsCertificate d�cod� */ pCurrent = pOutBloc->pData;
if (bVersionPresent == TRUE) { pCurrent[0] = TAG_OPTION_VERSION; pCurrent[1] = 0x03; pCurrent[2] = 0x02; pCurrent[3] = 0x01; pCurrent[4] = (BYTE)usVersion; pCurrent += 5; }
memcpy(pCurrent, serialNumberPart.Asn1.pData, serialNumberPart.Asn1.usLen); GMEM_Free(serialNumberPart.Asn1.pData); pCurrent += serialNumberPart.Asn1.usLen;
memcpy(pCurrent, signaturePart.Asn1.pData, signaturePart.Asn1.usLen); GMEM_Free(signaturePart.Asn1.pData); pCurrent += signaturePart.Asn1.usLen;
memcpy(pCurrent, issuerPart.Asn1.pData, issuerPart.Asn1.usLen); GMEM_Free(issuerPart.Asn1.pData); pCurrent += issuerPart.Asn1.usLen;
memcpy(pCurrent, validityPart.Asn1.pData, validityPart.Asn1.usLen); GMEM_Free(validityPart.Asn1.pData); pCurrent += validityPart.Asn1.usLen;
memcpy(pCurrent, subjectPart.Asn1.pData, subjectPart.Asn1.usLen); GMEM_Free(subjectPart.Asn1.pData); pCurrent += subjectPart.Asn1.usLen;
memcpy(pCurrent, subjectPKInfoPart.Asn1.pData, subjectPKInfoPart.Asn1.usLen); GMEM_Free(subjectPKInfoPart.Asn1.pData); pCurrent += subjectPKInfoPart.Asn1.usLen;
if (bIssuerUIDPresent == TRUE) { memcpy(pCurrent, issuerUIDPart.Asn1.pData, issuerUIDPart.Asn1.usLen); GMEM_Free(issuerUIDPart.Asn1.pData); pCurrent += issuerUIDPart.Asn1.usLen; }
if (bSubjectUIDPresent == TRUE) { memcpy(pCurrent, subjectUIDPart.Asn1.pData, subjectUIDPart.Asn1.usLen); GMEM_Free(subjectUIDPart.Asn1.pData); pCurrent += subjectUIDPart.Asn1.usLen; }
if (bExtensionsPresent == TRUE) { memcpy(pCurrent, extensionsPart.Asn1.pData, extensionsPart.Asn1.usLen); GMEM_Free(extensionsPart.Asn1.pData); pCurrent += extensionsPart.Asn1.usLen; }
return(RV_SUCCESS);
err: GMEM_Free(serialNumberPart.Asn1.pData); GMEM_Free(signaturePart.Asn1.pData); GMEM_Free(issuerPart.Asn1.pData); GMEM_Free(validityPart.Asn1.pData); GMEM_Free(subjectPart.Asn1.pData); GMEM_Free(subjectPKInfoPart.Asn1.pData); GMEM_Free(issuerUIDPart.Asn1.pData); GMEM_Free(subjectUIDPart.Asn1.pData); GMEM_Free(extensionsPart.Asn1.pData);
return (rv); }
/*******************************************************************************
* int CC_Decode_CertificateSerialNumber(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type CertificateSerialNumber. * Ceci consiste seulement en le d�codage brute (CC_RawDecode) de * la donn�e d'entr�e. * * Remarks : * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * pLength : la longueur de donn�es encod�s utilis�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_CertificateSerialNumber(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ int rv;
rv = CC_RawDecode(pInData, pOutBloc, pLength, TRUE); if (rv != RV_SUCCESS) return rv;
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Decode_AlgorithmIdentifier(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type AlgorithmIdentifier. * Ceci consiste en le d�codage des diff�rentes parties encod�es * successives, leurs enrobages respectifs (tags uniquement * par la spec X.509), et la concat�nation de ces r�sultats. * * Remarks : Voir l'encodage * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * pLength : la longueur de donn�es encod�s utilis�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_AlgorithmIdentifier(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ ASN1 AlgorithmPart, ParametersPart; BOOL bNullParam = FALSE, bNoParam = FALSE; int rv; USHORT AlgoIndex, Length;
AlgorithmPart.Asn1.pData = NULL; ParametersPart.Asn1.pData = NULL;
if (pInData[0] == ESCAPE_CHAR) { rv = CC_RawDecode(&pInData[1], pOutBloc, &Length, TRUE); *pLength = 1 + Length; } else { if (pInData[0] == ABSENT_PARAMETER_CHAR) { bNoParam = TRUE; bNullParam = FALSE; AlgoIndex = pInData[1]; } else { bNoParam = ((pInData[0] & 0x80) != 0); bNullParam = bNoParam; AlgoIndex = pInData[0] & 0x7F; }
if (bNoParam == TRUE) { AlgorithmPart.Content.usLen = (USHORT)strlen(AlgorithmTypeDict[AlgoIndex]); if ((AlgorithmPart.Content.pData = GMEM_Alloc(AlgorithmPart.Content.usLen)) == NULL_PTR) { return (RV_MALLOC_FAILED); } memcpy(AlgorithmPart.Content.pData, AlgorithmTypeDict[AlgoIndex], AlgorithmPart.Content.usLen);
AlgorithmPart.Tag = TAG_OBJECT_IDENTIFIER; rv = CC_BuildAsn1(&AlgorithmPart); GMEM_Free(AlgorithmPart.Content.pData); if (rv != RV_SUCCESS) goto err;
if (bNullParam == FALSE) { pOutBloc->usLen = AlgorithmPart.Asn1.usLen; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
memcpy(pOutBloc->pData, AlgorithmPart.Asn1.pData, AlgorithmPart.Asn1.usLen);
*pLength = 2;
GMEM_Free(AlgorithmPart.Asn1.pData); } else { pOutBloc->usLen = AlgorithmPart.Asn1.usLen + 2; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
memcpy(pOutBloc->pData, AlgorithmPart.Asn1.pData, AlgorithmPart.Asn1.usLen);
pOutBloc->pData[AlgorithmPart.Asn1.usLen] = 0x05; pOutBloc->pData[AlgorithmPart.Asn1.usLen+1] = 0x00;
*pLength = 1;
GMEM_Free(AlgorithmPart.Asn1.pData);
} } else { AlgorithmPart.Content.usLen = (USHORT)strlen(AlgorithmTypeDict[AlgoIndex]); if ((AlgorithmPart.Content.pData = GMEM_Alloc(AlgorithmPart.Content.usLen)) == NULL_PTR) { return (RV_MALLOC_FAILED); } memcpy(AlgorithmPart.Content.pData, AlgorithmTypeDict[AlgoIndex], AlgorithmPart.Content.usLen);
AlgorithmPart.Tag = TAG_OBJECT_IDENTIFIER; rv = CC_BuildAsn1(&AlgorithmPart); GMEM_Free(AlgorithmPart.Content.pData); if (rv != RV_SUCCESS) goto err;
/* On recup�re directement l'asn1 des param�tres */ rv = CC_RawDecode(&pInData[1], &(ParametersPart.Asn1), &Length, TRUE); if (rv != RV_SUCCESS) goto err;
pOutBloc->usLen = AlgorithmPart.Asn1.usLen + ParametersPart.Asn1.usLen; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; } memcpy(pOutBloc->pData, AlgorithmPart.Asn1.pData, AlgorithmPart.Asn1.usLen); memcpy(pOutBloc->pData + AlgorithmPart.Asn1.usLen, ParametersPart.Asn1.pData, ParametersPart.Asn1.usLen);
*pLength = 1 + Length;
GMEM_Free(AlgorithmPart.Asn1.pData); GMEM_Free(ParametersPart.Asn1.pData); } }
return (RV_SUCCESS);
err: GMEM_Free(AlgorithmPart.Asn1.pData); GMEM_Free(ParametersPart.Asn1.pData);
return rv; }
/*******************************************************************************
* int CC_Decode_Name(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type Name. * Ceci consiste en le d�codage des diff�rentes parties encod�es * successives, leurs enrobages respectifs (tags uniquement * par la spec X.509), et la concat�nation de ces r�sultats. * * Remarks : Voir l'encodage * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * pLength : la longueur de donn�es encod�s utilis�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_Name(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ ASN1 RDN[MAX_RDN]; BYTE *pCurrent; int rv; USHORT i, usNbRDN, Length;
/* D�codage des diff�rents composants et calcul de la longueur n�cessaire */
pCurrent = pInData; pOutBloc->usLen = 0; usNbRDN = (USHORT) *pCurrent; pCurrent++; for (i = 0; i < usNbRDN; i++) { RDN[i].Asn1.pData = NULL; }
for (i = 0; i < usNbRDN; i++) { rv = CC_Decode_RDN(pCurrent, &(RDN[i].Content), &Length); if (rv != RV_SUCCESS) goto err; RDN[i].Tag = TAG_SET_OF; rv = CC_BuildAsn1(&RDN[i]); GMEM_Free(RDN[i].Content.pData); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += RDN[i].Asn1.usLen; pCurrent += Length; }
*pLength = (unsigned short)(DWORD) (pCurrent - pInData);
/* Reconstruction du Name d�cod� */ if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
pCurrent = pOutBloc->pData;
for (i = 0; i < usNbRDN; i++) { memcpy(pCurrent, RDN[i].Asn1.pData, RDN[i].Asn1.usLen); GMEM_Free(RDN[i].Asn1.pData); pCurrent += RDN[i].Asn1.usLen; }
return(RV_SUCCESS);
err: for (i = 0; i < usNbRDN; i++) { GMEM_Free(RDN[i].Asn1.pData); }
return rv; }
/*******************************************************************************
* int CC_Decode_RDN(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type RelativeDistinguishedName. * Ceci consiste en le d�codage des diff�rentes parties encod�es * successives, leurs enrobages respectifs (tags uniquement * par la spec X.509), et la concat�nation de ces r�sultats. * * Remarks : Voir l'encodage * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * pLength : la longueur de donn�es encod�s utilis�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_RDN(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ ASN1 AVA[MAX_AVA]; BYTE *pCurrent; int rv; USHORT i, usNbAVA, Length;
/* D�codage des diff�rents composants et calcul de la longueur n�cessaire */
pCurrent = pInData; pOutBloc->usLen = 0; usNbAVA = *pCurrent; pCurrent++; for (i = 0; i < usNbAVA; i++) { AVA[i].Asn1.pData = NULL; } for (i = 0; i < usNbAVA; i++) { rv = CC_Decode_AVA(pCurrent, &(AVA[i].Content), &Length); if (rv != RV_SUCCESS) goto err; AVA[i].Tag = TAG_SEQUENCE; rv = CC_BuildAsn1(&AVA[i]); GMEM_Free(AVA[i].Content.pData); if (rv != RV_SUCCESS) goto err; pOutBloc->usLen += AVA[i].Asn1.usLen; pCurrent += Length; }
*pLength = (unsigned short)(DWORD) (pCurrent - pInData);
/* Reconstruction du Name d�cod� */ if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
pCurrent = pOutBloc->pData;
for (i = 0; i < usNbAVA; i++) { memcpy(pCurrent, AVA[i].Asn1.pData, AVA[i].Asn1.usLen); GMEM_Free(AVA[i].Asn1.pData); pCurrent += AVA[i].Asn1.usLen; }
return(RV_SUCCESS);
err: for (i = 0; i < usNbAVA; i++) { GMEM_Free(AVA[i].Asn1.pData); }
return rv; }
/*******************************************************************************
* int CC_Decode_AVA(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type AttributeValueAssertion. * Ceci consiste en le d�codage des diff�rentes parties encod�es * successives, leurs enrobages respectifs (tags uniquement * par la spec X.509), et la concat�nation de ces r�sultats. * * Remarks : Voir l'encodage * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * pLength : la longueur de donn�es encod�s utilis�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_AVA(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ ASN1 AttributeTypePart, AttributeValuePart; BYTE *pCurrent; int rv; USHORT AttributeTypeIndex, Length;
AttributeTypePart.Asn1.pData = NULL; AttributeValuePart.Asn1.pData = NULL; if (pInData[0] == ESCAPE_CHAR) { pCurrent = &pInData[1];
rv = CC_RawDecode(pCurrent, &(AttributeTypePart.Content), &Length, TRUE); if (rv != RV_SUCCESS) goto err; AttributeTypePart.Tag = TAG_OBJECT_IDENTIFIER; rv = CC_BuildAsn1(&AttributeTypePart); GMEM_Free(AttributeTypePart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
/* Ce que l'on d�code contient d�j� l'enrobage */ rv = CC_RawDecode(pCurrent, &(AttributeValuePart.Asn1), &Length, TRUE); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
*pLength = (unsigned short)(DWORD) (pCurrent - pInData);
pOutBloc->usLen = AttributeTypePart.Asn1.usLen + AttributeValuePart.Asn1.usLen;
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
pCurrent = pOutBloc->pData;
memcpy(pCurrent, AttributeTypePart.Asn1.pData, AttributeTypePart.Asn1.usLen); GMEM_Free(AttributeTypePart.Asn1.pData); pCurrent += AttributeTypePart.Asn1.usLen;
memcpy(pCurrent, AttributeValuePart.Asn1.pData, AttributeValuePart.Asn1.usLen); GMEM_Free(AttributeValuePart.Asn1.pData); pCurrent += AttributeValuePart.Asn1.usLen; } else { AttributeTypeIndex = pInData[0];
AttributeTypePart.Content.usLen = (USHORT)strlen(AttributeTypeDict[AttributeTypeIndex]); if ((AttributeTypePart.Content.pData = GMEM_Alloc(AttributeTypePart.Content.usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; } memcpy(AttributeTypePart.Content.pData, AttributeTypeDict[AttributeTypeIndex], AttributeTypePart.Content.usLen);
AttributeTypePart.Tag = TAG_OBJECT_IDENTIFIER; rv = CC_BuildAsn1(&AttributeTypePart); GMEM_Free(AttributeTypePart.Content.pData); if (rv != RV_SUCCESS) goto err;
rv = CC_RawDecode(&pInData[1], &(AttributeValuePart.Asn1), &Length, TRUE); if (rv != RV_SUCCESS) goto err;
pOutBloc->usLen = AttributeTypePart.Asn1.usLen + AttributeValuePart.Asn1.usLen;
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
pCurrent = pOutBloc->pData;
memcpy(pCurrent, AttributeTypePart.Asn1.pData, AttributeTypePart.Asn1.usLen); GMEM_Free(AttributeTypePart.Asn1.pData); pCurrent += AttributeTypePart.Asn1.usLen;
memcpy(pCurrent, AttributeValuePart.Asn1.pData, AttributeValuePart.Asn1.usLen); GMEM_Free(AttributeValuePart.Asn1.pData); pCurrent += AttributeValuePart.Asn1.usLen;
*pLength = 1 + Length; } return(RV_SUCCESS);
err: GMEM_Free(AttributeTypePart.Asn1.pData); GMEM_Free(AttributeValuePart.Asn1.pData);
return rv; }
/*******************************************************************************
* int CC_Decode_Validity(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type Validity. * Ceci consiste en le d�codage des diff�rentes parties encod�es * successives, leurs enrobages respectifs (tags uniquement * par la spec X.509), et la concat�nation de ces r�sultats. * * Remarks : Voir l'encodage * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * pLength : la longueur de donn�es encod�s utilis�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_Validity(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ ASN1 notBeforePart, notAfterPart; BYTE notBeforeFormat, notAfterFormat, *pCurrent; int rv; USHORT Length;
notBeforePart.Asn1.pData = NULL; notAfterPart.Asn1.pData = NULL;
pCurrent = pInData;
notBeforeFormat = (*pCurrent & 0xF0) >> 4; notAfterFormat = *pCurrent & 0x0F; pCurrent++;
rv = CC_Decode_UTCTime(pCurrent, notBeforeFormat, &(notBeforePart.Content), &Length); if (rv != RV_SUCCESS) goto err; notBeforePart.Tag = TAG_UTCT; rv = CC_BuildAsn1(¬BeforePart); GMEM_Free(notBeforePart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
rv = CC_Decode_UTCTime(pCurrent, notAfterFormat, &(notAfterPart.Content), &Length); if (rv != RV_SUCCESS) goto err; notAfterPart.Tag = TAG_UTCT; rv = CC_BuildAsn1(¬AfterPart); GMEM_Free(notAfterPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
*pLength = (unsigned short)(DWORD) (pCurrent - pInData);
/* Calcul de la longueur de Validity d�cod� et allocation */ pOutBloc->usLen = notBeforePart.Asn1.usLen + notAfterPart.Asn1.usLen;
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
/* Reconstruction de Validity d�cod� */ pCurrent = pOutBloc->pData;
memcpy(pCurrent, notBeforePart.Asn1.pData, notBeforePart.Asn1.usLen); GMEM_Free(notBeforePart.Asn1.pData); pCurrent += notBeforePart.Asn1.usLen;
memcpy(pCurrent, notAfterPart.Asn1.pData, notAfterPart.Asn1.usLen); GMEM_Free(notAfterPart.Asn1.pData); pCurrent += notAfterPart.Asn1.usLen;
return(RV_SUCCESS);
err: GMEM_Free(notBeforePart.Asn1.pData); GMEM_Free(notAfterPart.Asn1.pData);
return rv; }
/*******************************************************************************
* int CC_Decode_UTCTime(BYTE *pInData, * BYTE Format, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type UTCTime. * Ceci consiste en la reconstruction de la chaine initiale suivant * le format au quel elle �tait exprim�e. * * Remarks : Voir l'encodage * * In : pInBloc : la partie � d�coder (champ Content) * Format : indique au quel format �tait la donn�e d'entr�e * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * pLength : la longueur de donn�es encod�s utilis�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * RV_INVALID_DATA : Le format sp�cifi� en entr�e est invalide. * *******************************************************************************/ int CC_Decode_UTCTime(BYTE *pInData, BYTE Format, BLOC *pOutBloc, USHORT *pLength )
{ BOOL bBissextile = FALSE; BYTE *pCurrent; ULONG ulTime, ulNbHour, ulNbMinute; USHORT usNbDeltaMinute, usNbDay, usNbFourYears, usNbDayInYear, usYear, usMonth, usDay, usHour, usMinute, usSecond, usDeltaHour, usDeltaMinute;
ulTime = *(ULONG UNALIGNED *)pInData; //memcpy( &ulTime, (ULONG *) &pInData[0],4);
switch(Format) { case UTCT_YYMMDDhhmmssZ : case UTCT_YYMMDDhhmmssphhmm : case UTCT_YYMMDDhhmmssmhhmm :
usSecond = (USHORT) (ulTime % 60); ulNbMinute = ulTime / 60;
break;
default :
ulNbMinute = ulTime;
break; }
switch(Format) { case UTCT_YYMMDDhhmmphhmm : case UTCT_YYMMDDhhmmmhhmm : case UTCT_YYMMDDhhmmssphhmm : case UTCT_YYMMDDhhmmssmhhmm :
*pLength = 6;
usNbDeltaMinute = *(USHORT UNALIGNED *)&pInData[4]; //memcpy(&usNbDeltaMinute, (USHORT *) &pInData[4], 2);
ASSERT((usNbDeltaMinute >= 0) && (usNbDeltaMinute < 3600));
usDeltaMinute = usNbDeltaMinute % 60; usDeltaHour = usNbDeltaMinute / 60;
break;
default :
*pLength = 4;
break; }
usMinute = (USHORT) (ulNbMinute % 60); ulNbHour = ulNbMinute / 60;
usHour = (USHORT) (ulNbHour % 24); usNbDay = (USHORT) (ulNbHour / 24);
usNbFourYears = usNbDay / 1461; usNbDay = usNbDay % 1461; usYear = 4 * usNbFourYears;
if ((usNbDay >= 0) && (usNbDay <= 365)) { bBissextile = TRUE; usNbDayInYear = usNbDay; } if ((usNbDay >= 366) && (usNbDay <= 730)) { usYear += 1; usNbDayInYear = usNbDay - 366; } if ((usNbDay >= 731) && (usNbDay <= 1095)) { usYear += 2; usNbDayInYear = usNbDay - 731; } if ((usNbDay >= 1096) && (usNbDay <= 1460)) { usYear += 3; usNbDayInYear = usNbDay - 1096; }
usMonth = 1; while (usNbDayInYear >= (((usMonth >= 2) && (bBissextile)) ? NbDaysInMonth[usMonth] + 1 : NbDaysInMonth[usMonth])) { usMonth++; }
usDay = usNbDayInYear - (((usMonth - 1 >= 2) && (bBissextile)) ? NbDaysInMonth[usMonth - 1] + 1 : NbDaysInMonth[usMonth - 1]) + 1; switch(Format) { case UTCT_YYMMDDhhmmZ :
pOutBloc->usLen = 11;
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); }
pCurrent = pOutBloc->pData;
*pCurrent++ = '0' + usYear / 10; *pCurrent++ = '0' + usYear % 10; *pCurrent++ = '0' + usMonth / 10; *pCurrent++ = '0' + usMonth % 10; *pCurrent++ = '0' + usDay / 10; *pCurrent++ = '0' + usDay % 10; *pCurrent++ = '0' + usHour / 10; *pCurrent++ = '0' + usHour % 10; *pCurrent++ = '0' + usMinute / 10; *pCurrent++ = '0' + usMinute % 10; *pCurrent = 'Z';
break;
case UTCT_YYMMDDhhmmphhmm :
pOutBloc->usLen = 15;
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); }
pCurrent = pOutBloc->pData;
*pCurrent++ = '0' + usYear / 10; *pCurrent++ = '0' + usYear % 10; *pCurrent++ = '0' + usMonth / 10; *pCurrent++ = '0' + usMonth % 10; *pCurrent++ = '0' + usDay / 10; *pCurrent++ = '0' + usDay % 10; *pCurrent++ = '0' + usHour / 10; *pCurrent++ = '0' + usHour % 10; *pCurrent++ = '0' + usMinute / 10; *pCurrent++ = '0' + usMinute % 10; *pCurrent++ = '+'; *pCurrent++ = '0' + usDeltaHour / 10; *pCurrent++ = '0' + usDeltaHour % 10; *pCurrent++ = '0' + usDeltaMinute / 10; *pCurrent++ = '0' + usDeltaMinute % 10;
break;
case UTCT_YYMMDDhhmmmhhmm :
pOutBloc->usLen = 15;
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); }
pCurrent = pOutBloc->pData;
*pCurrent++ = '0' + usYear / 10; *pCurrent++ = '0' + usYear % 10; *pCurrent++ = '0' + usMonth / 10; *pCurrent++ = '0' + usMonth % 10; *pCurrent++ = '0' + usDay / 10; *pCurrent++ = '0' + usDay % 10; *pCurrent++ = '0' + usHour / 10; *pCurrent++ = '0' + usHour % 10; *pCurrent++ = '0' + usMinute / 10; *pCurrent++ = '0' + usMinute % 10; *pCurrent++ = '-'; *pCurrent++ = '0' + usDeltaHour / 10; *pCurrent++ = '0' + usDeltaHour % 10; *pCurrent++ = '0' + usDeltaMinute / 10; *pCurrent++ = '0' + usDeltaMinute % 10;
break;
case UTCT_YYMMDDhhmmssZ :
pOutBloc->usLen = 13;
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); }
pCurrent = pOutBloc->pData;
*pCurrent++ = '0' + usYear / 10; *pCurrent++ = '0' + usYear % 10; *pCurrent++ = '0' + usMonth / 10; *pCurrent++ = '0' + usMonth % 10; *pCurrent++ = '0' + usDay / 10; *pCurrent++ = '0' + usDay % 10; *pCurrent++ = '0' + usHour / 10; *pCurrent++ = '0' + usHour % 10; *pCurrent++ = '0' + usMinute / 10; *pCurrent++ = '0' + usMinute % 10; *pCurrent++ = '0' + usSecond / 10; *pCurrent++ = '0' + usSecond % 10; *pCurrent++ = 'Z';
break;
case UTCT_YYMMDDhhmmssphhmm :
pOutBloc->usLen = 17;
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); }
pCurrent = pOutBloc->pData;
*pCurrent++ = '0' + usYear / 10; *pCurrent++ = '0' + usYear % 10; *pCurrent++ = '0' + usMonth / 10; *pCurrent++ = '0' + usMonth % 10; *pCurrent++ = '0' + usDay / 10; *pCurrent++ = '0' + usDay % 10; *pCurrent++ = '0' + usHour / 10; *pCurrent++ = '0' + usHour % 10; *pCurrent++ = '0' + usMinute / 10; *pCurrent++ = '0' + usMinute % 10; *pCurrent++ = '0' + usSecond / 10; *pCurrent++ = '0' + usSecond % 10; *pCurrent++ = '+'; *pCurrent++ = '0' + usDeltaHour / 10; *pCurrent++ = '0' + usDeltaHour % 10; *pCurrent++ = '0' + usDeltaMinute / 10; *pCurrent++ = '0' + usDeltaMinute % 10;
break;
case UTCT_YYMMDDhhmmssmhhmm :
pOutBloc->usLen = 17;
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); }
pCurrent = pOutBloc->pData;
*pCurrent++ = '0' + usYear / 10; *pCurrent++ = '0' + usYear % 10; *pCurrent++ = '0' + usMonth / 10; *pCurrent++ = '0' + usMonth % 10; *pCurrent++ = '0' + usDay / 10; *pCurrent++ = '0' + usDay % 10; *pCurrent++ = '0' + usHour / 10; *pCurrent++ = '0' + usHour % 10; *pCurrent++ = '0' + usMinute / 10; *pCurrent++ = '0' + usMinute % 10; *pCurrent++ = '0' + usSecond / 10; *pCurrent++ = '0' + usSecond % 10; *pCurrent++ = '-'; *pCurrent++ = '0' + usDeltaHour / 10; *pCurrent++ = '0' + usDeltaHour % 10; *pCurrent++ = '0' + usDeltaMinute / 10; *pCurrent++ = '0' + usDeltaMinute % 10;
break;
default :
return(RV_INVALID_DATA);
break; }
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Decode_SubjectPKInfo(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type SubjectPublicKeyInfo. * Ceci consiste en le d�codage des diff�rentes parties encod�es * successives, leurs enrobages respectifs (tags uniquement * par la spec X.509), et la concat�nation de ces r�sultats. * * Remarks : Voir l'encodage * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * pLength : la longueur de donn�es encod�s utilis�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_SubjectPKInfo(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ ASN1 algorithmPart, subjectPKPart; // BLOC
// CompData;
BYTE *pCurrent; int rv; USHORT Length;
algorithmPart.Asn1.pData = NULL; subjectPKPart.Asn1.pData = NULL;
pCurrent = pInData; rv = CC_Decode_AlgorithmIdentifier(pCurrent, &(algorithmPart.Content), &Length); if (rv != RV_SUCCESS) goto err; algorithmPart.Tag = TAG_SEQUENCE; rv = CC_BuildAsn1(&algorithmPart); GMEM_Free(algorithmPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length;
#ifdef _TRICKY_COMPRESSION
/* Ne pas faire le RawDecode a permis de gagner l'octet 0xFF */ #ifdef _OPT_HEADER
if (pCurrent[0] < 0x80) { CompData.usLen = pCurrent[0]; CompData.pData = &(pCurrent[1]); Length = CompData.usLen + 1; } else { CompData.usLen = ((pCurrent[0] & 0x7F) << 8) + pCurrent[1]; CompData.pData = &(pCurrent[2]); Length = CompData.usLen + 2; } #else /* _OPT_HEADER */
CompData.usLen = (pCurrent[0] << 8) + pCurrent[1]; CompData.pData = &(pCurrent[2]); Length = CompData.usLen + 2; #endif
subjectPKPart.Content.usLen = CompData.usLen; if ((subjectPKPart.Content.pData = GMEM_Alloc(subjectPKPart.Content.usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; } memcpy(subjectPKPart.Content.pData, CompData.pData, subjectPKPart.Content.usLen );
subjectPKPart.Tag = TAG_BIT_STRING; rv = CC_BuildAsn1(&subjectPKPart); GMEM_Free(subjectPKPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length; #else /* _TRICKY_COMPRESSION */
rv = CC_RawDecode(pCurrent, &(subjectPKPart.Content), &Length, FALSE); if (rv != RV_SUCCESS) goto err; subjectPKPart.Tag = TAG_BIT_STRING; rv = CC_BuildAsn1(&subjectPKPart); GMEM_Free(subjectPKPart.Content.pData); if (rv != RV_SUCCESS) goto err; pCurrent += Length; #endif
*pLength = (unsigned short)(DWORD) (pCurrent - pInData);
/* Calcul de la longueur du d�cod� et allocation */ pOutBloc->usLen = algorithmPart.Asn1.usLen + subjectPKPart.Asn1.usLen;
if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
/* Reconstruction */ pCurrent = pOutBloc->pData;
memcpy(pCurrent, algorithmPart.Asn1.pData, algorithmPart.Asn1.usLen); GMEM_Free(algorithmPart.Asn1.pData); pCurrent += algorithmPart.Asn1.usLen;
memcpy(pCurrent, subjectPKPart.Asn1.pData, subjectPKPart.Asn1.usLen); GMEM_Free(subjectPKPart.Asn1.pData); pCurrent += subjectPKPart.Asn1.usLen;
return(RV_SUCCESS);
err: GMEM_Free(algorithmPart.Asn1.pData); GMEM_Free(subjectPKPart.Asn1.pData);
return rv; }
/*******************************************************************************
* int CC_Decode_UniqueIdentifier(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type UniqueIdentifier. * Ceci consiste seulement en le d�codage brute (CC_RawDecode) de * la donn�e d'entr�e. * * Remarks : * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_UniqueIdentifier(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ int rv;
rv = CC_RawDecode(pInData, pOutBloc, pLength, TRUE); if (rv != RV_SUCCESS) return rv;
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Decode_Extensions(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type Extensions. * Ceci consiste en le d�codage des diff�rentes parties encod�es * successives, leurs enrobages respectifs (tags uniquement * par la spec X.509), et la concat�nation de ces r�sultats. * * Remarks : Voir l'encodage * L'ajout d'un enrobage 'context sp�cifique' est requis * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * pLength : la longueur de donn�es encod�s utilis�e * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_Extensions(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ ASN1 ExtensionPart[MAX_AVA], InOutAsn1; BYTE *pCurrent; int rv; USHORT i, usNbExtension, Length;
/* D�codage des diff�rents composants et calcul de la longueur n�cessaire */
pCurrent = pInData; InOutAsn1.Content.usLen = 0; usNbExtension = *pCurrent; pCurrent++;
for (i = 0; i < usNbExtension; i++) { ExtensionPart[i].Asn1.pData = NULL; }
for (i = 0; i < usNbExtension; i++) { rv = CC_Decode_Extension(pCurrent, &(ExtensionPart[i].Content), &Length); if (rv != RV_SUCCESS) goto err; ExtensionPart[i].Tag = TAG_SEQUENCE; rv = CC_BuildAsn1(&ExtensionPart[i]); GMEM_Free(ExtensionPart[i].Content.pData); if (rv != RV_SUCCESS) goto err; InOutAsn1.Content.usLen += ExtensionPart[i].Asn1.usLen; pCurrent += Length; }
*pLength = (unsigned short)(DWORD) (pCurrent - pInData);
/* Reconstruction de la partie int�rieure au 'context specific' */ if ((InOutAsn1.Content.pData = GMEM_Alloc(InOutAsn1.Content.usLen)) == NULL_PTR) { rv = RV_MALLOC_FAILED; goto err; }
pCurrent = InOutAsn1.Content.pData;
for (i = 0; i < usNbExtension; i++) { memcpy(pCurrent, ExtensionPart[i].Asn1.pData, ExtensionPart[i].Asn1.usLen); GMEM_Free(ExtensionPart[i].Asn1.pData); pCurrent += ExtensionPart[i].Asn1.usLen; }
/* Ajout de l'enrobage 'context specific' */
InOutAsn1.Tag = TAG_SEQUENCE; rv = CC_BuildAsn1(&InOutAsn1); GMEM_Free(InOutAsn1.Content.pData); if (rv != RV_SUCCESS) return rv;
*pOutBloc = InOutAsn1.Asn1; return(RV_SUCCESS);
err: for (i = 0; i < usNbExtension; i++) { GMEM_Free(ExtensionPart[i].Asn1.pData); }
return rv; }
/*******************************************************************************
* int CC_Decode_Extension(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code une donn�e de type Extension. * Ceci consiste seulement en le d�codage brute (CC_RawDecode) de * la donn�e d'entr�e. * * Remarks : * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_Extension(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ int rv;
rv = CC_RawDecode(pInData, pOutBloc, pLength, TRUE); if (rv != RV_SUCCESS) return rv;
return(RV_SUCCESS); }
/*******************************************************************************
* int CC_Decode_Signature(BYTE *pInData, * BLOC *pOutBloc, * USHORT *pLength * ) * * Description : D�code la signature du certificat. * Ceci consiste seulement en le d�codage brute (CC_RawDecode) de * la donn�e d'entr�e. * * Remarks : Voir l'encodage * * In : pInBloc : la partie � d�coder (champ Content) * * Out : pOutBloc : le d�cod� (m�moire allou�e ici � lib�rer par la * fonction appelante) * * Responses : RV_SUCCESS : All is OK. * RV_MALLOC_FAILED : Un malloc a �chou�. * Autre : D'autres codes d'erreur peuvent �tre retourn�s par des * fonctions d'un niveau inf�rieur. * *******************************************************************************/ int CC_Decode_Signature(BYTE *pInData, BLOC *pOutBloc, USHORT *pLength )
{ // BLOC
// CompData;
int rv;
#ifdef _TRICKY_COMPRESSION
/* Ne pas faire le RawDecode a permis de gagner l'octet 0xFF */ #ifdef _OPT_HEADER
if (pInData[0] < 0x80) { CompData.usLen = pInData[0]; CompData.pData = &(pInData[1]); *pLength = CompData.usLen + 1; } else { CompData.usLen = ((pInData[0] & 0x7F) << 8) + pInData[1]; CompData.pData = &(pInData[2]); *pLength = CompData.usLen + 2; } #else /* _OPT_HEADER */
CompData.usLen = (pInData[0] << 8) + pInData[1]; CompData.pData = &(pInData[2]); *pLength = CompData.usLen + 2; #endif
pOutBloc->usLen = CompData.usLen; if ((pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen)) == NULL_PTR) { return(RV_MALLOC_FAILED); } memcpy(pOutBloc->pData, CompData.pData, pOutBloc->usLen); #else /* _TRICKY_COMPRESSION */
rv = CC_RawDecode(pInData, pOutBloc, pLength, TRUE); if (rv != RV_SUCCESS) return rv; #endif
return(RV_SUCCESS); }
|