2 * Copyright (c) 2015 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.
18 * @author Jacek Migacz (j.migacz@samsung.com)
19 * @author Kyungwook Tak (k.tak@samsung.com)
21 * @brief PKCS#12 container manipulation routines.
27 #include <sys/types.h>
29 #include <openssl/err.h>
30 #include <openssl/pkcs12.h>
31 #include <openssl/sha.h>
32 #include <openssl/x509.h>
33 #include <openssl/pem.h>
35 #include <cert-service.h>
36 #include <cert-service-debug.h>
37 #include <cert-svc/cerror.h>
38 #include <cert-svc-client.h>
40 #include <vcore/utils.h>
43 #define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
45 #define START_CERT "-----BEGIN CERTIFICATE-----"
46 #define END_CERT "-----END CERTIFICATE-----"
47 #define START_TRUSTED "-----BEGIN TRUSTED CERTIFICATE-----"
48 #define END_TRUSTED "-----END TRUSTED CERTIFICATE-----"
49 #define START_KEY "-----BEGIN PRIVATE KEY-----"
50 #define END_KEY "-----END PRIVATE KEY-----"
52 #define _CERT_SVC_VERIFY_PKCS12
54 static int generate_random_filepath(char **filepath)
59 unsigned char d[SHA_DIGEST_LENGTH];
63 return CERTSVC_WRONG_ARGUMENT;
65 SYSCALL(generator = open("/dev/urandom", O_RDONLY));
68 SYSCALL(result = read(generator, &random, sizeof(random)));
70 SYSCALL(close(generator));
73 SYSCALL(result = close(generator));
78 SHA1_Update(&ctx, &random, sizeof(random));
81 result = asprintf(filepath, "%s/" \
82 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \
83 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
84 CERTSVC_PKCS12_STORAGE_DIR,
85 d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9],
86 d[10], d[11], d[12], d[13], d[14], d[15], d[16], d[17], d[18], d[19]);
87 return (result != -1) ? CERTSVC_SUCCESS : CERTSVC_BAD_ALLOC;
90 static int unique_filename(char **filepath)
94 for (unsigned trial = 0x00U; trial < 0xFFU; ++trial) {
95 result = generate_random_filepath(filepath);
96 if (result != CERTSVC_SUCCESS)
99 result = access(*filepath, F_OK);
101 return CERTSVC_SUCCESS;
109 static char *bare_filename(char *filepath)
114 needle = strrchr(filepath, '/');
117 return *(++needle) ? needle : NULL;
120 int read_from_file(const char *fileName, char **certBuffer, int *length)
122 int result = CERTSVC_SUCCESS;
127 if (stat(fileName, &st) == -1) {
128 SLOGE("Certificate does not exist in disable folder.");
129 result = CERTSVC_FAIL;
133 if (!(fp_out = fopen(fileName, "rb"))) {
134 SLOGE("Fail to open file for reading, [%s].", fileName);
135 result = CERTSVC_FAIL;
139 fseek(fp_out, 0L, SEEK_END);
140 certLength = ftell(fp_out);
141 if (certLength < 1) {
142 SLOGE("Fail to get certificate length.");
143 result = CERT_SVC_ERR_FILE_IO;
147 *certBuffer = (char*)malloc(sizeof(char) * ((int)certLength + 1));
148 if (*certBuffer == NULL) {
149 SLOGE("Fail to allocate memory");
150 result = CERTSVC_BAD_ALLOC;
154 memset(*certBuffer, 0x00, certLength+1);
156 if (fread(*certBuffer, sizeof(char), (size_t)certLength, fp_out) != (size_t)certLength) {
157 SLOGE("Fail to read file, [%s]", fileName);
158 result = CERTSVC_IO_ERROR;
161 *length = certLength;
164 if (fp_out != NULL) {
171 int c_certsvc_pkcs12_set_certificate_status_to_store(CertStoreType storeType, int is_root_app, const char* gname, CertStatus status)
173 return vcore_client_set_certificate_status_to_store(storeType, is_root_app, gname, status);
176 int c_certsvc_pkcs12_get_certificate_buffer_from_store(CertStoreType storeType, const char* gname, char** certBuffer, size_t* certSize)
178 return vcore_client_get_certificate_from_store(storeType, gname, certBuffer, certSize, PEM_CRT);
181 int c_certsvc_pkcs12_get_certificate_status_from_store(CertStoreType storeType, const char *gname, CertStatus *status)
183 return vcore_client_get_certificate_status_from_store(storeType, gname, status);
186 int c_certsvc_pkcs12_alias_exists_in_store(CertStoreType storeType, const char *alias, int *isUnique)
188 return vcore_client_check_alias_exist_in_store(storeType, alias, isUnique);
191 int c_certsvc_pkcs12_private_key_load_from_store(CertStoreType storeType, const char *gname, char **certBuffer, size_t *certSize)
193 return vcore_client_get_certificate_from_store(storeType, gname, certBuffer, certSize, (CertType)P12_PKEY);
196 int c_certsvc_pkcs12_delete_certificate_from_store(CertStoreType storeType, const char* gname)
198 return vcore_client_delete_certificate_from_store(storeType, gname);
201 int c_certsvc_pkcs12_get_certificate_alias_from_store(CertStoreType storeType, const char *gname, char **alias)
203 return vcore_client_get_certificate_alias_from_store(storeType, gname, alias);
206 int c_certsvc_pkcs12_load_certificates_from_store(CertStoreType storeType, const char *gname, char ***certs, size_t *ncerts)
208 return vcore_client_load_certificates_from_store(storeType, gname, certs, ncerts);
211 int c_certsvc_pkcs12_free_aliases_loaded_from_store(CertSvcStoreCertList** certList)
213 int result = CERTSVC_SUCCESS;
214 CertSvcStoreCertList* tmpNode = NULL;
219 free(tmpNode->title);
221 free(tmpNode->gname);
222 *certList = (*certList)->next;
228 int c_certsvc_pkcs12_get_root_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList** certList, size_t *length)
230 return vcore_client_get_root_certificate_list_from_store(storeType, certList, length);
233 int c_certsvc_pkcs12_get_end_user_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList** certList, size_t *length)
235 return vcore_client_get_end_user_certificate_list_from_store(storeType, certList, length);
238 int c_certsvc_pkcs12_get_certificate_list_from_store(CertStoreType storeType, int is_root_app, CertSvcStoreCertList** certList, size_t *length)
240 return vcore_client_get_certificate_list_from_store(storeType, is_root_app, certList, length);
243 int install_pem_file_format_to_store(CertStoreType storeType, const char *certBuffer, size_t certLength,
244 const char *alias, const char* path, char *private_key_gname, char *associated_gname, CertType decideCert)
246 int result = CERTSVC_SUCCESS;
248 char* fileName = NULL;
249 char* commonName = NULL;
252 X509* x509Struct = NULL;
255 if (!certBuffer || !certLength) {
256 SLOGE("Invalid argument. certBuffer is input cert.");
257 return CERTSVC_WRONG_ARGUMENT;
260 if (decideCert == PEM_CRT) {
261 result = unique_filename(&unique);
262 if (result != CERTSVC_SUCCESS) {
263 SLOGE("Fail to generate unique filename.");
268 unique = (char*)path;
270 if (unique == NULL) {
271 SLOGE("Failed to get unique file name.");
275 /* Get common name from buffer or from file */
276 if (stat(path, &dirST) != -1) {
277 result = get_common_name(path, NULL, &commonName);
278 if (result != CERTSVC_SUCCESS) {
279 pBio = BIO_new(BIO_s_mem());
281 SLOGE("Failed to allocate memory.");
282 result = CERTSVC_BAD_ALLOC;
286 readCount = BIO_write(pBio, (const void*) certBuffer, certLength);
288 SLOGE("Failed to load cert into bio.");
289 result = CERTSVC_BAD_ALLOC;
293 x509Struct = PEM_read_bio_X509(pBio, NULL, 0, NULL);
294 if (x509Struct == NULL) {
295 SLOGE("Failed to create x509 structure.");
296 result = CERTSVC_IO_ERROR;
300 result = get_common_name(NULL, x509Struct, &commonName);
301 if (result != CERTSVC_SUCCESS) {
302 SLOGE("CommonName is NULL");
303 result = CERTSVC_FAIL;
309 /* storing the certificate to key-manager */
310 fileName = bare_filename(unique);
311 if ((decideCert == P12_END_USER) && (private_key_gname != NULL))
312 result = vcore_client_install_certificate_to_store(storeType, fileName, alias, private_key_gname, fileName, certBuffer, certLength, decideCert);
313 else if ((decideCert == P12_TRUSTED) || (decideCert == P12_INTERMEDIATE))
314 result = vcore_client_install_certificate_to_store(storeType, fileName, commonName, NULL, associated_gname, certBuffer, certLength, decideCert);
316 result = vcore_client_install_certificate_to_store(storeType, fileName, commonName, NULL, fileName, certBuffer, certLength, decideCert);
318 if (result != CERTSVC_SUCCESS) {
319 SLOGE("Failed to intall certificate. result[%d]", result);
320 result = CERTSVC_FAIL;
324 SLOGD("Success to add certificate in store.");
332 int install_crt_file(
334 CertStoreType storeType,
336 char *private_key_gname,
337 char *associated_gname,
340 int result = CERTSVC_SUCCESS;
343 const char* header = NULL;
344 const char* trailer = NULL;
345 char* fileContent = NULL;
346 const char* tmpBuffer = NULL;
347 char* certBuffer = NULL;
348 const char* tailEnd = NULL;
350 if (read_from_file(path, &fileContent, &fileSize)!=CERTSVC_SUCCESS)
352 SLOGE("Failed to read the file. [%s]",path);
353 result = CERTSVC_IO_ERROR;
357 tmpBuffer = fileContent;
358 if (decideCert == PEM_CRT)
359 header = strstr(tmpBuffer, START_CERT);
360 else if (decideCert == P12_END_USER)
361 header = strstr(tmpBuffer, START_CERT);
362 else if ((decideCert == P12_TRUSTED)||(decideCert == P12_INTERMEDIATE))
363 header = strstr(tmpBuffer, START_TRUSTED);
365 SLOGE("Invalid cert.");
366 result = CERTSVC_IO_ERROR;
370 if (header != NULL) {
371 /* Supports installation of only one certificate present in a CRT file */
372 if (decideCert == PEM_CRT) {
373 trailer = strstr(header, END_CERT);
376 else if (decideCert == P12_END_USER) {
377 trailer = strstr(header, END_CERT);
380 else if ((decideCert == P12_TRUSTED)||(decideCert == P12_INTERMEDIATE)) {
381 trailer = strstr(header, END_TRUSTED);
382 tailEnd = END_TRUSTED;
385 SLOGE("Invalid certificate passed.");
386 result = CERTSVC_IO_ERROR;
390 if (trailer != NULL) {
392 certLength = ((int)(trailer - header) + strlen(tailEnd));
393 certBuffer = (char*) malloc(sizeof(char) * (certLength+2));
394 if (certBuffer == NULL) {
395 result = CERTSVC_BAD_ALLOC;
396 SLOGE("Fail to allocate memory.");
400 memset(certBuffer, 0x00, certLength+2);
401 memcpy(certBuffer, header, certLength);
402 certBuffer[certLength] = '\0';
404 result = install_pem_file_format_to_store(storeType, certBuffer, certLength, alias, \
405 path, private_key_gname, associated_gname, decideCert);
406 if (result != CERTSVC_SUCCESS) {
407 result = CERTSVC_FAIL;
408 SLOGE("Fail to install certificate[%s]", path);
413 SLOGE("Invalid file type passed.");
414 result = CERT_SVC_ERR_INVALID_CERTIFICATE;
425 int handle_crt_pem_file_installation(CertStoreType storeType, const char *path, const char *alias)
427 int result = CERTSVC_SUCCESS;
429 if ((strstr(path, ".crt")) != NULL || (strstr(path, ".pem")) != NULL) {
430 SLOGD("certificate extention is .crt/.pem file");
432 /* Installs CRT and PEM files. We will passing NULL for private_key_gname and associated_gname parameter in
433 * install_crt_file(). Which means that there is no private key involved in the certificate which we are
434 * installing and there are no other certificates related with the current certificate which is installed */
435 result = install_crt_file(path, storeType, alias, NULL, NULL, PEM_CRT);
436 if (result != CERTSVC_SUCCESS) {
437 SLOGE("Failed to install the certificate.");
438 result = CERTSVC_FAIL;
443 SLOGE("Invalid certificate passed.");
444 result = CERTSVC_FAIL;
447 SLOGD("Success to install the certificate.");
453 int verify_cert_details(X509** cert, STACK_OF(X509) **certv)
455 int result = CERTSVC_SUCCESS;
456 char* pSubject = NULL;
457 char* pIssuerName = NULL;
458 X509_STORE_CTX *cert_ctx = NULL;
459 X509_STORE *cert_store = NULL;
462 #ifdef _CERT_SVC_VERIFY_PKCS12
463 if (*certv == NULL) {
464 pSubject = X509_NAME_oneline((*cert)->cert_info->subject, NULL, 0);
466 SLOGE("Failed to get subject name");
467 result = CERTSVC_FAIL;
471 pIssuerName = X509_NAME_oneline((*cert)->cert_info->issuer, NULL, 0);
473 SLOGE("Failed to get issuer name");
474 result = CERTSVC_FAIL;
478 if (strcmp((const char*)pSubject, (const char*)pIssuerName) == 0) {
480 EVP_PKEY* pKey = NULL;
481 pKey = X509_get_pubkey(*cert);
483 SLOGE("Failed to get public key");
484 result = CERTSVC_FAIL;
488 if (X509_verify(*cert, pKey) <= 0) {
489 SLOGE("P12 verification failed");
491 result = CERTSVC_FAIL;
494 SLOGD("P12 verification Success");
498 cert_store = X509_STORE_new();
500 SLOGE("Memory allocation failed");
501 result = CERTSVC_FAIL;
505 res = X509_STORE_load_locations(cert_store, NULL, "/opt/etc/ssl/certs/");
507 SLOGE("P12 load certificate store failed");
508 X509_STORE_free(cert_store);
509 result = CERTSVC_FAIL;
513 res = X509_STORE_set_default_paths(cert_store);
515 SLOGE("P12 load certificate store path failed");
516 X509_STORE_free(cert_store);
517 result = CERTSVC_FAIL;
521 /* initialise store and store context */
522 cert_ctx = X509_STORE_CTX_new();
523 if (cert_ctx == NULL) {
524 SLOGE("Memory allocation failed");
525 result = CERTSVC_FAIL;
529 /* construct store context */
530 if (!X509_STORE_CTX_init(cert_ctx, cert_store, *cert, NULL)) {
531 SLOGE("Memory allocation failed");
532 result = CERTSVC_FAIL;
536 #ifdef P12_VERIFICATION_NEEDED
537 res = X509_verify_cert(cert_ctx);
539 SLOGE("P12 verification failed");
540 result = CERTSVC_FAIL;
543 SLOGD("P12 verification Success");
547 else if (*certv != NULL) {
549 cert_store = X509_STORE_new();
551 SLOGE("Memory allocation failed");
552 result = CERTSVC_FAIL;
556 res = X509_STORE_load_locations(cert_store, NULL, CERTSVC_SSL_CERTS_DIR);
558 SLOGE("P12 load certificate store failed");
559 result = CERTSVC_FAIL;
563 res = X509_STORE_set_default_paths(cert_store);
565 SLOGE("P12 load certificate path failed");
566 result = CERTSVC_FAIL;
570 /* initialise store and store context */
571 cert_ctx = X509_STORE_CTX_new();
572 if (cert_ctx == NULL) {
573 SLOGE("Memory allocation failed");
574 result = CERTSVC_FAIL;
578 /* construct store context */
579 if (!X509_STORE_CTX_init(cert_ctx, cert_store, *cert, NULL)) {
580 SLOGE("Memory allocation failed");
581 result = CERTSVC_FAIL;
585 X509_STORE_CTX_trusted_stack(cert_ctx, *certv);
586 #ifdef P12_VERIFICATION_NEEDED
587 res = X509_verify_cert(cert_ctx);
589 SLOGE("P12 verification failed");
590 result = CERTSVC_FAIL;
593 SLOGD("P12 verification Success");
596 #endif //_CERT_SVC_VERIFY_PKCS12
599 if (pSubject != NULL) { free(pSubject); }
600 if (pIssuerName != NULL) { free(pIssuerName); }
601 if (cert_store != NULL) { X509_STORE_free(cert_store); }
602 if (cert_ctx) { X509_STORE_CTX_free(cert_ctx); }
606 int c_certsvc_pkcs12_import_from_file_to_store(CertStoreType storeTypes, const char *path, const char *password, const char *alias)
608 int result = CERTSVC_SUCCESS;
612 size_t nicerts = 0, i = 0, n = 0, ncerts = 0;
613 CertStoreType storeType = NONE_STORE;
615 PKCS12* container = NULL;
616 EVP_PKEY* key = NULL;
618 STACK_OF(X509) *certv = NULL;
620 char* pkvalue = NULL;
621 char** cvaluev = NULL;
623 char* tmpPkValue = NULL;
625 char fileBuffer[4096] = {0,};
627 CertType decideCert = INVALID_DATA;
630 if ((!alias) || (strlen(alias) < 1) || (!path) || (strlen(path) < 1)) {
631 SLOGE("Invalid input parameter.");
632 SLOG(LOG_INFO, "MDM_LOG_USER", "Object=certificate, AccessType=Install, Result=Failed");
633 return CERTSVC_WRONG_ARGUMENT;
637 /* Iteration only possible from VPN_STORE till SYSTEM_STORE */
638 if (loopCount == (MAX_STORE_ENUMS-1)) break;
640 /* User should not install any form of certificates inside SYSTEM_STORE */
641 if (((1 << loopCount) & storeTypes) == SYSTEM_STORE) {
642 SLOGE("Not a valid store type installing certificate, store type passed [%d].", (1 << loopCount));
643 SLOG(LOG_INFO, "MDM_LOG_USER", "Object=certificate, AccessType=Install, Result=Failed");
644 return CERTSVC_INVALID_STORE_TYPE;
647 /* Iterating over all the stores */
648 if ((1 << loopCount) & storeTypes) {
649 storeType = NONE_STORE;
650 storeType = (CertStoreType) (1 << loopCount);
651 SLOGD("Processing store type : [%s]", (storeType == VPN_STORE)? "VPN" : (storeType == WIFI_STORE)? "WIFI" : "EMAIL");
653 /* check if the alias exists before installing certificate */
654 result = c_certsvc_pkcs12_alias_exists_in_store(storeType, alias, &exists);
655 if (result != CERTSVC_SUCCESS) {
656 SLOGE("Failure to access database.");
657 result = CERTSVC_FAIL;
661 if (exists!=CERTSVC_TRUE) {
662 SLOGE("Alias exist in store [%s].", (storeType == VPN_STORE)? "VPN" : (storeType == WIFI_STORE)? "WIFI" : "EMAIL");
663 result = CERTSVC_DUPLICATED_ALIAS;
667 /* Logic for handling crt/pem cert installation */
668 /* Check if the input file is a PEM/CRT, since a PFX cert can also be opened without a password */
669 if (password == NULL && ((strstr(path, ".pfx") == NULL) || (strstr(path, ".p12")))) {
670 result = handle_crt_pem_file_installation(storeType, path, alias);
671 if (result != CERTSVC_SUCCESS) {
672 SLOGE("Failed to install PEM/CRT file to store.");
673 result = CERTSVC_FAIL;
679 /* Logic for handling .pfx/.p12 cert installation */
680 if ((stream = fopen(path, "rb")) == NULL) {
681 SLOGE("Unable to open the file for reading [%s].", path);
682 result = CERTSVC_IO_ERROR;
686 if (container == NULL) {
687 container = d2i_PKCS12_fp(stream, NULL);
689 if (container == NULL) {
690 SLOGE("Failed to parse the input file passed.");
691 result = CERTSVC_FAIL;
696 /* To ensure when the code re-enters, we should clean up */
697 if (key==NULL && cert==NULL && certv==NULL) {
698 result = PKCS12_parse(container, password, &key, &cert, &certv);
699 PKCS12_free(container);
700 if (result == CERTSVC_FAIL) {
701 SLOGE("Failed to parse the file passed.");
702 result = CERTSVC_FAIL;
706 result = verify_cert_details(&cert, &certv);
707 if (result == CERTSVC_FAIL) {
708 SLOGE("Failed to verify p12 certificate.");
714 int tempCertNum = sk_X509_num(certv);
718 nicerts = static_cast<size_t>(tempCertNum);
723 if (cvaluev != NULL) {
724 for (i = 0; i < n; i++)
726 if (cvaluev) free(cvaluev);
730 cvaluev = (char **)calloc(1 + nicerts, sizeof(char *));
731 if (unique != NULL) { free(unique); unique = NULL; }
732 result = unique_filename(&unique);
733 if (result != CERTSVC_SUCCESS || !unique) {
734 SLOGE("Unique filename generation failed.");
738 if ((stream = fopen(unique, "w+")) == NULL) {
739 SLOGE("Unable to open the file for writing [%s].",unique);
740 result = CERTSVC_IO_ERROR;
744 result = PEM_write_PrivateKey(stream, key, NULL, NULL, 0, NULL, NULL);
746 SLOGE("Writing the private key contents failed.");
747 result = CERTSVC_FAIL;
752 fseek(stream, 0, SEEK_SET);
753 memset(fileBuffer, 0, (sizeof(char)*4096));
755 readLen = fread(fileBuffer, sizeof(char), 4096, stream);
758 SLOGE("Failed to read key file");
759 result = CERTSVC_FAIL;
763 bare = bare_filename(unique);
765 pkvalue = strdup(bare);
766 tmpLen = strlen((const char*)pkvalue);
767 tmpPkValue = (char*)malloc(sizeof(char) * (tmpLen + 1));
768 memset(tmpPkValue, 0x00, tmpLen+1);
769 memcpy(tmpPkValue, pkvalue, tmpLen);
772 decideCert = P12_PKEY;
773 result = vcore_client_install_certificate_to_store(storeType, tmpPkValue, NULL, NULL, NULL, fileBuffer, readLen, decideCert);
774 if (result != CERTSVC_SUCCESS) {
775 SLOGD("Failed to store the private key contents.");
776 result = CERTSVC_FAIL;
781 if (unique!=NULL) { free(unique); unique=NULL; }
782 result = unique_filename(&unique);
783 if (result != CERTSVC_SUCCESS || !unique) {
784 SLOGE("Unique filename generation failed.");
788 if ((stream = fopen(unique, "w")) == NULL) {
789 SLOGE("Unable to open the file for writing [%s].", unique);
790 result = CERTSVC_IO_ERROR;
794 result = PEM_write_X509(stream, cert);
797 SLOGE("Failed to write contents to file.");
798 result = CERTSVC_FAIL;
803 bare = bare_filename(unique);
805 cvaluev[n++] = strdup(bare);
807 decideCert = P12_END_USER;
808 wr_res = install_crt_file(unique, storeType, alias, tmpPkValue, NULL, decideCert);
809 if (wr_res != CERTSVC_SUCCESS) {
810 result = CERTSVC_FAIL;
811 SLOGE("Failed to install the end user certificate.");
816 for (i=nicerts; i>0; i--) {
817 result = unique_filename(&unique);
818 if (result != CERTSVC_SUCCESS || !unique) {
819 SLOGE("Unique filename generation failed.");
823 if ((stream = fopen(unique, "w")) == NULL) {
824 result = CERTSVC_IO_ERROR;
825 SLOGE("Unable to open the file for writing.");
829 result = PEM_write_X509_AUX(stream, sk_X509_value(certv, i-1));
832 result = CERTSVC_FAIL;
833 SLOGE("Unable to extract the certificates.");
838 decideCert = P12_INTERMEDIATE;
840 decideCert = P12_TRUSTED;
841 wr_res = install_crt_file(unique, storeType, alias, NULL, cvaluev[0], decideCert);
842 if (wr_res != CERTSVC_SUCCESS) {
843 result = CERTSVC_FAIL;
848 bare = bare_filename(unique);
850 cvaluev[n++] = strdup(bare);
857 /* if any certificate parsing/installation fails in middle,
858 * the below logic will delete the chain installed in DB */
859 if (result != CERTSVC_SUCCESS) {
860 SLOG(LOG_INFO, "MDM_LOG_USER", "Object=certificate, AccessType=Install, Result=Failed");
863 /* cvaluev[0] holds the end user certificate identifier which will be associated
864 * to chain certs. Pull the cert chain based on end user cert and delete one by one. */
865 if (c_certsvc_pkcs12_load_certificates_from_store(storeType, cvaluev[0], &certs, &ncerts) != CERTSVC_SUCCESS) {
866 SLOGE("Unable to load certificates from store.");
870 for (i=0; i<ncerts; i++) {
871 if (certs[i] != NULL) {
872 SLOGD("file to delete : %s",certs[i]);
873 c_certsvc_pkcs12_delete_certificate_from_store(storeType, (char *)certs[i]);
877 if (certs[i] != NULL) {
878 for (i=0; i<ncerts; i++)
884 SLOG(LOG_INFO, "MDM_LOG_USER", "Object=certificate, AccessType=Install, Result=Succeed");
886 if (key != NULL) EVP_PKEY_free(key);
887 if (cert != NULL) X509_free(cert);
888 if (certv != NULL) sk_X509_free(certv);
889 if (pkvalue != NULL) free(pkvalue);
890 if (tmpPkValue != NULL) free(tmpPkValue);
891 if (unique != NULL) free(unique);
895 int c_certsvc_pkcs12_has_password(const char *filepath, int *passworded)
903 if(passworded == NULL)
904 return CERTSVC_WRONG_ARGUMENT;
905 if((stream = fopen(filepath, "rb")) == NULL)
906 return CERTSVC_IO_ERROR;
907 container = d2i_PKCS12_fp(stream, NULL);
909 if(container == NULL)
911 result = PKCS12_parse(container, NULL, &pkey, &cert, NULL);
912 PKCS12_free(container);
917 return CERTSVC_SUCCESS;
920 if(ERR_GET_REASON(ERR_peek_last_error()) == PKCS12_R_MAC_VERIFY_FAILURE) {
922 return CERTSVC_SUCCESS;
929 void c_certsvc_pkcs12_free_certificates(char **certs)