static xmlSecKeysMngrPtr getKeyManager(VALUE rb_certs) { int i, numCerts = RARRAY_LEN(rb_certs); xmlSecKeysMngrPtr keyManager = xmlSecKeysMngrCreate(); VALUE rb_cert; char *cert; unsigned int certLength; int numSuccessful = 0; if (keyManager == NULL) return NULL; if (xmlSecCryptoAppDefaultKeysMngrInit(keyManager) < 0) { rb_raise(rb_eKeystoreError, "could not initialize key manager"); xmlSecKeysMngrDestroy(keyManager); return NULL; } for (i = 0; i < numCerts; i++) { rb_cert = RARRAY_PTR(rb_certs)[i]; Check_Type(rb_cert, T_STRING); cert = RSTRING_PTR(rb_cert); certLength = RSTRING_LEN(rb_cert); if(xmlSecCryptoAppKeysMngrCertLoadMemory(keyManager, (xmlSecByte *)cert, certLength, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { rb_warn("failed to load certificate at index %d", i); } else { numSuccessful++; } } // note, numCerts could be zero, meaning that we should use system SSL certs if (numSuccessful == 0 && numCerts != 0) { rb_raise(rb_eKeystoreError, "Could not load any of the specified certificates for signature verification"); xmlSecKeysMngrDestroy(keyManager); return NULL; } return keyManager; }
//Could be used for many trusted certificates in string xmlSecKeysMngrPtr load_trusted_cert_str(xmlSecKeysMngrPtr* keys_manager, const std::string& cert_str) { xmlSecKeysMngrPtr keys_mngr; if((keys_manager != NULL) && (*keys_manager != NULL)) keys_mngr = *keys_manager; else { keys_mngr = xmlSecKeysMngrCreate(); //initialize keys manager if (xmlSecCryptoAppDefaultKeysMngrInit(keys_mngr)<0) { std::cerr<<"Can not initialize xmlSecKeysMngr object"<<std::endl; xmlSecKeysMngrDestroy(keys_mngr); return NULL; } } if(keys_mngr == NULL) { std::cerr<<"Can not create xmlSecKeysMngr object"<<std::endl; return NULL;} //load cert from memory if(!cert_str.empty()) if(xmlSecCryptoAppKeysMngrCertLoadMemory(keys_mngr, (const xmlSecByte*)(cert_str.c_str()), (xmlSecSize)(cert_str.size()), xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { xmlSecKeysMngrDestroy(keys_mngr); return NULL; } if(keys_manager != NULL) keys_manager = &keys_mngr; return keys_mngr; }
int xml_verify(char *filename) { xmlSecDSigCtxPtr dsig_ctx = NULL; xmlDocPtr doc = NULL; xmlNodePtr root_node; xmlNodePtr sign_node; xmlNodePtr cert_node; xmlNodePtr x509d_node; xmlNodePtr cur_node; int result = DCP_FATAL; xmlSecKeysMngrPtr key_manager; char cert[5000]; int cert_l; xmlsec_verify_init(); /* load doc file */ doc = xmlParseFile(filename); if (doc == NULL) { dcp_log(LOG_ERROR, "unable to parse file %s", filename); goto done; } /* find root node */ root_node = xmlDocGetRootElement(doc); if (root_node == NULL){ dcp_log(LOG_ERROR, "unable to find root node"); goto done; } /* find signature node */ sign_node = xmlSecFindNode(root_node, xmlSecNodeSignature, xmlSecDSigNs); if(sign_node == NULL) { dcp_log(LOG_ERROR, "signature node not found"); goto done; } /* create keys manager */ key_manager = load_certificates(); if (key_manager == NULL) { dcp_log(LOG_ERROR,"create key manager failed"); goto done; } /* find certificates */ cur_node = sign_node; while (x509d_node = xmlSecFindNode(cur_node, xmlSecNodeX509Data, xmlSecDSigNs)) { cert_node = xmlSecFindNode(x509d_node, xmlSecNodeX509Certificate, xmlSecDSigNs); if(cert_node == NULL) { dcp_log(LOG_ERROR, "X509certficate node not found"); goto done; } sprintf(cert,"-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n",xmlNodeGetContent(cert_node)); cert_l = strlen(cert); if (xmlSecCryptoAppKeysMngrCertLoadMemory(key_manager, cert, cert_l, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { dcp_log(LOG_ERROR, "could read X509certificate node value"); goto done; } cur_node = xmlNextElementSibling(x509d_node); } /* create signature context */ dsig_ctx = xmlSecDSigCtxCreate(key_manager); if (dsig_ctx == NULL) { dcp_log(LOG_ERROR,"create signature opendcp failed"); goto done; } /* sign the template */ if (xmlSecDSigCtxVerify(dsig_ctx, sign_node) < 0) { dcp_log(LOG_ERROR,"signature verify failed"); goto done; } if (dsig_ctx->status != xmlSecDSigStatusSucceeded) { dcp_log(LOG_ERROR,"signature validation failed"); goto done; } /* success */ result = 0; done: /* destroy keys manager */ xmlSecKeysMngrDestroy(key_manager); /* destroy signature context */ if(dsig_ctx != NULL) { xmlSecDSigCtxDestroy(dsig_ctx); } /* destroy xml doc */ if(doc != NULL) { xmlFreeDoc(doc); } xmlsec_close(); return(result); }
xmlSecKeysMngrPtr load_certificates_sign(opendcp_t *opendcp) { xmlSecKeysMngrPtr key_manager; xmlSecKeyPtr key; /* create and initialize keys manager */ key_manager = xmlSecKeysMngrCreate(); if (key_manager == NULL) { fprintf(stderr, "Error: failed to create keys manager.\n"); return(NULL); } if (xmlSecCryptoAppDefaultKeysMngrInit(key_manager) < 0) { fprintf(stderr, "Error: failed to initialize keys manager.\n"); xmlSecKeysMngrDestroy(key_manager); return(NULL); } /* read key file */ if (opendcp->xml_signature.private_key) { key = xmlSecCryptoAppKeyLoad(opendcp->xml_signature.private_key, xmlSecKeyDataFormatPem, NULL, NULL, NULL); } else { key = xmlSecCryptoAppKeyLoadMemory(opendcp_private_key, strlen((char *)opendcp_private_key),xmlSecKeyDataFormatPem, NULL, NULL, NULL); } if (xmlSecCryptoAppDefaultKeysMngrAdoptKey(key_manager, key) < 0) { fprintf(stderr, "Error: failed to initialize keys manager.\n"); xmlSecKeysMngrDestroy(key_manager); return(NULL); } /* load root certificate */ if (opendcp->xml_signature.root) { if (xmlSecCryptoAppKeysMngrCertLoad(key_manager, opendcp->xml_signature.root, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { fprintf(stderr,"Error: failed to load pem certificate \"%s\"\n", opendcp->xml_signature.root); xmlSecKeysMngrDestroy(key_manager); return(NULL); } } else { if (xmlSecCryptoAppKeysMngrCertLoadMemory(key_manager, opendcp_root_cert, strlen((char* )opendcp_root_cert), xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { fprintf(stderr,"Error: failed to load pem certificate from memory\n"); xmlSecKeysMngrDestroy(key_manager); return(NULL); } } /* load ca (intermediate) certificate */ if (opendcp->xml_signature.ca) { if (xmlSecCryptoAppKeysMngrCertLoad(key_manager, opendcp->xml_signature.ca, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { fprintf(stderr,"Error: failed to load pem certificate \"%s\"\n", opendcp->xml_signature.ca); xmlSecKeysMngrDestroy(key_manager); return(NULL); } } else { if (xmlSecCryptoAppKeysMngrCertLoadMemory(key_manager, opendcp_ca_cert, strlen((char *)opendcp_ca_cert), xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { fprintf(stderr,"Error: failed to load pem certificate from memory\n"); xmlSecKeysMngrDestroy(key_manager); return(NULL); } } return(key_manager); }
xmlSecKeysMngrPtr load_trusted_certs(const char** files) { const char **f; xmlSecKeysMngrPtr mngr, mngr_test; char valid_cert; FILE *file; char *pi, *pf, *data; size_t size; char **a, *all_files[10000]; struct stat stat_struct; DIR *dir; struct dirent *dir_file; char name[10000]; assert(files); /* Create keys manager */ mngr = xmlSecKeysMngrCreate(); if(mngr == NULL) { fprintf(stderr, "XmlSecError: failed to create keys manager.\n"); return(NULL); } if(xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) { fprintf(stderr, "XmlSecError: failed to initialize keys manager.\n"); xmlSecKeysMngrDestroy(mngr); return(NULL); } /* Create a list of files scanning directories */ for (f = files, a = all_files; *f; f++) { if (stat(*f, &stat_struct)) perror(*f); else if (S_ISDIR(stat_struct.st_mode)) { dir = opendir(*f); while ((dir_file = readdir(dir))) { sprintf(name, "%s/%s", *f, dir_file->d_name); if (stat(name, &stat_struct)) perror(name); else if (!(S_ISDIR(stat_struct.st_mode))) *(a++) = strdup(name); } closedir(dir); } else *(a++) = strdup(*f); } *a = NULL; /* Open each file, read data and add the certificates to keys manager, because * when load from file directly, just add the first certificate, then we need * read data and add each certificate in it. Other problem is when I have a invalid * certificate, the manager brokes, then I test with a other manager. */ for (a = all_files; *a; a++) { /* Open a file and read content data */ file = fopen(*a, "r"); if (file == NULL){ perror(*a); free(*a); continue; } fseek(file, 0, SEEK_END); size = ftell(file); fseek(file, 0, SEEK_SET); data = (char*)malloc(size + 1); fread(data, size, 1, file); fclose(file); data[size] = '\0'; /* Set pi to start of certificate and pf to end */ pf = pi = data; pf = strstr(pi, "-----END CERTIFICATE-----"); if (!pf) pf = pi + size; while (pf) { /* Test manager for test the certificate */ mngr_test = xmlSecKeysMngrCreate(); valid_cert = 1; if(mngr_test == NULL) { fprintf(stderr, "XmlSecError: failed to create keys manager.\n"); valid_cert = 0; } else if(xmlSecCryptoAppDefaultKeysMngrInit(mngr_test) < 0) { fprintf(stderr, "XmlSecError: failed to initialize keys manager.\n"); valid_cert = 0; } else if (xmlSecCryptoAppKeysMngrCertLoadMemory(mngr_test, (xmlSecByte*)pi, pf - pi + 25, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { fprintf(stderr,"XmlSecError: failed to load pem certificate from \"%s\" at %i.\n", *a, pi - data + 1); valid_cert = 0; } xmlSecKeysMngrDestroy(mngr_test); /* If certificate is valid, add this to keys manager for future use */ if (valid_cert && xmlSecCryptoAppKeysMngrCertLoadMemory( mngr, (xmlSecByte*)pi, pf - pi + 25, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) fprintf(stderr,"XmlSecError: maybe duplicate pem certificate from \"%s\" at %i.\n", *a, pi - data + 1); pi = pf + 25; pf = strstr(pi, "-----END CERTIFICATE-----"); } /* Free allocated memory */ free(*a); free(data); } return(mngr); }