int xmlSecAppCryptoSimpleKeysMngrBinaryKeyLoad(xmlSecKeysMngrPtr mngr, const char* keyKlass, const char *filename, const char *name) { xmlSecKeyPtr key; xmlSecKeyDataId dataId; int ret; xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(keyKlass != NULL, -1); xmlSecAssert2(filename != NULL, -1); /* find requested data */ dataId = xmlSecKeyDataIdListFindByName(xmlSecKeyDataIdsGet(), BAD_CAST keyKlass, xmlSecKeyDataUsageAny); if(dataId == xmlSecKeyDataIdUnknown) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecKeyDataIdListFindByName", XMLSEC_ERRORS_R_XMLSEC_FAILED, "name=%s", xmlSecErrorsSafeString(keyKlass)); return(-1); } key = xmlSecKeyReadBinaryFile(dataId, filename); if(key == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecKeyReadBinaryFile", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } 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); } /* finally add it to keys manager */ 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); }
CAMLprim value xmlsecml_xmlSecKeySetName(value camlKey, value camlName) { CAMLparam2(camlKey, camlName); int res; xmlSecKeyPtr key = Key_val(camlKey); unsigned char *name = (unsigned char *) String_val(camlName); res = xmlSecKeySetName(key, name); CAMLreturn(Val_int(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; } }
/** * load_des_keys: * @files: the list of filenames. * @files_size: the number of filenames in #files. * * Creates simple keys manager and load DES 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_des_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 DES key */ key = xmlSecKeyReadBinaryFile(xmlSecKeyDataDesId, files[i]); if(key == NULL) { fprintf(stderr,"Error: failed to load des key from binary file \"%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); }
static int addRubyKeyToManager(VALUE rb_key, VALUE rb_value, VALUE rb_manager) { xmlSecKeysMngrPtr keyManager = (xmlSecKeysMngrPtr)rb_manager; char *keyName, *keyData; unsigned int keyDataLength; xmlSecKeyPtr key; Check_Type(rb_key, T_STRING); Check_Type(rb_value, T_STRING); keyName = RSTRING_PTR(rb_key); keyData = RSTRING_PTR(rb_value); keyDataLength = RSTRING_LEN(rb_value); // load key key = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)keyData, keyDataLength, xmlSecKeyDataFormatPem, NULL, // password NULL, NULL); if (key == NULL) { rb_warn("failed to load '%s' public or private pem key", keyName); return ST_CONTINUE; } // set key name if (xmlSecKeySetName(key, BAD_CAST keyName) < 0) { rb_warn("failed to set key name for key '%s'", keyName); return ST_CONTINUE; } // add key to key manager; from now on the manager is responsible for // destroying the key if (xmlSecCryptoAppDefaultKeysMngrAdoptKey(keyManager, key) < 0) { rb_warn("failed to add key '%s' to key manager", keyName); return ST_CONTINUE; } return ST_CONTINUE; }
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; }
/** * encrypt_file: * @xml_file: the encryption template file name. * @key_file: the Triple DES key file. * * Encrypts #xml_file using a dynamicaly created template and DES key from * #key_file. * * Returns 0 on success or a negative value if an error occurs. */ int encrypt_file(const char* xml_file, const char* key_file) { xmlDocPtr doc = NULL; xmlNodePtr encDataNode = NULL; xmlNodePtr keyInfoNode = NULL; xmlSecEncCtxPtr encCtx = NULL; int res = -1; assert(xml_file); assert(key_file); /* load template */ doc = xmlParseFile(xml_file); if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_file); goto done; } /* create encryption template to encrypt XML file and replace * its content with encryption result */ encDataNode = xmlSecTmplEncDataCreate(doc, xmlSecTransformDes3CbcId, NULL, xmlSecTypeEncElement, NULL, NULL); if(encDataNode == NULL) { fprintf(stderr, "Error: failed to create encryption template\n"); goto done; } /* we want to put encrypted data in the <enc:CipherValue/> node */ if(xmlSecTmplEncDataEnsureCipherValue(encDataNode) == NULL) { fprintf(stderr, "Error: failed to add CipherValue node\n"); goto done; } /* add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to put key name in the signed document */ keyInfoNode = xmlSecTmplEncDataEnsureKeyInfo(encDataNode, NULL); if(keyInfoNode == NULL) { fprintf(stderr, "Error: failed to add key info\n"); goto done; } if(xmlSecTmplKeyInfoAddKeyName(keyInfoNode, NULL) == NULL) { fprintf(stderr, "Error: failed to add key name\n"); goto done; } /* create encryption context, we don't need keys manager in this example */ encCtx = xmlSecEncCtxCreate(NULL); if(encCtx == NULL) { fprintf(stderr,"Error: failed to create encryption context\n"); goto done; } /* load DES key, assuming that there is not password */ encCtx->encKey = xmlSecKeyReadBinaryFile(xmlSecKeyDataDesId, key_file); if(encCtx->encKey == NULL) { fprintf(stderr,"Error: failed to load des key from binary file \"%s\"\n", key_file); goto done; } /* set key name to the file name, this is just an example! */ if(xmlSecKeySetName(encCtx->encKey, key_file) < 0) { fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file); goto done; } /* encrypt the data */ if(xmlSecEncCtxXmlEncrypt(encCtx, encDataNode, xmlDocGetRootElement(doc)) < 0) { fprintf(stderr,"Error: encryption failed\n"); goto done; } /* we template is inserted in the doc */ encDataNode = NULL; /* print encrypted data with document to stdout */ xmlDocDump(stdout, doc); /* success */ res = 0; done: /* cleanup */ if(encCtx != NULL) { xmlSecEncCtxDestroy(encCtx); } if(encDataNode != NULL) { xmlFreeNode(encDataNode); } if(doc != NULL) { xmlFreeDoc(doc); } return(res); }
/** * encrypt_file: * @tmpl_file: the encryption template file name. * @key_file: the Triple DES key file. * @data: the binary data to encrypt. * @dataSize: the binary data size. * * Encrypts binary #data using template from #tmpl_file and DES key from * #key_file. * * Returns 0 on success or a negative value if an error occurs. */ int encrypt_file(const char* tmpl_file, const char* key_file, const unsigned char* data, size_t dataSize) { xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xmlSecEncCtxPtr encCtx = NULL; int res = -1; assert(tmpl_file); assert(key_file); assert(data); /* load template */ doc = xmlParseFile(tmpl_file); if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ printf_a_ignorar3(stderr, "Error: unable to parse file \"%s\"\n", tmpl_file); goto done; } /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeEncryptedData, xmlSecEncNs); if(node == NULL) { printf_a_ignorar3(stderr, "Error: start node not found in \"%s\"\n", tmpl_file); goto done; } /* create encryption context, we don't need keys manager in this example */ encCtx = xmlSecEncCtxCreate(NULL); if(encCtx == NULL) { printf_a_ignorar3(stderr,"Error: failed to create encryption context\n"); goto done; } /* load DES key, assuming that there is not password */ encCtx->encKey = xmlSecKeyReadBinaryFile(xmlSecKeyDataDesId, key_file); if(encCtx->encKey == NULL) { printf_a_ignorar3(stderr,"Error: failed to load des key from binary file \"%s\"\n", key_file); goto done; } /* set key name to the file name, this is just an example! */ if(xmlSecKeySetName(encCtx->encKey, key_file) < 0) { printf_a_ignorar3(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file); goto done; } /* encrypt the data */ if(xmlSecEncCtxBinaryEncrypt(encCtx, node, data, dataSize) < 0) { printf_a_ignorar3(stderr,"Error: encryption failed\n"); goto done; } /* print encrypted data with document to stdout */ xmlDocDump(stdout, doc); /* success */ res = 0; done: /* cleanup */ if(encCtx != NULL) { xmlSecEncCtxDestroy(encCtx); } 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); }
/** * 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); }
xmlSecKeyPtr xmlSecAppCryptoKeyGenerate(const char* keyKlassAndSize, const char* name, xmlSecKeyDataType type) { xmlSecKeyPtr key; char* buf; char* p; int size; int ret; xmlSecAssert2(keyKlassAndSize != NULL, NULL); buf = (char*) xmlStrdup(BAD_CAST keyKlassAndSize); if(buf == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_R_STRDUP_FAILED, "name=%s", xmlSecErrorsSafeString(name)); return(NULL); } /* separate key klass and size */ p = strchr(buf, '-'); if(p == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_R_INVALID_DATA, "key size is not specified %s", xmlSecErrorsSafeString(buf)); xmlFree(buf); return(NULL); } *(p++) = '\0'; size = atoi(p); key = xmlSecKeyGenerateByName(BAD_CAST buf, size, type); if(key == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecKeyGenerate", XMLSEC_ERRORS_R_XMLSEC_FAILED, "klass=%s;size=%d", xmlSecErrorsSafeString(buf), size); xmlFree(buf); return(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); xmlFree(buf); return(NULL); } xmlFree(buf); 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); }
static xmlSecKeyPtr xmlSecMSCryptoKeysStoreFindKey(xmlSecKeyStorePtr store, const xmlChar* name, xmlSecKeyInfoCtxPtr keyInfoCtx) { xmlSecKeyStorePtr* ss; xmlSecKeyPtr key = NULL; xmlSecKeyReqPtr keyReq = NULL; PCCERT_CONTEXT pCertContext = NULL; PCCERT_CONTEXT pCertContext2 = NULL; xmlSecKeyDataPtr data = NULL; xmlSecKeyDataPtr x509Data = NULL; xmlSecKeyPtr res = NULL; int ret; xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecMSCryptoKeysStoreId), NULL); xmlSecAssert2(keyInfoCtx != NULL, NULL); ss = xmlSecMSCryptoKeysStoreGetSS(store); xmlSecAssert2(((ss != NULL) && (*ss != NULL)), NULL); /* first try to find key in the simple keys store */ key = xmlSecKeyStoreFindKey(*ss, name, keyInfoCtx); if (key != NULL) { return (key); } /* Next try to find the key in the MS Certificate store, and construct an xmlSecKey. * we must have a name to lookup keys in the certificate store. */ if (name == NULL) { goto done; } /* what type of key are we looking for? * WK: For now, we'll look only for public/private keys using the * name as a cert nickname. Then the name is regarded as the subject * dn of the certificate to be searched for. */ keyReq = &(keyInfoCtx->keyReq); if (keyReq->keyType & (xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate)) { pCertContext = xmlSecMSCryptoKeysStoreFindCert(store, name, keyInfoCtx); if(pCertContext == NULL) { goto done; } /* set cert in x509 data */ x509Data = xmlSecKeyDataCreate(xmlSecMSCryptoKeyDataX509Id); if(x509Data == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecKeyDataCreate", XMLSEC_ERRORS_R_XMLSEC_FAILED, "data=%s", xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); goto done; } pCertContext2 = CertDuplicateCertificateContext(pCertContext); if (NULL == pCertContext2) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "CertDuplicateCertificateContext", XMLSEC_ERRORS_R_CRYPTO_FAILED, "data=%s", xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); goto done; } ret = xmlSecMSCryptoKeyDataX509AdoptCert(x509Data, pCertContext2); if (ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecMSCryptoKeyDataX509AdoptCert", XMLSEC_ERRORS_R_XMLSEC_FAILED, "data=%s", xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); goto done; } pCertContext2 = NULL; pCertContext2 = CertDuplicateCertificateContext(pCertContext); if (NULL == pCertContext2) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "CertDuplicateCertificateContext", XMLSEC_ERRORS_R_CRYPTO_FAILED, "data=%s", xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); goto done; } ret = xmlSecMSCryptoKeyDataX509AdoptKeyCert(x509Data, pCertContext2); if (ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecMSCryptoKeyDataX509AdoptKeyCert", XMLSEC_ERRORS_R_XMLSEC_FAILED, "data=%s", xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); goto done; } pCertContext2 = NULL; /* set cert in key data */ data = xmlSecMSCryptoCertAdopt(pCertContext, keyReq->keyType); if(data == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecMSCryptoCertAdopt", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); goto done; } pCertContext = NULL; /* create key and add key data and x509 data to it */ key = xmlSecKeyCreate(); if (key == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecKeyCreate", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); goto done; } ret = xmlSecKeySetValue(key, data); if (ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecKeySetValue", XMLSEC_ERRORS_R_XMLSEC_FAILED, "data=%s", xmlSecErrorsSafeString(xmlSecKeyDataGetName(data))); goto done; } data = NULL; ret = xmlSecKeyAdoptData(key, x509Data); if (ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecKeyAdoptData", XMLSEC_ERRORS_R_XMLSEC_FAILED, "data=%s", xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); goto done; } x509Data = NULL; /* Set the name of the key to the given name */ ret = xmlSecKeySetName(key, name); if (ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)), "xmlSecKeySetName", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); goto done; } /* now that we have a key, make sure it is valid and let the simple * store adopt it */ if (xmlSecKeyIsValid(key)) { res = key; key = NULL; } } done: if (NULL != pCertContext) { CertFreeCertificateContext(pCertContext); } if (NULL != pCertContext2) { CertFreeCertificateContext(pCertContext2); } if (data != NULL) { xmlSecKeyDataDestroy(data); } if (x509Data != NULL) { xmlSecKeyDataDestroy(x509Data); } if (key != NULL) { xmlSecKeyDestroy(key); } return (res); }
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; }