/** * verify_file: * @mngr: the pointer to keys manager. * @xml_file: the signed XML file name. * * Verifies XML signature in #xml_file. * * Returns 0 on success or a negative value if an error occurs. */ int verify_file(xmlSecKeysMngrPtr mngr, const char* xml_file) { xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; int res = -1; assert(mngr); assert(xml_file); /* load file */ doc = xmlParseFile(xml_file); if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_file); goto done; } /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { fprintf(stderr, "Error: start node not found in \"%s\"\n", xml_file); goto done; } /* create signature context */ dsigCtx = xmlSecDSigCtxCreate(mngr); if(dsigCtx == NULL) { fprintf(stderr,"Error: failed to create signature context\n"); goto done; } /* Verify signature */ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { fprintf(stderr,"Error: signature verify\n"); goto done; } /* print verification result to stdout */ if(dsigCtx->status == xmlSecDSigStatusSucceeded) { fprintf(stdout, "Signature is OK\n"); } else { fprintf(stdout, "Signature is INVALID\n"); } /* success */ res = 0; done: /* cleanup */ if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } if(doc != NULL) { xmlFreeDoc(doc); } return(res); }
VALUE xmlsec_is_valid_by_key(VALUE self, xmlDocPtr doc, VALUE key_file ) { xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: start node not found\n"); return Qnil; } /* create signature context*/ dsigCtx = xmlSecDSigCtxCreate(NULL); if(dsigCtx == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to create signature context\n"); return Qnil; } dsigCtx->enabledReferenceUris = xmlSecTransformUriTypeEmpty; /* load public key */ dsigCtx->signKey = xmlSecCryptoAppKeyLoad(StringValuePtr(key_file), xmlSecKeyDataFormatPem, NULL, NULL, NULL); if(dsigCtx->signKey == NULL) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to load public pem key from \"%s\"\n", StringValuePtr(key_file)); return Qnil; } /* set key name to the file name*/ if(xmlSecKeySetName(dsigCtx->signKey, StringValuePtr(key_file)) < 0) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to set key name for key from \"%s\"\n", StringValuePtr(key_file)); return Qnil; } /* Verify signature */ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: signature verify \"%s\"\n"); return Qnil; } /* verification result*/ if(dsigCtx->status == xmlSecDSigStatusSucceeded) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); return Qtrue; } else { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); return Qfalse; } }
int verify_xml(xmlSecKeysMngrPtr mngr, const char* xml_string, const char* id_attr_name, const char* id_node_name) { xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; int res = -1; assert(mngr); assert(xml_string); /* load template */ doc = xmlParseDoc((xmlChar*)xml_string); if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ fprintf(stderr, "XmlSecError: unable to parse xml string\n"); goto done2; } /* add id */ if (id_attr_name && id_node_name) xmlSecAppAddIDAttr(xmlDocGetRootElement(doc), (xmlChar*)id_attr_name, (xmlChar*)id_node_name, NULL); /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { fprintf(stderr, "XmlSecError: start node not found in xml string\n"); goto done2; } /* create signature context */ dsigCtx = xmlSecDSigCtxCreate(mngr); if(dsigCtx == NULL) { fprintf(stderr,"XmlSecError: failed to create signature context\n"); goto done2; } /* Verify signature */ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { fprintf(stderr,"XmlSecError: signature verify\n"); goto done2; } res = (dsigCtx->status == xmlSecDSigStatusSucceeded); done2: /* cleanup */ if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } if(doc != NULL) { xmlFreeDoc(doc); } return(res); }
VALUE verify_signature_with_certificates(VALUE self, VALUE rb_certs) { xmlDocPtr doc; xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; xmlSecKeysMngrPtr keyManager = NULL; VALUE result = Qfalse; Check_Type(rb_certs, T_ARRAY); Data_Get_Struct(self, xmlDoc, doc); // find start node node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { rb_raise(rb_eVerificationError, "start node not found"); goto done; } keyManager = getKeyManager(rb_certs); if (keyManager == NULL) { rb_raise(rb_eKeystoreError, "failed to create key manager"); goto done; } // create signature context, we don't need keys manager in this example dsigCtx = xmlSecDSigCtxCreate(keyManager); if(dsigCtx == NULL) { rb_raise(rb_eVerificationError, "failed to create signature context"); goto done; } // verify signature if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { rb_raise(rb_eVerificationError, "error occurred during signature verification"); goto done; } if(dsigCtx->status == xmlSecDSigStatusSucceeded) { result = Qtrue; } done: if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } if (keyManager != NULL) { xmlSecKeysMngrDestroy(keyManager); } return result; }
int verify_document(xmlDocPtr doc, const char* key) { initialize(); xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; int res = 0; if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ rb_raise(rb_eRuntimeError, "unable to parse XML document"); } /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { rb_raise(rb_eRuntimeError, "could not find start node in XML document"); } if(assign_id_attributes(doc) < 0) { rb_raise(rb_eRuntimeError, "Could not find ID attribute in document"); } /* create signature context */ dsigCtx = xmlSecDSigCtxCreate(NULL); if(dsigCtx == NULL) { cleanup(dsigCtx); rb_raise(rb_eRuntimeError, "could not create signature context"); } /* load public key */ dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory(key, strlen(key), xmlSecKeyDataFormatCertPem, NULL, NULL, NULL); if(dsigCtx->signKey == NULL) { cleanup(dsigCtx); rb_raise(rb_eRuntimeError, "could not read public pem key %s", key); } /* Verify signature */ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { cleanup(dsigCtx); rb_raise(rb_eRuntimeError, "Document does not seem to be in an XMLDsig format"); } /* print verification result to stdout */ if(dsigCtx->status == xmlSecDSigStatusSucceeded) { res = 1; } else { res = 0; } cleanup(dsigCtx); return res; }
PyObject *xmlsec_DSigCtxCreate(PyObject *self, PyObject *args) { PyObject *mngr_obj; xmlSecKeysMngrPtr mngr = NULL; xmlSecDSigCtxPtr dsigCtx; if (CheckArgs(args, "o:dsigCtxCreate")) { if(!PyArg_ParseTuple(args, (char *) "O:dsigCtxCreate", &mngr_obj)) return NULL; } else return NULL; mngr = xmlSecKeysMngrPtr_get(mngr_obj); dsigCtx = xmlSecDSigCtxCreate(mngr); return (wrap_xmlSecDSigCtxPtr(dsigCtx)); }
VALUE xmlsec_is_valid(VALUE self, xmlDocPtr doc) { xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: start node not found\n"); return Qnil; } /* create signature context*/ dsigCtx = xmlSecDSigCtxCreate(NULL); if(dsigCtx == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to create signature context\n"); return Qnil; } dsigCtx->enabledReferenceUris = xmlSecTransformUriTypeEmpty; /* Verify signature */ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: signature verify \"%s\"\n"); return Qnil; } /* verification result*/ if(dsigCtx->status == xmlSecDSigStatusSucceeded) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); return Qtrue; } else { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); return Qfalse; } }
int xml_sign(opendcp_t *opendcp, char *filename) { xmlSecDSigCtxPtr dsig_ctx = NULL; xmlDocPtr doc = NULL; xmlNodePtr root_node; xmlNodePtr sign_node; FILE *fp; int result = OPENDCP_ERROR; xmlSecKeysMngrPtr key_manager = NULL; dcp_log(LOG_DEBUG, "xml_sign: xmlsec_init"); xmlsec_init(); /* load doc file */ dcp_log(LOG_DEBUG, "xml_sign: parse file"); doc = xmlParseFile(filename); if (doc == NULL) { dcp_log(OPENDCP_ERROR, "Error: unable to parse file %s", filename); goto done; } /* find root node */ root_node = xmlDocGetRootElement(doc); if (root_node == NULL){ dcp_log(OPENDCP_ERROR, "Error: unable to find root node"); goto done; } /* find signature node */ sign_node = xmlSecFindNode(root_node, xmlSecNodeSignature, xmlSecDSigNs); if(sign_node == NULL) { fprintf(stderr, "Error: start node not found"); goto done; } /* create keys manager */ key_manager = load_certificates_sign(opendcp); if (key_manager == NULL) { fprintf(stderr,"Error: failed to create key manager\n"); goto done; } /* create signature opendcp */ dsig_ctx = xmlSecDSigCtxCreate(key_manager); if(dsig_ctx == NULL) { fprintf(stderr,"Error: failed to create signature opendcp\n"); goto done; } /* sign the template */ if(xmlSecDSigCtxSign(dsig_ctx, sign_node) < 0) { fprintf(stderr,"Error: signature failed\n"); goto done; } /* open xml file */ fp = fopen(filename,"wb"); if (fp == NULL) { fprintf(stderr,"Error: could not open output file\n"); goto done; } /* write the xml file */ if (xmlDocDump(fp, doc) < 0) { fprintf(stderr,"Error: writing XML document failed\n"); goto done; } /* close the file */ fclose(fp); /* 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); }
static PyObject* sign_xml(const char* xml_string, const char* key_file, const char* cert_file, const char* id_attr_name, const char* id_node_name) { xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; xmlChar *signed_xml; int size; PyObject *result; assert(xml_string); assert(key_file); assert(cert_file); /* load template */ doc = xmlParseDoc((xmlChar*)xml_string); if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ fprintf(stderr, "XmlSecError: unable to parse xml string!\n"); goto done; } /* add id */ if (id_attr_name && id_node_name && *id_attr_name != '\0' && *id_node_name != '\0') xmlSecAppAddIDAttr(xmlDocGetRootElement(doc), (xmlChar*)id_attr_name, (xmlChar*)id_node_name, NULL); /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { fprintf(stderr, "XmlSecError: start node <Signature> not found in xml string\n"); goto done; } /* create signature context, we don't need keys manager in this example */ dsigCtx = xmlSecDSigCtxCreate(NULL); if(dsigCtx == NULL) { fprintf(stderr,"XmlSecError: failed to create signature context\n"); goto done; } /* load private key, assuming that there is not password */ dsigCtx->signKey = xmlSecCryptoAppKeyLoad(key_file, xmlSecKeyDataFormatPem, NULL, NULL, NULL); if(dsigCtx->signKey == NULL) { fprintf(stderr,"XmlSecError: failed to load private pem key from \"%s\"\n", key_file); goto done; } /* set key name to the file name */ if(xmlSecKeySetName(dsigCtx->signKey, (xmlChar*)key_file) < 0) { fprintf(stderr,"XmlSecError: failed to set key name for key from \"%s\"\n", key_file); goto done; } /* set cert name to the file name */ if(xmlSecCryptoAppKeyCertLoad(dsigCtx->signKey, cert_file, xmlSecKeyDataFormatPem) < 0) { fprintf(stderr,"XmlSecError: failed to set cert name for cert from \"%s\"\n", cert_file); goto done; } /* sign the template */ if(xmlSecDSigCtxSign(dsigCtx, node) < 0) { fprintf(stderr,"XmlSecError: signature failed\n"); goto done; } done: /* cleanup */ if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } if(doc != NULL) { xmlDocDumpMemory(doc, &signed_xml, &size); result = Py_BuildValue("s", signed_xml); xmlFree(signed_xml); xmlFreeDoc(doc); } else { result = Py_BuildValue("s", NULL); } return result; }
VALUE sign_with_certificate(VALUE self, VALUE rb_key_name, VALUE rb_rsa_key, VALUE rb_cert) { xmlDocPtr doc; xmlNodePtr signNode = NULL; xmlNodePtr refNode = NULL; xmlNodePtr keyInfoNode = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; char *keyName; char *certificate; char *rsaKey; unsigned int rsaKeyLength, certificateLength; Data_Get_Struct(self, xmlDoc, doc); rsaKey = RSTRING_PTR(rb_rsa_key); rsaKeyLength = RSTRING_LEN(rb_rsa_key); keyName = RSTRING_PTR(rb_key_name); certificate = RSTRING_PTR(rb_cert); certificateLength = RSTRING_LEN(rb_cert); // create signature template for RSA-SHA1 enveloped signature signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId, xmlSecTransformRsaSha1Id, NULL); if (signNode == NULL) { rb_raise(rb_eSigningError, "failed to create signature template"); goto done; } // add <dsig:Signature/> node to the doc xmlAddChild(xmlDocGetRootElement(doc), signNode); // add reference refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id, NULL, NULL, NULL); if(refNode == NULL) { rb_raise(rb_eSigningError, "failed to add reference to signature template"); goto done; } // add enveloped transform if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL) { rb_raise(rb_eSigningError, "failed to add enveloped transform to reference"); goto done; } // add <dsig:KeyInfo/> and <dsig:X509Data/> keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL); if(keyInfoNode == NULL) { rb_raise(rb_eSigningError, "failed to add key info"); goto done; } if(xmlSecTmplKeyInfoAddX509Data(keyInfoNode) == NULL) { rb_raise(rb_eSigningError, "failed to add X509Data node"); goto done; } // create signature context, we don't need keys manager in this example dsigCtx = xmlSecDSigCtxCreate(NULL); if(dsigCtx == NULL) { rb_raise(rb_eSigningError, "failed to create signature context"); goto done; } // load private key, assuming that there is not password dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)rsaKey, rsaKeyLength, xmlSecKeyDataFormatPem, NULL, // password NULL, NULL); if(dsigCtx->signKey == NULL) { rb_raise(rb_eSigningError, "failed to load private key"); goto done; } // load certificate and add to the key if(xmlSecCryptoAppKeyCertLoadMemory(dsigCtx->signKey, (xmlSecByte *)certificate, certificateLength, xmlSecKeyDataFormatPem) < 0) { rb_raise(rb_eSigningError, "failed to load certificate"); goto done; } // set key name if(xmlSecKeySetName(dsigCtx->signKey, (xmlSecByte *)keyName) < 0) { rb_raise(rb_eSigningError, "failed to set key name"); goto done; } // sign the template if(xmlSecDSigCtxSign(dsigCtx, signNode) < 0) { rb_raise(rb_eSigningError, "signature failed"); goto done; } done: if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } return T_NIL; }
/** * verify_request: * @mng: the keys manager * * Verifies XML signature in the request (stdin). * * Returns 0 on success or a negative value if an error occurs. */ int verify_request(xmlSecKeysMngrPtr mngr) { xmlBufferPtr buffer = NULL; char buf[256]; xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; int ret; int res = -1; assert(mngr); /* load request in the buffer */ buffer = xmlBufferCreate(); if(buffer == NULL) { fprintf(stdout,"Error: failed to create buffer\n"); goto done; } while(!feof(stdin)) { ret = fread(buf, 1, sizeof(buf), stdin); if(ret < 0) { fprintf(stdout,"Error: read failed\n"); goto done; } xmlBufferAdd(buffer, buf, ret); } /* is the document subbmitted from the form? */ if(strncmp((char*)xmlBufferContent(buffer), "_xmldoc=", 8) == 0) { xmlBufferShrink(buffer, 8); buffer->use = url_decode((char*)xmlBufferContent(buffer), xmlBufferLength(buffer)); } /** * Load doc */ doc = xmlReadMemory(xmlBufferContent(buffer), xmlBufferLength(buffer), NULL, NULL, XML_PARSE_NOENT | XML_PARSE_NOCDATA | XML_PARSE_PEDANTIC | XML_PARSE_NOCDATA); if (doc == NULL) { fprintf(stdout, "Error: unable to parse xml document (syntax error)\n"); goto done; } /* * Check the document is of the right kind */ if(xmlDocGetRootElement(doc) == NULL) { fprintf(stdout,"Error: empty document\n"); goto done; } /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { fprintf(stdout, "Error: start <dsig:Signature/> node not found\n"); goto done; } /* create signature context */ dsigCtx = xmlSecDSigCtxCreate(mngr); if(dsigCtx == NULL) { fprintf(stdout,"Error: failed to create signature context\n"); goto done; } /* we would like to store and print out everything */ /* actually we would not because it opens a security hole dsigCtx->flags = XMLSEC_DSIG_FLAGS_STORE_SIGNEDINFO_REFERENCES | XMLSEC_DSIG_FLAGS_STORE_MANIFEST_REFERENCES | XMLSEC_DSIG_FLAGS_STORE_SIGNATURE; */ /* Verify signature */ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { fprintf(stdout,"Error: signature verification failed\n"); goto done; } /* print verification result to stdout */ if(dsigCtx->status == xmlSecDSigStatusSucceeded) { fprintf(stdout, "RESULT: Signature is OK\n"); } else { fprintf(stdout, "RESULT: Signature is INVALID\n"); } fprintf(stdout, "---------------------------------------------------\n"); xmlSecDSigCtxDebugDump(dsigCtx, stdout); /* success */ res = 0; done: /* cleanup */ if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } if(doc != NULL) { xmlFreeDoc(doc); } if(buffer != NULL) { xmlBufferFree(buffer); } return(res); }
/** * Funkcja dokonuje weryfikacji poprawności złożonego podpisu pod formularzem. * \param[in] mngr Zainicjalizowany menedżer kluczy. * \param[in] buffer Formularz do zweryfikowania. * \param[in] buffer_len Długość weryfikowanego formularza. * * \retval 0 Podpis poprawny. * \retval 1 Podpis niepoprawny. * \retval -1 Nie można przeparsować dokumentu. * \retval -2 Nie znaleziono startowego węzła. * \retval -3 Nie dało się utworzyć kontekstu podpisu. * \retval -4 Nie dało rady zweryfikować podpisu. * */ static long verify_memory(xmlSecKeysMngrPtr mngr, const char* buffer, const long buffer_len) { xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; long ret = -99; assert(mngr); /* load file */ doc = xmlParseMemory(buffer,buffer_len); if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ PRINT_DEBUG("UNABLE TO PARSE DOCUMENT\n"); ret = -1; goto done; } /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { PRINT_DEBUG("Start node %s not found\n",xmlSecNodeSignature); ret = -2; goto done; } /* create signature context */ dsigCtx = xmlSecDSigCtxCreate(mngr); if(dsigCtx == NULL) { PRINT_DEBUG("Failed to create signature context\n"); ret = -3; goto done; } /* Verify signature */ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { PRINT_DEBUG("Error: signature verify failed\n"); ret = -4; goto done; } /* print verification result to stdout */ if(dsigCtx->status == xmlSecDSigStatusSucceeded) { ret = 0; PRINT_DEBUG("XAdES: Signature is OK\n"); } else { ret = 1; PRINT_DEBUG("XAdES: Signature is INVALID\n"); } done: /* cleanup */ if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } if(doc != NULL) { xmlFreeDoc(doc); } return(ret); }
/** * verify_file: * @mngr: the pointer to keys manager. * @xml_file: the signed XML file name. * * Verifies XML signature in #xml_file. * * Returns 0 on success or a negative value if an error occurs. */ int verify_file(xmlSecKeysMngrPtr mngr, const char* xml_file) { xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; int res = -1; assert(mngr); assert(xml_file); /* load file */ doc = xmlParseFile(xml_file); if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_file); goto done; } /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { fprintf(stderr, "Error: start node not found in \"%s\"\n", xml_file); goto done; } /* create signature context */ dsigCtx = xmlSecDSigCtxCreate(mngr); if(dsigCtx == NULL) { fprintf(stderr,"Error: failed to create signature context\n"); goto done; } /* limit the Reference URI attributes to empty or NULL */ dsigCtx->enabledReferenceUris = xmlSecTransformUriTypeEmpty; /* limit allowed transforms for signature and reference processing */ if((xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformInclC14NId) < 0) || (xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformExclC14NId) < 0) || (xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformSha1Id) < 0) || (xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformRsaSha1Id) < 0)) { fprintf(stderr,"Error: failed to limit allowed signature transforms\n"); goto done; } if((xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformInclC14NId) < 0) || (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformExclC14NId) < 0) || (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformSha1Id) < 0) || (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformEnvelopedId) < 0)) { fprintf(stderr,"Error: failed to limit allowed reference transforms\n"); goto done; } /* in addition, limit possible key data to valid X509 certificates only */ if(xmlSecPtrListAdd(&(dsigCtx->keyInfoReadCtx.enabledKeyData), BAD_CAST xmlSecKeyDataX509Id) < 0) { fprintf(stderr,"Error: failed to limit allowed key data\n"); goto done; } /* Verify signature */ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { fprintf(stderr,"Error: signature verify\n"); goto done; } /* check that we have only one Reference */ if((dsigCtx->status == xmlSecDSigStatusSucceeded) && (xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) != 1)) { fprintf(stderr,"Error: only one reference is allowed\n"); goto done; } /* print verification result to stdout */ if(dsigCtx->status == xmlSecDSigStatusSucceeded) { fprintf(stdout, "Signature is OK\n"); } else { fprintf(stdout, "Signature is INVALID\n"); } /* success */ res = 0; done: /* cleanup */ if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } if(doc != NULL) { xmlFreeDoc(doc); } return(res); }
/** * sign_file: * @tmpl_file: the signature template file name. * @key_file: the PEM private key file name. * * Signs the #tmpl_file using private key from #key_file. * * Returns 0 on success or a negative value if an error occurs. */ int sign_file(const char* tmpl_file, const char* key_file) { xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; int res = -1; assert(tmpl_file); assert(key_file); /* load template */ doc = xmlParseFile(tmpl_file); if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ fprintf(stderr, "Error: unable to parse file \"%s\"\n", tmpl_file); goto done; } /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { fprintf(stderr, "Error: start node not found in \"%s\"\n", tmpl_file); goto done; } /* create signature context, we don't need keys manager in this example */ dsigCtx = xmlSecDSigCtxCreate(NULL); if(dsigCtx == NULL) { fprintf(stderr,"Error: failed to create signature context\n"); goto done; } /* load private key, assuming that there is not password */ dsigCtx->signKey = xmlSecCryptoAppKeyLoad(key_file, xmlSecKeyDataFormatPem, NULL, NULL, NULL); if(dsigCtx->signKey == NULL) { fprintf(stderr,"Error: failed to load private pem key from \"%s\"\n", key_file); goto done; } /* set key name to the file name, this is just an example! */ if(xmlSecKeySetName(dsigCtx->signKey, key_file) < 0) { fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file); goto done; } /* sign the template */ if(xmlSecDSigCtxSign(dsigCtx, node) < 0) { fprintf(stderr,"Error: signature failed\n"); goto done; } /* print signed document to stdout */ xmlDocDump(stdout, doc); /* success */ res = 0; done: /* cleanup */ if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } if(doc != NULL) { xmlFreeDoc(doc); } return(res); }
VALUE xmlsec_is_valid_by_x509_file(VALUE self, xmlDocPtr doc, VALUE x509_file ) { xmlSecKeysMngrPtr mngr; VALUE v; xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; long i; mngr = xmlSecKeysMngrCreate(); if(mngr == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to create keys manager.\n"); return Qnil; } if(xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) { if(doc != NULL) xmlFreeDoc(doc); if(mngr != NULL) xmlSecKeysMngrDestroy(mngr); rb_raise(rb_eRuntimeError, "Error: failed to initialize keys manager.\n"); return Qnil; } if (TYPE(x509_file) == T_STRING){ /* load trusted cert */ if(xmlSecCryptoAppKeysMngrCertLoad(mngr, StringValuePtr(x509_file), xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { if(doc != NULL) xmlFreeDoc(doc); if(mngr != NULL) xmlSecKeysMngrDestroy(mngr); rb_raise(rb_eRuntimeError, "Error: failed to load pem certificate from \"%s\"\n", StringValuePtr(x509_file)); return Qnil; } } if (TYPE(x509_file) == T_ARRAY) { for (i =0; i < RARRAY_LEN(x509_file); i++) { v = rb_ary_entry(x509_file, i); StringValue(v); if(xmlSecCryptoAppKeysMngrCertLoad(mngr, RSTRING_PTR(v), xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { if(doc != NULL) xmlFreeDoc(doc); if(mngr != NULL) xmlSecKeysMngrDestroy(mngr); rb_raise(rb_eRuntimeError, "Error: failed to load pem certificate from \"%s\"\n", RSTRING_PTR(v)); return Qnil; } } //rb_ary_entry } /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: start node not found\n"); return Qnil; } /* create signature context*/ dsigCtx = xmlSecDSigCtxCreate(mngr); if(dsigCtx == NULL) { if(doc != NULL) xmlFreeDoc(doc); if(mngr != NULL) xmlSecKeysMngrDestroy(mngr); rb_raise(rb_eRuntimeError, "Error: failed to create signature context\n"); return Qnil; } /* limit the Reference URI attributes to empty or NULL */ dsigCtx->enabledReferenceUris = xmlSecTransformUriTypeEmpty; /* Verify signature */ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); if(mngr != NULL) xmlSecKeysMngrDestroy(mngr); rb_raise(rb_eRuntimeError, "Error: signature verify \"%s\"\n"); return Qnil; } /* verification result*/ if(dsigCtx->status == xmlSecDSigStatusSucceeded) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); if(mngr != NULL) xmlSecKeysMngrDestroy(mngr); return Qtrue; } else { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); if(mngr != NULL) xmlSecKeysMngrDestroy(mngr); return Qfalse; } }
/** * sign_file: * @xml_file: the XML file name. * @key_file: the PEM private key file name. * * Signs the #xml_file using private key from #key_file and dynamicaly * created enveloped signature template. * * Returns 0 on success or a negative value if an error occurs. */ int sign_file(const char* xml_file, const char* key_file) { xmlDocPtr doc = NULL; xmlNodePtr signNode = NULL; xmlNodePtr refNode = NULL; xmlNodePtr keyInfoNode = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; int res = -1; assert(xml_file); assert(key_file); /* load doc file */ doc = xmlParseFile(xml_file); if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ printf_a_ignorar3(stderr, "Error: unable to parse file \"%s\"\n", xml_file); goto done; } /* create signature template for RSA-SHA1 enveloped signature */ signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId, xmlSecTransformRsaSha1Id, NULL); if(signNode == NULL) { printf_a_ignorar3(stderr, "Error: failed to create signature template\n"); goto done; } /* add <dsig:Signature/> node to the doc */ xmlAddChild(xmlDocGetRootElement(doc), signNode); /* add reference */ refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id, NULL, NULL, NULL); if(refNode == NULL) { printf_a_ignorar3(stderr, "Error: failed to add reference to signature template\n"); goto done; } /* add enveloped transform */ if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL) { printf_a_ignorar3(stderr, "Error: failed to add enveloped transform to reference\n"); goto done; } /* add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to put key name in the signed document */ keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL); if(keyInfoNode == NULL) { printf_a_ignorar3(stderr, "Error: failed to add key info\n"); goto done; } if(xmlSecTmplKeyInfoAddKeyName(keyInfoNode, NULL) == NULL) { printf_a_ignorar3(stderr, "Error: failed to add key name\n"); goto done; } /* create signature context, we don't need keys manager in this example */ dsigCtx = xmlSecDSigCtxCreate(NULL); if(dsigCtx == NULL) { printf_a_ignorar3(stderr,"Error: failed to create signature context\n"); goto done; } /* load private key, assuming that there is not password */ dsigCtx->signKey = xmlSecCryptoAppKeyLoad(key_file, xmlSecKeyDataFormatPem, NULL, NULL, NULL); if(dsigCtx->signKey == NULL) { printf_a_ignorar3(stderr,"Error: failed to load private pem key from \"%s\"\n", key_file); goto done; } /* set key name to the file name, this is just an example! */ if(xmlSecKeySetName(dsigCtx->signKey, key_file) < 0) { printf_a_ignorar3(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file); goto done; } /* sign the template */ if(xmlSecDSigCtxSign(dsigCtx, signNode) < 0) { printf_a_ignorar3(stderr,"Error: signature failed\n"); goto done; } /* print signed document to stdout */ xmlDocDump(stdout, doc); /* success */ res = 0; done: /* cleanup */ if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } if(doc != NULL) { xmlFreeDoc(doc); } return(res); }
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); }
static VALUE xmlsec_sign(VALUE self, xmlDocPtr doc, VALUE key_file, VALUE password, VALUE x509_file, VALUE node_name ) { xmlNodePtr signNode = NULL; xmlNodePtr refNode = NULL; xmlNodePtr pathNode = NULL; xmlNodePtr keyInfoNode = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; xmlChar *xmlbuff; int xmlbuffsize; VALUE result; /* create signature template for RSA-SHA1 enveloped signature */ signNode = xmlSecTmplSignatureCreate( doc, xmlSecTransformInclC14NWithCommentsId, xmlSecTransformRsaSha256Id, NULL ); if(signNode == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to create signature template\n"); return Qnil; } pathNode = xmlDocGetRootElement(doc); if (! NIL_P(node_name)) { pathNode = xmlNewChild(xmlDocGetRootElement(doc), NULL, StringValuePtr(node_name), NULL); if(pathNode == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to create %s node\n", StringValuePtr(node_name)); return Qnil; } } /* add <dsig:Signature/> node to the doc */ xmlAddChild(pathNode, signNode); /* add reference */ refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha256Id, NULL, "\0", NULL); if(refNode == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to add reference to signature template\n"); return Qnil; } /* add enveloped transform */ if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to add enveloped transform to reference\n"); return Qnil; } if (! NIL_P(x509_file)){ /* add <dsig:KeyInfo/> and <dsig:X509Data/> */ keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL); if(keyInfoNode == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to add key info\n"); return Qnil; } if(xmlSecTmplKeyInfoAddX509Data(keyInfoNode) == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to add X509Data node\n"); return Qnil; } if(xmlSecTmplKeyInfoAddKeyValue(keyInfoNode) == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to add KeyValue node\n"); return Qnil; } } /* create signature context, we don't need keys manager in this example */ dsigCtx = xmlSecDSigCtxCreate(NULL); if(dsigCtx == NULL) { if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to create signature context\n"); return Qnil; } /* load private key, assuming that there is not password */ dsigCtx->signKey = xmlSecCryptoAppKeyLoad(StringValuePtr(key_file), xmlSecKeyDataFormatPem, NIL_P(password) ? NULL : StringValuePtr(password), NULL, NULL); if(dsigCtx->signKey == NULL) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to load private pem key from \"%s\"\n", StringValuePtr(key_file)); return Qnil; } if (! NIL_P(x509_file)){ /* load certificate and add to the key */ if(xmlSecCryptoAppKeyCertLoad(dsigCtx->signKey, StringValuePtr(x509_file), xmlSecKeyDataFormatPem) < 0) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to load pem certificate \"%s\"\n", StringValuePtr(x509_file)); return Qnil; } } /* set key name to the file name, this is just an example! */ if(xmlSecKeySetName(dsigCtx->signKey, StringValuePtr(key_file)) < 0) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: failed to set key name for key from \"%s\"\n", StringValuePtr(key_file)); return Qnil; } /* sign the template */ if(xmlSecDSigCtxSign(dsigCtx, signNode) < 0) { if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); rb_raise(rb_eRuntimeError, "Error: signature failed"); return Qnil; } /* return signed document*/ xmlDocDumpFormatMemory(doc, &xmlbuff, &xmlbuffsize, 1); result = rb_str_new(xmlbuff, xmlbuffsize); xmlFree(xmlbuff); if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx); if(doc != NULL) xmlFreeDoc(doc); return result; }