2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include <dpl/assert.h>
17 #include <openssl/x509v3.h>
18 #include <dpl/log/log.h>
19 #include <dpl/noncopyable.h>
20 #include <openssl/ecdsa.h>
21 #include <openssl/evp.h>
24 #include "CertificateLoader.h"
25 #include "SSLContainers.h"
28 const int MIN_RSA_KEY_LENGTH = 1024;
29 //const char *OID_CURVE_SECP256R1 = "urn:oid:1.2.840.10045.3.1.7";
30 } // namespace anonymous
32 namespace ValidationCore {
33 //// COMPARATOR CLASS START ////
35 //class CertificateLoaderECDSA : public CertificateLoader::CertificateLoaderComparator, DPL::Noncopyable {
37 // CertificateLoaderECDSA(const std::string &publicKey)
38 // : m_ecPublicKey(NULL)
39 // , m_searchKey(NULL)
41 // m_bnCtx = BN_CTX_new(); // if fails we can continue anyway
42 // m_tmpPoint = BN_new(); // if fails we can continue anyway
43 // m_initialized = CertificateLoader::convertBase64NodeToBigNum(publicKey, &m_searchKey);
46 // LogError("Init failed!");
49 // virtual bool compare(X509 *x509cert){
53 // EVP_PKEY_free(m_ecPublicKey);
55 // m_ecPublicKey = X509_get_pubkey(x509cert);
57 // if(m_ecPublicKey == NULL)
60 // if(m_ecPublicKey->type != EVP_PKEY_EC){
61 // LogError("ecPublicKey has wrong type!");
65 // // Pointer to internal data of ecPublicKey. Do not free!
66 // EC_KEY *eckey = m_ecPublicKey->pkey.ec;
68 // const EC_POINT *ecpoint = EC_KEY_get0_public_key(eckey);
69 // const EC_GROUP *ecgroup = EC_KEY_get0_group(eckey);
71 // m_tmpPoint = EC_POINT_point2bn(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, m_tmpPoint, m_bnCtx);
73 // if(BN_cmp(m_tmpPoint, m_searchKey) == 0)
79 // ~CertificateLoaderECDSA(){
80 // BN_CTX_free(m_bnCtx);
81 // EVP_PKEY_free(m_ecPublicKey);
82 // BN_free(m_searchKey);
83 // BN_free(m_tmpPoint);
87 // bool m_initialized;
88 // EVP_PKEY *m_ecPublicKey;
90 // BIGNUM *m_searchKey;
91 // BIGNUM *m_tmpPoint;
94 ///// COMPARETORS CLASS END /////
96 //// COMPARATOR RSA CLASS START ////
98 //class CertificateLoaderRSA : public CertificateLoader::CertificateLoaderComparator, DPL::Noncopyable {
100 // CertificateLoaderRSA(const std::string &m_modulus,const std::string &m_exponent )
101 // : m_rsaPublicKey(NULL)
102 // , m_modulus_bn(NULL)
103 // , m_exponent_bn(NULL)
106 // m_initialized_modulus = CertificateLoader::convertBase64NodeToBigNum(m_modulus, &m_modulus_bn);
107 // m_initialized_exponent = CertificateLoader::convertBase64NodeToBigNum(m_exponent, &m_exponent_bn);
109 // if(!m_initialized_modulus || !m_initialized_exponent)
110 // LogError("Init failed!");
113 // virtual bool compare(X509 *x509cert){
115 // if(!m_initialized_modulus || !m_initialized_exponent)
118 // EVP_PKEY_free(m_rsaPublicKey);
119 // m_rsaPublicKey = X509_get_pubkey(x509cert);
121 // if(m_rsaPublicKey == NULL)
124 // if(m_rsaPublicKey->type != EVP_PKEY_RSA){
125 // LogInfo("rsaPublicKey has wrong type!");
130 // rsa = m_rsaPublicKey->pkey.rsa;
132 // if (BN_cmp(m_modulus_bn, rsa->n) == 0 &&
133 // BN_cmp(m_exponent_bn, rsa->e) == 0 ){
134 // LogError ("Compare TRUE");
140 // ~CertificateLoaderRSA(){
141 // EVP_PKEY_free(m_rsaPublicKey);
142 // BN_free(m_modulus_bn);
143 // BN_free(m_exponent_bn);
148 // bool m_initialized_modulus;
149 // bool m_initialized_exponent;
150 // EVP_PKEY *m_rsaPublicKey;
151 // BIGNUM *m_modulus_bn;
152 // BIGNUM *m_exponent_bn;
155 ///// COMPARETORS RSA CLASS END /////
157 CertificateLoader::CertificateLoaderResult CertificateLoader::
158 loadCertificateBasedOnExponentAndModulus(const std::string &m_modulus,
159 const std::string &m_exponent)
163 LogError("Not implemented.");
164 return UNKNOWN_ERROR;
165 // if (m_exponent.empty() || m_modulus.empty())
166 // return WRONG_ARGUMENTS;
168 // CertificateLoaderRSA comparator(m_modulus,m_exponent);
170 // CertificateLoaderResult result = NO_ERROR;
171 // for(int i=0; storeId[i]; ++i){
172 // result = loadCertificate(std::string(storeId[i]), &comparator);
174 // if(result == ERR_NO_MORE_CERTIFICATES)
183 CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificate(
184 const std::string &storageName,
185 CertificateLoader::CertificateLoaderComparator *cmp)
189 LogError("Not Implemented");
190 return UNKNOWN_ERROR;
191 // long int result = OPERATION_SUCCESS;
193 // char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
194 // char type[CERTMGR_MAX_CERT_TYPE_SIZE];
195 // certmgr_cert_id certId;
196 // certmgr_ctx context;
197 // certmgr_mem_buff certRetrieved;
198 // unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
200 // certmgr_cert_descriptor descriptor;
202 // certRetrieved.data = buffer;
203 // certRetrieved.firstFree = 0;
204 // certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
205 // certId.storeId = storeId;
206 // certId.type = type;
208 // CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
210 // strncpy(context.storeId, storageName.c_str(), storageName.size());
212 // for(certRetrieved.firstFree = 0;
213 // OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
214 // certRetrieved.firstFree = 0)
217 // if(OPERATION_SUCCESS!=certmgr_extract_certificate_data(&certRetrieved, &descriptor)){
218 // LogError("Extracting Certificate Data failed \n");
222 // const unsigned char *ptr = certRetrieved.data;
224 // X509 *x509cert = d2i_X509(NULL, &ptr, certRetrieved.size);
225 // if(x509cert == NULL){
226 // certmgr_release_certificate_data(&descriptor);
227 // LogError("Error extracting certificate (d2i_X509).");
228 // return UNKNOWN_ERROR;
231 // LogDebug("The subject of this certificate is " << descriptor.mandatory.subject);
232 // if(cmp->compare(x509cert)){
233 // LogDebug("Found match. Coping bytes: " << certRetrieved.size);
234 // m_certificatePtr = CertificatePtr(new Certificate(certRetrieved));
235 // certmgr_release_certificate_data(&descriptor);
236 // X509_free(x509cert);
240 // LogDebug("Release");
241 // X509_free(x509cert);
242 // certmgr_release_certificate_data(&descriptor);
245 // if(ERR_NO_MORE_CERTIFICATES == result){
246 // LogError("Certificates for given DN not found\n");
247 // return CERTIFICATE_NOT_FOUND;
250 // if(result!= OPERATION_SUCCESS){
251 // LogError("Certificate Manager Error\n");
252 // return UNKNOWN_ERROR;
260 CertificateLoader::CertificateLoaderResult CertificateLoader::
261 loadCertificateBasedOnSubjectName(const std::string &subjectName)
264 LogError("Not implemented.");
265 return UNKNOWN_ERROR;
266 // if(subjectName.empty())
268 // return WRONG_ARGUMENTS;
271 // long int result = OPERATION_SUCCESS;
273 // char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
274 // char type[CERTMGR_MAX_CERT_TYPE_SIZE];
275 // certmgr_cert_id certId;
276 // certmgr_ctx context;
277 // certmgr_mem_buff certRetrieved;
278 // unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
280 // certmgr_cert_descriptor descriptor;
282 // certRetrieved.data = buffer;
283 // certRetrieved.firstFree = 0;
284 // certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
285 // certId.storeId = storeId;
286 // certId.type = type;
288 // CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
290 // for(certRetrieved.firstFree = 0;
291 // OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
292 // certRetrieved.firstFree = 0)
295 // if(OPERATION_SUCCESS!=certmgr_extract_certificate_data(&certRetrieved, &descriptor)){
296 // LogError("Extracting Certificate Data failed \n");
300 // if(!strcmp(subjectName.c_str(), descriptor.mandatory.subject)){
301 // LogDebug("The subject of this certificate is " << descriptor.mandatory.subject);
302 // m_certificatePtr = CertificatePtr(new Certificate(certRetrieved));
303 // certmgr_release_certificate_data(&descriptor);
306 // LogDebug("Release");
307 // certmgr_release_certificate_data(&descriptor);
310 // if(ERR_NO_MORE_CERTIFICATES == result) {
311 // LogError("Certificates for given DN not found\n");
312 // return CERTIFICATE_NOT_FOUND;
314 // if(result!= OPERATION_SUCCESS){
315 // LogError("Certificate Manager Error\n");
316 // return UNKNOWN_ERROR;
322 // KW CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificateBasedOnIssuerName(const std::string &issuerName, const std::string &serialNumber)
324 // KW if(issuerName.empty() || serialNumber.empty())
326 // KW return WRONG_ARGUMENTS;
329 // KW if(m_cmBuff.data){
330 // KW delete[] m_cmBuff.data;
331 // KW memset(&m_cmBuff, 0, sizeof(certmgr_mem_buff));
334 // KW LogDebug("IssuerName: " << issuerName << " serialNumber: " << serialNumber);
336 // KW //used to check status of retrieved certificate
337 // KW long int result = OPERATION_SUCCESS;
338 // KW char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
339 // KW char type[CERTMGR_MAX_CERT_TYPE_SIZE];
340 // KW certmgr_cert_id certId;
341 // KW certmgr_ctx context;
342 // KW certmgr_mem_buff certRetrieved;
343 // KW unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
345 // KW certmgr_cert_descriptor descriptor;
347 // KW certRetrieved.data = buffer;
348 // KW certRetrieved.firstFree = 0;
349 // KW certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
350 // KW certId.storeId = storeId;
351 // KW certId.type = type;
353 // KW CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
355 // KW for(certRetrieved.firstFree = 0;
356 // KW OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
357 // KW certRetrieved.firstFree = 0)
360 // KW LogDebug("Extracting certificate from CertMgr");
362 // KW if( OPERATION_SUCCESS != certmgr_extract_certificate_data(&certRetrieved, &descriptor) ){
363 // KW LogError("Extracting Certificate Data failed \n");
367 // KW LogDebug("Issuer: " << descriptor.mandatory.issuer);
369 // KW const unsigned char *ptr = certRetrieved.data;
372 // KW X509 *x509cert = d2i_X509(NULL, &ptr, certRetrieved.size);
373 // KW std::string serialNO = std::string(tmp = i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(x509cert)));
374 // KW OPENSSL_free(tmp);
375 // KW X509_free(x509cert);
377 // KW LogInfo("Certificate number found: " << serialNO);
378 // KW LogInfo("Certificate number looking for: " << serialNumber);
380 // KW if(!strcmp(issuerName.c_str(), descriptor.mandatory.issuer)
381 // KW && serialNumber == serialNO)
383 // KW LogError("The issuer of this certificate is " << descriptor.mandatory.issuer);
385 // KW m_cmBuff.data = new unsigned char[certRetrieved.size];
386 // KW m_cmBuff.firstFree = m_cmBuff.size = certRetrieved.size;
387 // KW memcpy(m_cmBuff.data, certRetrieved.data, certRetrieved.size);
388 // KW certmgr_release_certificate_data(&descriptor);
391 // KW certmgr_release_certificate_data(&descriptor);
394 // KW if(ERR_NO_MORE_CERTIFICATES == result) {
395 // KW LogError("Certificates not found");
396 // KW return CERTIFICATE_NOT_FOUND;
398 // KW if(result != OPERATION_SUCCESS){
399 // KW LogError("Certificate Manager Error");
400 // KW return UNKNOWN_ERROR;
402 // KW return NO_ERROR;
405 CertificateLoader::CertificateLoaderResult CertificateLoader::
406 loadCertificateWithECKEY(const std::string &curveName,
407 const std::string &publicKey)
411 LogError("Not implemented.");
412 return UNKNOWN_ERROR;
413 // if(curveName != OID_CURVE_SECP256R1){
414 // LogError("Found field id: " << curveName << " Expected: " << OID_CURVE_SECP256R1);
415 // return UNSUPPORTED_CERTIFICATE_FIELD;
418 // CertificateLoaderECDSA comparator(publicKey);
420 // CertificateLoaderResult result = NO_ERROR;
421 // for(int i=0; storeId[i]; ++i){
422 // result = loadCertificate(std::string(storeId[i]), &comparator);
424 // if(result == ERR_NO_MORE_CERTIFICATES)
433 CertificateLoader::CertificateLoaderResult CertificateLoader::
434 loadCertificateFromRawData(const std::string &rawData)
439 base.append(rawData);
440 if (!base.finalize()) {
441 LogWarning("Certificate format is broken.");
442 return UNKNOWN_ERROR;
444 std::string derCert = base.get();
445 m_certificatePtr = CertificatePtr(new Certificate(derCert));
446 } Catch(Certificate::Exception::Base) {
447 LogWarning("Error reading certificate by openssl.");
448 return UNKNOWN_ERROR;
451 // Check the key length if sig algorithm is RSA
452 EVP_PKEY *pKey = X509_get_pubkey(m_certificatePtr->getX509());
454 if (pKey->type == EVP_PKEY_RSA) {
455 RSA* pRSA = pKey->pkey.rsa;
458 int keyLength = RSA_size(pRSA);
460 // key Length (modulus) is in bytes
462 LogDebug("RSA key length: " << keyLength << " bits");
464 if (keyLength < MIN_RSA_KEY_LENGTH) {
466 "RSA key too short!" << "Has only " << keyLength << " bits");
467 return CERTIFICATE_SECURITY_ERROR;
475 // DEPRACETED FUNCTION
476 //CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificateFromRawData(const std::string &rawData)
478 // certmgr_mem_buff cmBuff = {0,0,0};
481 // cmBuff.data = certmgr_util_base64_decode(const_cast<void*>(static_cast<const void*>(rawData.c_str())), rawData.size(), &size);
483 // cmBuff.firstFree = cmBuff.size = size;
485 // certmgr_cert_descriptor descriptor;
487 // long int result = certmgr_extract_certificate_data(&cmBuff, &descriptor);
489 // if (result != OPERATION_SUCCESS)
491 // LogError("Unable to load certificate");
492 // return UNKNOWN_ERROR;
495 // certmgr_release_certificate_data(&descriptor);
497 // m_certificatePtr = CertificatePtr(new Certificate(cmBuff));
499 // // we have to use temp pointer cause d2i_x509 modifies its input
500 // const unsigned char* tmpPtr = cmBuff.data;
501 // X509* pCertificate = d2i_X509(NULL, &tmpPtr, cmBuff.size);
505 // SSLSmartContainer<X509> pX509(pCertificate);
507 // // Check the key length if sig algorithm is RSA
508 // EVP_PKEY *pKey = X509_get_pubkey(pX509);
510 // if (pKey->type == EVP_PKEY_RSA)
512 // RSA* pRSA = pKey->pkey.rsa;
516 // int keyLength = RSA_size(pRSA);
518 // // key Length (modulus) is in bytes
520 // LogDebug("RSA key length: " << keyLength << " bits");
522 // if (keyLength < MIN_RSA_KEY_LENGTH)
524 // LogError("RSA key too short!" << "Has only " << keyLength << " bits");
525 // return CERTIFICATE_SECURITY_ERROR;
534 CertificateLoader::CertificateLoaderResult CertificateLoader::
535 loadCertificateBasedOnDSAComponents(const std::string& strP,
536 const std::string& strQ,
537 const std::string& strG,
538 const std::string& strY,
539 const std::string& strJ,
540 const std::string& strSeed,
541 const std::string& strPGenCounter)
549 (void) strPGenCounter;
550 LogError("Not implemented.");
551 return UNKNOWN_ERROR;
555 // (void)strPGenCounter;
557 // long int result = UNKNOWN_ERROR;
559 // char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
560 // char type[CERTMGR_MAX_CERT_TYPE_SIZE];
561 // certmgr_cert_id certId;
562 // certmgr_ctx context;
563 // certmgr_mem_buff certRetrieved;
565 // unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
567 // certmgr_cert_descriptor descriptor;
569 // certRetrieved.data = buffer;
570 // certRetrieved.firstFree = 0;
571 // certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
572 // certId.storeId = storeId;
573 // certId.type = type;
575 // CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
576 // std::string strStoreType("Operator");
577 // strncpy(context.storeId, strStoreType.c_str(), strStoreType.length());
579 // for (certRetrieved.firstFree = 0;
580 // OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
581 // certRetrieved.firstFree = 0)
584 // if (OPERATION_SUCCESS != certmgr_extract_certificate_data(&certRetrieved, &descriptor))
586 // LogDebug("unable to retrieve cert from storage");
590 // X509* pCertificate = d2i_X509(NULL, (const unsigned char**) &(certRetrieved.data), certRetrieved.size);
594 // EVP_PKEY *pKey = X509_get_pubkey(pCertificate);
596 // if (pKey->type == EVP_PKEY_DSA)
598 // DSA* pDSA = pKey->pkey.dsa;
602 // BIGNUM *pDSApBigNum = NULL, *pDSAqBigNum = NULL, *pDSAgBigNum = NULL;
604 // convertBase64NodeToBigNum(strP, &pDSApBigNum);
605 // convertBase64NodeToBigNum(strQ, &pDSAqBigNum);
606 // convertBase64NodeToBigNum(strG, &pDSAgBigNum);
608 // if (pDSApBigNum && pDSAqBigNum && pDSAgBigNum &&
609 // BN_cmp(pDSApBigNum, pDSA->p) == 0 &&
610 // BN_cmp(pDSAqBigNum, pDSA->q) == 0 &&
611 // BN_cmp(pDSAgBigNum, pDSA->g) == 0)
613 // LogInfo("DSA Certificate found");
614 // /* TODO load this certificate to m_cmBuff value */
615 // LogError("Not implemented!");
617 // EVP_PKEY_free(pKey);
618 // X509_free(pCertificate);
620 // BN_free(pDSApBigNum);
621 // BN_free(pDSAqBigNum);
622 // BN_free(pDSAgBigNum);
624 // certmgr_release_certificate_data(&descriptor);
630 // BN_free(pDSApBigNum);
634 // BN_free(pDSAqBigNum);
638 // BN_free(pDSAgBigNum);
642 // EVP_PKEY_free(pKey);
644 // X509_free(pCertificate);
647 // LogError("Unable to load certificate");
649 // certmgr_release_certificate_data(&descriptor);
652 // LogError("No DSA certificate with given parameters");
654 // return CERTIFICATE_NOT_FOUND;
657 bool CertificateLoader::convertBase64NodeToBigNum(const std::string& strNode,
662 LogError("Not implemented.");
664 // if (!ppBigNum || *ppBigNum != NULL)
666 // LogError("Ptr variable not initialized properly!");
670 // // decode base64 to binary
671 // long int binBuffLength = 0;
672 // unsigned char* binBuff = NULL;
674 // binBuff = certmgr_util_base64_decode(const_cast<char*> (strNode.c_str()), strNode.length(), &binBuffLength);
678 // LogError("base64 decode failed");
682 // // convert binary to bignum
683 // *ppBigNum = BN_bin2bn(binBuff, binBuffLength, *ppBigNum);
689 // LogError("Conversion from node to bignum failed");
696 // KW bool CertificateLoader::convertBigNumToBase64Node(const BIGNUM* pBigNum, std::string& strNode)
700 // KW LogError("null ptr");
704 // KW int nNumLength = BN_num_bytes(pBigNum);
705 // KW unsigned char* buffer = new unsigned char[nNumLength + 1];
707 // KW // convert bignum to binary format
708 // KW if (BN_bn2bin(pBigNum, buffer) < 0)
710 // KW LogError("Conversion from bignum to binary failed");
711 // KW delete []buffer;
715 // KW char* pBase64Node = NULL;
716 // KW unsigned long int buffLen = 0;
717 // KW certmgr_util_base64_encode(buffer, (unsigned long int) nNumLength, &pBase64Node, &buffLen);
719 // KW strNode.assign(pBase64Node, buffLen);
721 // KW delete []buffer;
724 } // namespace ValidationCore