PyObject *xmlsec_TmplSignatureAddReference(PyObject *self, PyObject *args) { PyObject *signNode_obj, *digestMethodId_obj; xmlNodePtr signNode; xmlSecTransformId digestMethodId; const xmlChar *id = NULL; const xmlChar *uri = NULL; const xmlChar *type = NULL; xmlNodePtr ref; if (CheckArgs(args, "OOsss:tmplSignatureAddReference")) { if (!PyArg_ParseTuple(args, "OOzzz:tmplSignatureAddReference", &signNode_obj, &digestMethodId_obj, &id, &uri, &type)) return NULL; } else return NULL; signNode = xmlNodePtr_get(signNode_obj); digestMethodId = xmlSecTransformId_get(digestMethodId_obj); ref = xmlSecTmplSignatureAddReference(signNode, digestMethodId, id, uri, type); return (wrap_xmlNodePtr(ref)); }
/** * 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); }
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; }
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; }