예제 #1
0
/** 
 * verify_file:
 * @mngr:		the pointer to keys manager.
 * @xml_file:		the signed XML file name.
 *
 * Verifies XML signature in #xml_file.
 *
 * Returns 0 on success or a negative value if an error occurs.
 */
int 
verify_file(xmlSecKeysMngrPtr mngr, const char* xml_file) {
    xmlDocPtr doc = NULL;
    xmlNodePtr node = NULL;
    xmlSecDSigCtxPtr dsigCtx = NULL;
    int res = -1;
    
    assert(mngr);
    assert(xml_file);

    /* load file */
    doc = xmlParseFile(xml_file);
    if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
	fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_file);
	goto done;	
    }
    
    /* find start node */
    node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
    if(node == NULL) {
	fprintf(stderr, "Error: start node not found in \"%s\"\n", xml_file);
	goto done;	
    }

    /* create signature context */
    dsigCtx = xmlSecDSigCtxCreate(mngr);
    if(dsigCtx == NULL) {
        fprintf(stderr,"Error: failed to create signature context\n");
	goto done;
    }

    /* Verify signature */
    if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
        fprintf(stderr,"Error: signature verify\n");
	goto done;
    }
        
    /* print verification result to stdout */
    if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
	fprintf(stdout, "Signature is OK\n");
    } else {
	fprintf(stdout, "Signature is INVALID\n");
    }    

    /* success */
    res = 0;

done:    
    /* cleanup */
    if(dsigCtx != NULL) {
	xmlSecDSigCtxDestroy(dsigCtx);
    }
    
    if(doc != NULL) {
	xmlFreeDoc(doc); 
    }
    return(res);
}
예제 #2
0
파일: verify.c 프로젝트: paracycle/xmlsec
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;
  }
}
예제 #3
0
파일: PoleXmlSec.c 프로젝트: MaxMorais/pole
int
verify_xml(xmlSecKeysMngrPtr mngr, const char* xml_string, const char* id_attr_name, const char* id_node_name) {
    xmlDocPtr doc = NULL;
    xmlNodePtr node = NULL;
    xmlSecDSigCtxPtr dsigCtx = NULL;
    int res = -1;

    assert(mngr);
    assert(xml_string);

    /* load template */
    doc = xmlParseDoc((xmlChar*)xml_string);
    if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
        fprintf(stderr, "XmlSecError: unable to parse xml string\n");
        goto done2;
    }

    /* add id */
    if (id_attr_name && id_node_name)
        xmlSecAppAddIDAttr(xmlDocGetRootElement(doc), (xmlChar*)id_attr_name, (xmlChar*)id_node_name, NULL);

    /* find start node */
    node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
    if(node == NULL) {
        fprintf(stderr, "XmlSecError: start node not found in xml string\n");
        goto done2;
    }

    /* create signature context */
    dsigCtx = xmlSecDSigCtxCreate(mngr);
    if(dsigCtx == NULL) {
        fprintf(stderr,"XmlSecError: failed to create signature context\n");
        goto done2;
    }

    /* Verify signature */
    if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
        fprintf(stderr,"XmlSecError: signature verify\n");
        goto done2;
    }

    res = (dsigCtx->status == xmlSecDSigStatusSucceeded);

done2:
    /* cleanup */
    if(dsigCtx != NULL) {
        xmlSecDSigCtxDestroy(dsigCtx);
    }

    if(doc != NULL) {
        xmlFreeDoc(doc);
    }
    return(res);
}
VALUE verify_signature_with_certificates(VALUE self, VALUE rb_certs) {
  xmlDocPtr doc;
  xmlNodePtr node = NULL;
  xmlSecDSigCtxPtr dsigCtx = NULL;
  xmlSecKeysMngrPtr keyManager = NULL;
  VALUE result = Qfalse;

  Check_Type(rb_certs, T_ARRAY);
  Data_Get_Struct(self, xmlDoc, doc);

  // find start node
  node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
  if(node == NULL) {
    rb_raise(rb_eVerificationError, "start node not found");
    goto done;
  }

  keyManager = getKeyManager(rb_certs);
  if (keyManager == NULL) {
    rb_raise(rb_eKeystoreError, "failed to create key manager");
    goto done;
  }

  // create signature context, we don't need keys manager in this example
  dsigCtx = xmlSecDSigCtxCreate(keyManager);
  if(dsigCtx == NULL) {
    rb_raise(rb_eVerificationError, "failed to create signature context");
    goto done;
  }

  // verify signature
  if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
    rb_raise(rb_eVerificationError, "error occurred during signature verification");
    goto done;
  }
      
  if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
    result = Qtrue;
  }    

done:
  if(dsigCtx != NULL) {
    xmlSecDSigCtxDestroy(dsigCtx);
  }

  if (keyManager != NULL) {
    xmlSecKeysMngrDestroy(keyManager);
  }

  return result;
}
예제 #5
0
int verify_document(xmlDocPtr doc, const char* key) {
  initialize();
  xmlNodePtr node = NULL;
  xmlSecDSigCtxPtr dsigCtx = NULL;
  int res = 0;
 
  if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
	rb_raise(rb_eRuntimeError, "unable to parse XML document");
  }
    
  /* find start node */
  node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
  if(node == NULL) {
	rb_raise(rb_eRuntimeError, "could not find start node in XML document");
  }

  if(assign_id_attributes(doc) < 0) {
	  rb_raise(rb_eRuntimeError, "Could not find ID attribute in document");
  }
  

  /* create signature context */
  dsigCtx = xmlSecDSigCtxCreate(NULL);
  if(dsigCtx == NULL) {
	cleanup(dsigCtx);
	rb_raise(rb_eRuntimeError, "could not create signature context");
  }
 
	/* load public key */
	dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory(key, strlen(key), xmlSecKeyDataFormatCertPem, NULL, NULL, NULL);
	if(dsigCtx->signKey == NULL) {
		cleanup(dsigCtx);
		rb_raise(rb_eRuntimeError, "could not read public pem key %s", key);
	}
	 
  /* Verify signature */
  if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
	cleanup(dsigCtx);
	rb_raise(rb_eRuntimeError, "Document does not seem to be in an XMLDsig format");
  }
        
  /* print verification result to stdout */
  if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
	  res = 1;
  } else {
	  res = 0;
  }    
  cleanup(dsigCtx);
  return res;
}
예제 #6
0
파일: xmldsig.c 프로젝트: DeltaOS/pyxmlsec
PyObject *xmlsec_DSigCtxCreate(PyObject *self, PyObject *args) {
  PyObject *mngr_obj;
  xmlSecKeysMngrPtr mngr = NULL;
  xmlSecDSigCtxPtr dsigCtx;
  
  if (CheckArgs(args, "o:dsigCtxCreate")) {
    if(!PyArg_ParseTuple(args, (char *) "O:dsigCtxCreate", &mngr_obj))
      return NULL;
  }
  else return NULL;

  mngr = xmlSecKeysMngrPtr_get(mngr_obj);
  dsigCtx = xmlSecDSigCtxCreate(mngr);
  
  return (wrap_xmlSecDSigCtxPtr(dsigCtx));
}
예제 #7
0
파일: verify.c 프로젝트: paracycle/xmlsec
VALUE xmlsec_is_valid(VALUE self, xmlDocPtr doc) {
  xmlNodePtr node = NULL;
  xmlSecDSigCtxPtr dsigCtx = NULL;

  /* find start node */
  node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
  if(node == NULL) {
    if(doc != NULL) xmlFreeDoc(doc);
    rb_raise(rb_eRuntimeError, "Error: start node not found\n");
    return Qnil;
  }

  /* create signature context*/
  dsigCtx = xmlSecDSigCtxCreate(NULL);
  if(dsigCtx == NULL) {
    if(doc != NULL) xmlFreeDoc(doc);
    rb_raise(rb_eRuntimeError, "Error: failed to create signature context\n");
    return Qnil;
  }
  dsigCtx->enabledReferenceUris = xmlSecTransformUriTypeEmpty;

  /* Verify signature */
  if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
    if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx);
    if(doc != NULL) xmlFreeDoc(doc);
    rb_raise(rb_eRuntimeError, "Error: signature verify \"%s\"\n");
    return Qnil;
  }

  /* verification result*/
  if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
    if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx);
    if(doc != NULL) xmlFreeDoc(doc);
    return Qtrue;
  } else {
    if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx);
    if(doc != NULL) xmlFreeDoc(doc);
    return Qfalse;
  }

}
예제 #8
0
int xml_sign(opendcp_t *opendcp, char *filename) {
    xmlSecDSigCtxPtr dsig_ctx = NULL;
    xmlDocPtr        doc = NULL;
    xmlNodePtr       root_node;
    xmlNodePtr       sign_node;
    FILE *fp;
    int result = OPENDCP_ERROR;
    xmlSecKeysMngrPtr key_manager = NULL;
    
    dcp_log(LOG_DEBUG, "xml_sign: xmlsec_init");
    xmlsec_init();

    /* load doc file */
    dcp_log(LOG_DEBUG, "xml_sign: parse file");
    doc = xmlParseFile(filename);

    if (doc == NULL) {
        dcp_log(OPENDCP_ERROR, "Error: unable to parse file %s", filename);
        goto done;
    }

    /* find root node */
    root_node = xmlDocGetRootElement(doc);

    if (root_node == NULL){
        dcp_log(OPENDCP_ERROR, "Error: unable to find root node");
        goto done;
    }

    /* find signature node */
    sign_node = xmlSecFindNode(root_node, xmlSecNodeSignature, xmlSecDSigNs);
    if(sign_node == NULL) {
        fprintf(stderr, "Error: start node not found");
        goto done;      
    }
  
    /* create keys manager */
    key_manager = load_certificates_sign(opendcp);
    if (key_manager == NULL) {
        fprintf(stderr,"Error: failed to create key manager\n");
        goto done;
    }

    /* create signature opendcp */
    dsig_ctx = xmlSecDSigCtxCreate(key_manager);
 
    if(dsig_ctx == NULL) {
        fprintf(stderr,"Error: failed to create signature opendcp\n");
        goto done;
    }

    /* sign the template */
    if(xmlSecDSigCtxSign(dsig_ctx, sign_node) < 0) {
        fprintf(stderr,"Error: signature failed\n");
        goto done;
    }

    /* open xml file */
    fp = fopen(filename,"wb"); 

    if (fp == NULL) {
        fprintf(stderr,"Error: could not open output file\n");
        goto done;
    }

    /* write the xml file */
    if (xmlDocDump(fp, doc) < 0) {
        fprintf(stderr,"Error: writing XML document failed\n");
        goto done;
    }
  
    /* close the file */
    fclose(fp);

    /* success */
    result = 0;

done:    
    /* destroy keys manager */
    xmlSecKeysMngrDestroy(key_manager);

    /* destroy signature context */
    if(dsig_ctx != NULL) {
        xmlSecDSigCtxDestroy(dsig_ctx);
    }
    
    /* destroy xml doc */
    if(doc != NULL) {
        xmlFreeDoc(doc); 
    }

    xmlsec_close();

    return(result);
}
예제 #9
0
파일: PoleXmlSec.c 프로젝트: MaxMorais/pole
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;
}
예제 #10
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;
}
예제 #11
0
/** 
 * verify_request:
 * @mng:                the keys manager
 *
 * Verifies XML signature in the request (stdin).
 *
 * Returns 0 on success or a negative value if an error occurs.
 */
int 
verify_request(xmlSecKeysMngrPtr mngr) {
    xmlBufferPtr buffer = NULL;
    char buf[256];
    xmlDocPtr doc = NULL;
    xmlNodePtr node = NULL;
    xmlSecDSigCtxPtr dsigCtx = NULL;
    int ret;
    int res = -1;
    
    assert(mngr);

    /* load request in the buffer */    
    buffer = xmlBufferCreate();
    if(buffer == NULL) {
        fprintf(stdout,"Error: failed to create buffer\n");
        goto done;      
    }
    
    while(!feof(stdin)) {
        ret = fread(buf, 1, sizeof(buf), stdin);
        if(ret < 0) {
            fprintf(stdout,"Error: read failed\n");
            goto done;  
        }
        xmlBufferAdd(buffer, buf, ret);
    }

    /* is the document subbmitted from the form? */
    if(strncmp((char*)xmlBufferContent(buffer), "_xmldoc=", 8) == 0) {
        xmlBufferShrink(buffer, 8);
        buffer->use = url_decode((char*)xmlBufferContent(buffer), xmlBufferLength(buffer)); 
    }
        
    /** 
     * Load doc 
     */
    doc = xmlReadMemory(xmlBufferContent(buffer), xmlBufferLength(buffer),
                        NULL, NULL,
                        XML_PARSE_NOENT | XML_PARSE_NOCDATA | 
                        XML_PARSE_PEDANTIC | XML_PARSE_NOCDATA);
    if (doc == NULL) {
        fprintf(stdout, "Error: unable to parse xml document (syntax error)\n");
        goto done;
    }
    
    /*
     * Check the document is of the right kind
     */    
    if(xmlDocGetRootElement(doc) == NULL) {
        fprintf(stdout,"Error: empty document\n");
        goto done;
    }
    
    /* find start node */
    node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
    if(node == NULL) {
        fprintf(stdout, "Error: start <dsig:Signature/> node not found\n");
        goto done;      
    }

    /* create signature context */
    dsigCtx = xmlSecDSigCtxCreate(mngr);
    if(dsigCtx == NULL) {
        fprintf(stdout,"Error: failed to create signature context\n");
        goto done;
    }
    
    /* we would like to store and print out everything */
    /* actually we would not because it opens a security hole
    dsigCtx->flags = XMLSEC_DSIG_FLAGS_STORE_SIGNEDINFO_REFERENCES |
                     XMLSEC_DSIG_FLAGS_STORE_MANIFEST_REFERENCES |
                     XMLSEC_DSIG_FLAGS_STORE_SIGNATURE;
    */

    /* Verify signature */
    if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
        fprintf(stdout,"Error: signature verification failed\n");
        goto done;
    }
        
    /* print verification result to stdout */
    if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
        fprintf(stdout, "RESULT: Signature is OK\n");
    } else {
        fprintf(stdout, "RESULT: Signature is INVALID\n");
    }    
    fprintf(stdout, "---------------------------------------------------\n");
    xmlSecDSigCtxDebugDump(dsigCtx, stdout);

    /* success */
    res = 0;

done:    
    /* cleanup */
    if(dsigCtx != NULL) {
        xmlSecDSigCtxDestroy(dsigCtx);
    }
    
    if(doc != NULL) {
        xmlFreeDoc(doc); 
    }
    
    if(buffer != NULL) {
        xmlBufferFree(buffer);
    }
    return(res);
}
예제 #12
0
파일: validate.c 프로젝트: unizeto/bmd
/**
 * Funkcja dokonuje weryfikacji poprawności złożonego podpisu pod formularzem.
 * \param[in] mngr Zainicjalizowany menedżer kluczy.
 * \param[in] buffer Formularz do zweryfikowania.
 * \param[in] buffer_len Długość weryfikowanego formularza.
 *
 * \retval 0 Podpis poprawny.
 * \retval 1 Podpis niepoprawny.
 * \retval -1 Nie można przeparsować dokumentu.
 * \retval -2 Nie znaleziono startowego węzła.
 * \retval -3 Nie dało się utworzyć kontekstu podpisu.
 * \retval -4 Nie dało rady zweryfikować podpisu.
 * */
static long verify_memory(xmlSecKeysMngrPtr mngr, const char* buffer, const long buffer_len) {
	xmlDocPtr doc = NULL;
	xmlNodePtr node = NULL;
	xmlSecDSigCtxPtr dsigCtx = NULL;
	long ret = -99;

	assert(mngr);

	/* load file */
	doc = xmlParseMemory(buffer,buffer_len);
	if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
		PRINT_DEBUG("UNABLE TO PARSE DOCUMENT\n");
		ret = -1;
		goto done;
	}

	/* find start node */
	node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
	if(node == NULL) {
		PRINT_DEBUG("Start node %s not found\n",xmlSecNodeSignature);
		ret = -2;
		goto done;
	}

	/* create signature context */
	dsigCtx = xmlSecDSigCtxCreate(mngr);
	if(dsigCtx == NULL) {
		PRINT_DEBUG("Failed to create signature context\n");
		ret = -3;
		goto done;
	}

	/* Verify signature */
	if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
		PRINT_DEBUG("Error: signature verify failed\n");
		ret = -4;
		goto done;
	}


	/* print verification result to stdout */
	if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
		ret = 0;
		PRINT_DEBUG("XAdES: Signature is OK\n");
	} else {
		ret = 1;
		PRINT_DEBUG("XAdES: Signature is INVALID\n");
	}


done:
			/* cleanup */
			if(dsigCtx != NULL) {
	xmlSecDSigCtxDestroy(dsigCtx);
			}

			if(doc != NULL) {
				xmlFreeDoc(doc);
			}
			return(ret);
}
예제 #13
0
/** 
 * verify_file:
 * @mngr:               the pointer to keys manager.
 * @xml_file:           the signed XML file name.
 *
 * Verifies XML signature in #xml_file.
 *
 * Returns 0 on success or a negative value if an error occurs.
 */
int 
verify_file(xmlSecKeysMngrPtr mngr, const char* xml_file) {
    xmlDocPtr doc = NULL;
    xmlNodePtr node = NULL;
    xmlSecDSigCtxPtr dsigCtx = NULL;
    int res = -1;
    
    assert(mngr);
    assert(xml_file);

    /* load file */
    doc = xmlParseFile(xml_file);
    if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
        fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_file);
        goto done;      
    }
    
    /* find start node */
    node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
    if(node == NULL) {
        fprintf(stderr, "Error: start node not found in \"%s\"\n", xml_file);
        goto done;      
    }

    /* create signature context */
    dsigCtx = xmlSecDSigCtxCreate(mngr);
    if(dsigCtx == NULL) {
        fprintf(stderr,"Error: failed to create signature context\n");
        goto done;
    }

    /* limit the Reference URI attributes to empty or NULL */
    dsigCtx->enabledReferenceUris = xmlSecTransformUriTypeEmpty;
    
    /* limit allowed transforms for signature and reference processing */
    if((xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformInclC14NId) < 0) ||
       (xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformExclC14NId) < 0) ||
       (xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformSha1Id) < 0) ||
       (xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformRsaSha1Id) < 0)) {

        fprintf(stderr,"Error: failed to limit allowed signature transforms\n");
        goto done;
    }
    if((xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformInclC14NId) < 0) ||
       (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformExclC14NId) < 0) ||
       (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformSha1Id) < 0) ||
       (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformEnvelopedId) < 0)) {

        fprintf(stderr,"Error: failed to limit allowed reference transforms\n");
        goto done;
    }

    /* in addition, limit possible key data to valid X509 certificates only */
    if(xmlSecPtrListAdd(&(dsigCtx->keyInfoReadCtx.enabledKeyData), BAD_CAST xmlSecKeyDataX509Id) < 0) {
        fprintf(stderr,"Error: failed to limit allowed key data\n");
        goto done;
    }
    
    /* Verify signature */
    if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
        fprintf(stderr,"Error: signature verify\n");
        goto done;
    }

    /* check that we have only one Reference */
    if((dsigCtx->status == xmlSecDSigStatusSucceeded) && 
        (xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) != 1)) {
        
        fprintf(stderr,"Error: only one reference is allowed\n");
        goto done;
    }
        
    /* print verification result to stdout */
    if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
        fprintf(stdout, "Signature is OK\n");
    } else {
        fprintf(stdout, "Signature is INVALID\n");
    }    

    /* success */
    res = 0;

done:    
    /* cleanup */
    if(dsigCtx != NULL) {
        xmlSecDSigCtxDestroy(dsigCtx);
    }
    
    if(doc != NULL) {
        xmlFreeDoc(doc); 
    }
    return(res);
}
예제 #14
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);
}
예제 #15
0
파일: verify.c 프로젝트: paracycle/xmlsec
VALUE xmlsec_is_valid_by_x509_file(VALUE self, xmlDocPtr doc, VALUE x509_file ) {
  xmlSecKeysMngrPtr mngr;
  VALUE v;
  xmlNodePtr node = NULL;
  xmlSecDSigCtxPtr dsigCtx = NULL;
  long i;

  mngr = xmlSecKeysMngrCreate();

  if(mngr == NULL) {
    if(doc != NULL) xmlFreeDoc(doc);
    rb_raise(rb_eRuntimeError, "Error: failed to create keys manager.\n");
    return Qnil;
  }

  if(xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) {
    if(doc != NULL) xmlFreeDoc(doc);
    if(mngr != NULL) xmlSecKeysMngrDestroy(mngr);
    rb_raise(rb_eRuntimeError, "Error: failed to initialize keys manager.\n");
    return Qnil;
  }
  if (TYPE(x509_file) == T_STRING){
    /* load trusted cert */
    if(xmlSecCryptoAppKeysMngrCertLoad(mngr, StringValuePtr(x509_file), xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
      if(doc != NULL) xmlFreeDoc(doc);
      if(mngr != NULL) xmlSecKeysMngrDestroy(mngr);
      rb_raise(rb_eRuntimeError, "Error: failed to load pem certificate from \"%s\"\n", StringValuePtr(x509_file));
      return Qnil;
    }
  }
  if (TYPE(x509_file) == T_ARRAY) {
    for (i =0; i < RARRAY_LEN(x509_file); i++) {
      v = rb_ary_entry(x509_file, i);
      StringValue(v);
      if(xmlSecCryptoAppKeysMngrCertLoad(mngr, RSTRING_PTR(v), xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
          if(doc != NULL) xmlFreeDoc(doc);
          if(mngr != NULL) xmlSecKeysMngrDestroy(mngr);
          rb_raise(rb_eRuntimeError, "Error: failed to load pem certificate from \"%s\"\n", RSTRING_PTR(v));
          return Qnil;
      }

    }
    //rb_ary_entry

  }


  /* find start node */
  node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
  if(node == NULL) {
    if(doc != NULL) xmlFreeDoc(doc);
    rb_raise(rb_eRuntimeError, "Error: start node not found\n");
    return Qnil;
  }

  /* create signature context*/
  dsigCtx = xmlSecDSigCtxCreate(mngr);
  if(dsigCtx == NULL) {
    if(doc != NULL) xmlFreeDoc(doc);
    if(mngr != NULL) xmlSecKeysMngrDestroy(mngr);
    rb_raise(rb_eRuntimeError, "Error: failed to create signature context\n");
    return Qnil;
  }

    /* limit the Reference URI attributes to empty or NULL */
  dsigCtx->enabledReferenceUris = xmlSecTransformUriTypeEmpty;

  /* Verify signature */
  if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
    if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx);
    if(doc != NULL) xmlFreeDoc(doc);
    if(mngr != NULL) xmlSecKeysMngrDestroy(mngr);
    rb_raise(rb_eRuntimeError, "Error: signature verify \"%s\"\n");
    return Qnil;
  }

  /* verification result*/
  if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
    if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx);
    if(doc != NULL) xmlFreeDoc(doc);
    if(mngr != NULL) xmlSecKeysMngrDestroy(mngr);
    return Qtrue;
  } else {
    if(dsigCtx != NULL) xmlSecDSigCtxDestroy(dsigCtx);
    if(doc != NULL) xmlFreeDoc(doc);
    if(mngr != NULL) xmlSecKeysMngrDestroy(mngr);
    return Qfalse;
  }

}
예제 #16
0
파일: sign2.c 프로젝트: Arcenciel/DDReader
/** 
 * 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);
}
예제 #17
0
int xml_verify(char *filename) {
    xmlSecDSigCtxPtr dsig_ctx = NULL;
    xmlDocPtr        doc = NULL;
    xmlNodePtr       root_node;
    xmlNodePtr       sign_node;
    xmlNodePtr       cert_node;
    xmlNodePtr       x509d_node; 
    xmlNodePtr       cur_node; 
    int              result = DCP_FATAL;
    xmlSecKeysMngrPtr key_manager;
    char cert[5000];
    int  cert_l; 
    xmlsec_verify_init();

    /* load doc file */
    doc = xmlParseFile(filename);

    if (doc == NULL) {
        dcp_log(LOG_ERROR, "unable to parse file %s", filename);
        goto done;
    }

    /* find root node */
    root_node = xmlDocGetRootElement(doc);

    if (root_node == NULL){
        dcp_log(LOG_ERROR, "unable to find root node");
        goto done;
    }

    /* find signature node */
    sign_node = xmlSecFindNode(root_node, xmlSecNodeSignature, xmlSecDSigNs);
    if(sign_node == NULL) {
        dcp_log(LOG_ERROR, "signature node not found");
        goto done;      
    }

    /* create keys manager */
    key_manager = load_certificates();
    if (key_manager == NULL) {
        dcp_log(LOG_ERROR,"create key manager failed");
        goto done;
    }

    /* find certificates */
    cur_node = sign_node;
    while (x509d_node = xmlSecFindNode(cur_node, xmlSecNodeX509Data, xmlSecDSigNs)) {
        cert_node = xmlSecFindNode(x509d_node, xmlSecNodeX509Certificate, xmlSecDSigNs);
        if(cert_node == NULL) {
            dcp_log(LOG_ERROR, "X509certficate node not found");
            goto done;      
        }
        sprintf(cert,"-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n",xmlNodeGetContent(cert_node));
        cert_l = strlen(cert);
        if (xmlSecCryptoAppKeysMngrCertLoadMemory(key_manager, cert, cert_l, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
            dcp_log(LOG_ERROR, "could read X509certificate node value");
            goto done;      
        }
        cur_node = xmlNextElementSibling(x509d_node);
    }

    /* create signature context */
    dsig_ctx = xmlSecDSigCtxCreate(key_manager);

    if (dsig_ctx == NULL) {
        dcp_log(LOG_ERROR,"create signature opendcp failed");
        goto done;
    }

    /* sign the template */
    if (xmlSecDSigCtxVerify(dsig_ctx, sign_node) < 0) {
        dcp_log(LOG_ERROR,"signature verify failed");
        goto done;
    }

    if (dsig_ctx->status != xmlSecDSigStatusSucceeded) {
        dcp_log(LOG_ERROR,"signature validation failed");
        goto done;
    }

    /* success */
    result = 0;

done:    
    /* destroy keys manager */
    xmlSecKeysMngrDestroy(key_manager);

    /* destroy signature context */
    if(dsig_ctx != NULL) {
        xmlSecDSigCtxDestroy(dsig_ctx);
    }
    
    /* destroy xml doc */
    if(doc != NULL) {
        xmlFreeDoc(doc); 
    }

    xmlsec_close();
    return(result);
}
예제 #18
0
파일: sign.c 프로젝트: 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;

}