Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
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));
}
Ejemplo n.º 3
0
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;
  }
}
Ejemplo n.º 4
0
/**
 * 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);
}
Ejemplo n.º 5
0
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 */
}
Ejemplo n.º 6
0
/**
 * 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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
/**
 * 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);
}
Ejemplo n.º 11
0
/**
 * 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);
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
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);
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
/** 
 * 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);
}
Ejemplo n.º 16
0
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);
}
Ejemplo n.º 17
0
Archivo: sign.c Proyecto: saaji/xmlsec
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;

}