Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TLS_axTLS-Example HTTPSClientExample
CertificateManager.cpp
00001 #include "CertificateManager.h" 00002 #include "axTLS/crypto/bigint.h" 00003 #include "cert_manager.h" 00004 #include "axTLS/ssl/crypto_misc.h " 00005 00006 CertificateManager::CertificateManager(): 00007 files(), 00008 certs(NULL), 00009 precomputedCerts() 00010 { 00011 } 00012 00013 CertificateManager::~CertificateManager() 00014 { 00015 clear(); 00016 } 00017 00018 CertificateManager& CertificateManager::instance() 00019 { 00020 static CertificateManager cm; 00021 return cm; 00022 } 00023 00024 void CertificateManager::add(const char *fileName) 00025 { 00026 CertificateManager::instance().files.push_back(fileName); 00027 } 00028 00029 bool CertificateManager::load(bool precompute) 00030 { 00031 if(precompute) 00032 return CertificateManager::instance().loadPrecomputeCertificates(); 00033 else 00034 return CertificateManager::instance().loadCertificates(); 00035 } 00036 00037 bool CertificateManager::loadCertificates() 00038 { 00039 X509_CTX *cert = certs; 00040 for(std::list<std::string>::iterator itor = files.begin(); 00041 itor != files.end(); 00042 ++itor) { 00043 FILE *fp = fopen(itor->c_str(), "r"); 00044 if(fp == NULL) 00045 return false; 00046 00047 fseek(fp, 0, SEEK_END); 00048 int length = ftell(fp); 00049 fseek(fp, 0, SEEK_SET); 00050 uint8_t *data = new uint8_t[length]; 00051 fread(data, sizeof(uint8_t), length, fp); 00052 fclose(fp); 00053 00054 if(x509_new(data, NULL, &cert) != 0) { 00055 x509_free(certs); 00056 delete[] data; 00057 return false; 00058 } 00059 00060 delete[] data; 00061 cert = cert->next; 00062 } 00063 files.clear(); 00064 return true; 00065 } 00066 00067 /* Check cert1 with cert2 00068 */ 00069 bool CertificateManager::check(X509_CTX *cert1, X509_CTX* cert2) 00070 { 00071 if(asn1_compare_dn(cert1->ca_cert_dn, cert2->cert_dn)) 00072 return false; 00073 if (time(NULL) < cert1->not_before) 00074 return false; 00075 if (time(NULL) > cert1->not_after) 00076 return false; 00077 00078 /* Cannot check : takes too much memory 00079 BI_CTX *ctx = cert2->rsa_ctx->bi_ctx; 00080 bigint *mod = bi_clone(ctx, cert2->rsa_ctx->m); 00081 bigint *expn = bi_clone(ctx , cert2->rsa_ctx->e); 00082 bigint *digest = sig_verify(ctx, cert1->signature, cert1->sig_len, mod, expn); 00083 if(digest && cert1->digest) 00084 { 00085 if(bi_compare(digest, cert1->digest) != 0) 00086 { 00087 bi_free(ctx, digest); 00088 return false; 00089 } 00090 bi_free(ctx, digest); 00091 } 00092 else 00093 return false; 00094 */ 00095 return true; 00096 } 00097 00098 bool CertificateManager::loadPrecomputeCertificates() 00099 { 00100 if(files.size() < 2) 00101 return false; 00102 precomputedCerts.reserve(files.size()-1); 00103 X509_CTX *cert1 = NULL, *cert2 = NULL; 00104 00105 // load cert1 00106 FILE *fp = fopen(files.front().c_str(), "r"); 00107 if(fp == NULL) { 00108 printf("Could not open file %s\n", files.front().c_str()); 00109 clear(); 00110 return false; 00111 } 00112 files.pop_front(); 00113 00114 fseek(fp, 0, SEEK_END); 00115 int length = ftell(fp); 00116 fseek(fp, 0, SEEK_SET); 00117 uint8_t *data = new uint8_t[length]; 00118 fread(data, sizeof(uint8_t), length, fp); 00119 fclose(fp); 00120 00121 if(x509_new(data, NULL, &cert1) != 0) { 00122 delete[] data; 00123 clear(); 00124 return false; 00125 } 00126 delete[] data; 00127 00128 while(!files.empty()) { 00129 // load cert2 00130 fp = fopen(files.front().c_str(), "r"); 00131 if(fp == NULL) { 00132 printf("Could not open file %s\n", files.front().c_str()); 00133 x509_free(cert1); 00134 clear(); 00135 return false; 00136 } 00137 files.pop_front(); 00138 00139 fseek(fp, 0, SEEK_END); 00140 length = ftell(fp); 00141 fseek(fp, 0, SEEK_SET); 00142 data = new uint8_t[length]; 00143 fread(data, sizeof(uint8_t), length, fp); 00144 fclose(fp); 00145 00146 if(x509_new(data, NULL, &cert2) != 0) { 00147 x509_free(cert1); 00148 delete[] data; 00149 clear(); 00150 return false; 00151 } 00152 delete[] data; 00153 00154 00155 if(!check(cert1, cert2)) { 00156 printf("Certificates verification failed\n"); 00157 x509_free(cert1); 00158 x509_free(cert2); 00159 clear(); 00160 return false; 00161 } 00162 00163 00164 // Create certificate 00165 PrecomputedCertificate pc; 00166 memset(&pc, 0, sizeof(PrecomputedCertificate)); 00167 for(int i = 0; i < X509_NUM_DN_TYPES; ++i) { 00168 if(cert1->ca_cert_dn[i] != NULL) { 00169 pc.ca_cert_dn[i] = new char[strlen(cert1->ca_cert_dn[i])+1]; 00170 strcpy(pc.ca_cert_dn[i], cert1->ca_cert_dn[i]); 00171 } 00172 if(cert1->cert_dn[i] != NULL) { 00173 pc.cert_dn[i] = new char[strlen(cert1->cert_dn[i])+1]; 00174 strcpy(pc.cert_dn[i], cert1->cert_dn[i]); 00175 } 00176 } 00177 00178 uint8_t buffer[512]; 00179 uint16_t paddingLength; 00180 bi_permanent(cert1->digest); 00181 bi_export(cert1->rsa_ctx->bi_ctx, cert1->digest, buffer, 512); 00182 bi_depermanent(cert1->digest); 00183 00184 paddingLength = 0; 00185 while(buffer[paddingLength] == 0 && paddingLength < 512) paddingLength++; 00186 pc.digest_len = 512 - paddingLength; 00187 pc.digest = new uint8_t[pc.digest_len]; 00188 memcpy(pc.digest, &buffer[paddingLength], pc.digest_len); 00189 00190 bi_export(cert2->rsa_ctx->bi_ctx, cert2->rsa_ctx->m, buffer, 512); 00191 00192 paddingLength = 0; 00193 while(buffer[paddingLength] == 0) paddingLength++; 00194 pc.mod_len = 512 - paddingLength; 00195 pc.mod = new uint8_t[pc.mod_len]; 00196 memcpy(pc.mod, &buffer[paddingLength], pc.mod_len); 00197 00198 00199 bi_export(cert2->rsa_ctx->bi_ctx, cert2->rsa_ctx->e, buffer, 512); 00200 paddingLength = 0; 00201 while(buffer[paddingLength] == 0) paddingLength++; 00202 pc.expn_len = 512 - paddingLength; 00203 pc.expn = new uint8_t[pc.expn_len]; 00204 memcpy(pc.expn, &buffer[paddingLength], pc.expn_len); 00205 00206 pc.sig = new uint8_t[cert1->sig_len]; 00207 pc.sig_len = cert1->sig_len; 00208 memcpy(pc.sig, cert1->signature, pc.sig_len); 00209 00210 00211 precomputedCerts.push_back(pc); 00212 00213 x509_free(cert1); 00214 cert1 = cert2; 00215 } 00216 x509_free(cert2); 00217 certs = NULL; 00218 return true; 00219 } 00220 00221 void CertificateManager::clear() 00222 { 00223 CertificateManager &cm = CertificateManager::instance(); 00224 cm.files.clear(); 00225 x509_free(cm.certs); 00226 cm.certs = NULL; 00227 for(int i = 0; i < cm.precomputedCerts.size(); ++i) { 00228 for(int j = 0; j < X509_NUM_DN_TYPES; ++j) { 00229 delete cm.precomputedCerts[i].cert_dn[j]; 00230 delete cm.precomputedCerts[i].ca_cert_dn[j]; 00231 } 00232 00233 delete[] cm.precomputedCerts[i].sig; 00234 delete[] cm.precomputedCerts[i].mod; 00235 delete[] cm.precomputedCerts[i].expn; 00236 delete[] cm.precomputedCerts[i].digest; 00237 } 00238 cm.precomputedCerts.clear(); 00239 } 00240 00241 extern "C" char is_precomputed(void) 00242 { 00243 return CertificateManager::instance().precomputedCerts.size() > 0 ? 1 : 0; 00244 } 00245 00246 extern "C" PrecomputedCertificate get_precomputed_cert(char *cert_dn[], char *ca_cert_dn[]) 00247 { 00248 std::vector<PrecomputedCertificate> &precomputedCerts = CertificateManager::instance().precomputedCerts; 00249 00250 for(int i = 0; i < precomputedCerts.size(); ++i) { 00251 00252 PrecomputedCertificate pc = precomputedCerts[i]; 00253 int j = 0; 00254 for(; j < X509_NUM_DN_TYPES; ++j) { 00255 00256 if( (cert_dn[j] == NULL && pc.cert_dn[j] != NULL) 00257 || (cert_dn[j] != NULL && pc.cert_dn[j] == NULL) 00258 || (ca_cert_dn[j] == NULL && pc.ca_cert_dn[j] != NULL) 00259 || (ca_cert_dn[j] != NULL && pc.ca_cert_dn[j] == NULL)) 00260 break; 00261 00262 if(cert_dn[j] && pc.cert_dn[j]) { 00263 if(strcmp(cert_dn[j], pc.cert_dn[j])) 00264 break; 00265 } 00266 00267 if(ca_cert_dn[j] && pc.ca_cert_dn[j]) { 00268 if(strcmp(ca_cert_dn[j], pc.ca_cert_dn[j])) 00269 break; 00270 } 00271 } 00272 if(j == X509_NUM_DN_TYPES) 00273 return pc; 00274 } 00275 00276 PrecomputedCertificate pc; 00277 memset(&pc, 0, sizeof(PrecomputedCertificate)); 00278 return pc; 00279 } 00280 00281 00282 extern "C" X509_CTX* get_cert(char *ca_cert_dn[]) 00283 { 00284 X509_CTX *cert = CertificateManager::instance().certs; 00285 00286 while(1) { 00287 if(cert == NULL) 00288 return NULL; 00289 int i = 0; 00290 for(; i < X509_NUM_DN_TYPES; ++i) { 00291 if(strcmp(ca_cert_dn[i], cert->cert_dn[i])) 00292 break; 00293 } 00294 if(i == X509_NUM_DN_TYPES) 00295 return cert; 00296 cert = cert->next; 00297 } 00298 } 00299 00300 00301 extern "C" void cert_manager_clear(void) 00302 { 00303 CertificateManager::clear(); 00304 } 00305 00306 00307
Generated on Wed Jul 13 2022 19:30:07 by
1.7.2