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; } }
/** * load_keys: * @files: the list of filenames. * @files_size: the number of filenames in #files. * * Creates simple keys manager and load PEM keys from #files in it. * The caller is responsible for destroing returned keys manager using * @xmlSecKeysMngrDestroy. * * Returns the pointer to newly created keys manager or NULL if an error * occurs. */ xmlSecKeysMngrPtr load_keys(char** files, int files_size) { xmlSecKeysMngrPtr mngr; xmlSecKeyPtr key; int i; assert(files); assert(files_size > 0); /* create and initialize keys manager, we use a simple list based * keys manager, implement your own xmlSecKeysStore klass if you need * something more sophisticated */ mngr = xmlSecKeysMngrCreate(); if(mngr == NULL) { fprintf(stderr, "Error: failed to create keys manager.\n"); return(NULL); } if(xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) { fprintf(stderr, "Error: failed to initialize keys manager.\n"); xmlSecKeysMngrDestroy(mngr); return(NULL); } for(i = 0; i < files_size; ++i) { assert(files[i]); /* load key */ key = xmlSecCryptoAppKeyLoad(files[i], xmlSecKeyDataFormatPem, NULL, NULL, NULL); if(key == NULL) { fprintf(stderr,"Error: failed to load pem key from \"%s\"\n", files[i]); xmlSecKeysMngrDestroy(mngr); return(NULL); } /* set key name to the file name, this is just an example! */ if(xmlSecKeySetName(key, BAD_CAST files[i]) < 0) { fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", files[i]); xmlSecKeyDestroy(key); xmlSecKeysMngrDestroy(mngr); return(NULL); } /* add key to keys manager, from now on keys manager is responsible * for destroying key */ if(xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key) < 0) { fprintf(stderr,"Error: failed to add key from \"%s\" to keys manager\n", files[i]); xmlSecKeyDestroy(key); xmlSecKeysMngrDestroy(mngr); return(NULL); } } return(mngr); }
int xmlSecAppCryptoSimpleKeysMngrPkcs12KeyLoad(xmlSecKeysMngrPtr mngr, const char *filename, const char* pwd, const char *name) { xmlSecKeyPtr key; int ret; xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); #ifndef XMLSEC_NO_X509 key = xmlSecCryptoAppKeyLoad(filename, xmlSecKeyDataFormatPkcs12, pwd, xmlSecCryptoAppGetDefaultPwdCallback(), (void*)filename); if(key == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecCryptoAppKeyLoad", XMLSEC_ERRORS_R_XMLSEC_FAILED, "filename=%s", xmlSecErrorsSafeString(filename)); return(-1); } if(name != NULL) { ret = xmlSecKeySetName(key, BAD_CAST name); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecKeySetName", XMLSEC_ERRORS_R_XMLSEC_FAILED, "name=%s", xmlSecErrorsSafeString(name)); xmlSecKeyDestroy(key); return(-1); } } ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecCryptoAppDefaultKeysMngrAdoptKey", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecKeyDestroy(key); return(-1); } return(0); #else /* XMLSEC_NO_X509 */ xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "x509", XMLSEC_ERRORS_R_DISABLED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); #endif /* XMLSEC_NO_X509 */ }
/** * files_keys_store_find_key: * @store: the pointer to simple keys store. * @name: the desired key name. * @keyInfoCtx: the pointer to <dsig:KeyInfo/> node processing context. * * Lookups key in the @store. The caller is responsible for destroying * returned key with #xmlSecKeyDestroy function. * * Returns pointer to key or NULL if key not found or an error occurs. */ static xmlSecKeyPtr files_keys_store_find_key(xmlSecKeyStorePtr store, const xmlChar* name, xmlSecKeyInfoCtxPtr keyInfoCtx) { xmlSecKeyPtr key; const xmlChar* p; assert(store); assert(keyInfoCtx); /* it's possible to do not have the key name or desired key type * but we could do nothing in this case */ if((name == NULL) || (keyInfoCtx->keyReq.keyId == xmlSecKeyDataIdUnknown)) { return(NULL); } /* we don't want to open files in a folder other than "current"; * to prevent it limit the characters in the key name to alpha/digit, * '.', '-' or '_'. */ for(p = name; (*p) != '\0'; ++p) { if(!isalnum((*p)) && ((*p) != '.') && ((*p) != '-') && ((*p) != '_')) { return(NULL); } } if((keyInfoCtx->keyReq.keyId == xmlSecKeyDataDsaId) || (keyInfoCtx->keyReq.keyId == xmlSecKeyDataRsaId)) { /* load key from a pem file, if key is not found then it's an error (is it?) */ key = xmlSecCryptoAppKeyLoad(name, xmlSecKeyDataFormatPem, NULL, NULL, NULL); if(key == NULL) { fprintf(stderr,"Error: failed to load public pem key from \"%s\"\n", name); return(NULL); } } else { /* otherwise it's a binary key, if key is not found then it's an error (is it?) */ key = xmlSecKeyReadBinaryFile(keyInfoCtx->keyReq.keyId, name); if(key == NULL) { fprintf(stderr,"Error: failed to load key from binary file \"%s\"\n", name); return(NULL); } } /* set key name */ if(xmlSecKeySetName(key, name) < 0) { fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", name); xmlSecKeyDestroy(key); return(NULL); } return(key); }
/** * 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); }
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); }
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; }
/** * 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); }
int xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(xmlSecKeysMngrPtr mngr, const char* files, const char* pwd, const char* name, xmlSecKeyDataFormat format) { xmlSecKeyPtr key; int ret; xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(files != NULL, -1); /* first is the key file */ key = xmlSecCryptoAppKeyLoad(files, format, pwd, xmlSecCryptoAppGetDefaultPwdCallback(), (void*)files); if(key == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecCryptoAppKeyLoad", XMLSEC_ERRORS_R_XMLSEC_FAILED, "uri=%s", xmlSecErrorsSafeString(files)); return(-1); } if(name != NULL) { ret = xmlSecKeySetName(key, BAD_CAST name); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecKeySetName", XMLSEC_ERRORS_R_XMLSEC_FAILED, "name=%s", xmlSecErrorsSafeString(name)); xmlSecKeyDestroy(key); return(-1); } } #ifndef XMLSEC_NO_X509 for(files += strlen(files) + 1; (files[0] != '\0'); files += strlen(files) + 1) { ret = xmlSecCryptoAppKeyCertLoad(key, files, format); if(ret < 0){ xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecCryptoAppKeyCertLoad", XMLSEC_ERRORS_R_XMLSEC_FAILED, "uri=%s", xmlSecErrorsSafeString(files)); xmlSecKeyDestroy(key); return(-1); } } #else /* XMLSEC_NO_X509 */ files += strlen(files) + 1; if(files[0] != '\0') { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "x509", XMLSEC_ERRORS_R_DISABLED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } #endif /* XMLSEC_NO_X509 */ ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecCryptoAppDefaultKeysMngrAdoptKey", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecKeyDestroy(key); return(-1); } return(0); }
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; }