예제 #1
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;
  }
}
예제 #2
0
/**
 * load_keys:
 * @files:		the list of filenames.
 * @files_size:		the number of filenames in #files.
 *
 * Creates simple keys manager and load PEM keys from #files in it.
 * The caller is responsible for destroing returned keys manager using
 * @xmlSecKeysMngrDestroy.
 *
 * Returns the pointer to newly created keys manager or NULL if an error
 * occurs.
 */
xmlSecKeysMngrPtr 
load_keys(char** files, int files_size) {
    xmlSecKeysMngrPtr mngr;
    xmlSecKeyPtr key;
    int i;
    
    assert(files);
    assert(files_size > 0);
    
    /* create and initialize keys manager, we use a simple list based
     * keys manager, implement your own xmlSecKeysStore klass if you need
     * something more sophisticated 
     */
    mngr = xmlSecKeysMngrCreate();
    if(mngr == NULL) {
	fprintf(stderr, "Error: failed to create keys manager.\n");
	return(NULL);
    }
    if(xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) {
	fprintf(stderr, "Error: failed to initialize keys manager.\n");
	xmlSecKeysMngrDestroy(mngr);
	return(NULL);
    }    
    
    for(i = 0; i < files_size; ++i) {
	assert(files[i]);

	/* load key */
	key = xmlSecCryptoAppKeyLoad(files[i], xmlSecKeyDataFormatPem, NULL, NULL, NULL);
	if(key == NULL) {
    	    fprintf(stderr,"Error: failed to load pem key from \"%s\"\n", files[i]);
	    xmlSecKeysMngrDestroy(mngr);
	    return(NULL);
	}

	/* set key name to the file name, this is just an example! */
	if(xmlSecKeySetName(key, BAD_CAST files[i]) < 0) {
    	    fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", files[i]);
	    xmlSecKeyDestroy(key);
	    xmlSecKeysMngrDestroy(mngr);
	    return(NULL);
	}
	
	/* add key to keys manager, from now on keys manager is responsible 
	 * for destroying key 
	 */
	if(xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key) < 0) {
    	    fprintf(stderr,"Error: failed to add key from \"%s\" to keys manager\n", files[i]);
	    xmlSecKeyDestroy(key);
	    xmlSecKeysMngrDestroy(mngr);
	    return(NULL);
	}
    }

    return(mngr);
}
예제 #3
0
파일: crypto.c 프로젝트: Arcenciel/DDReader
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 */
}
예제 #4
0
파일: decrypt3.c 프로젝트: lsh123/xmlsec
/**
 * 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);
}
예제 #5
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);
}
예제 #6
0
xmlSecKeysMngrPtr load_certificates_sign(opendcp_t *opendcp) {
    xmlSecKeysMngrPtr key_manager;
    xmlSecKeyPtr      key; 
        
    /* create and initialize keys manager */
    key_manager = xmlSecKeysMngrCreate();

    if (key_manager == NULL) {
        fprintf(stderr, "Error: failed to create keys manager.\n");
        return(NULL);
    }

    if (xmlSecCryptoAppDefaultKeysMngrInit(key_manager) < 0) {
        fprintf(stderr, "Error: failed to initialize keys manager.\n");
        xmlSecKeysMngrDestroy(key_manager);
        return(NULL);
    }    

    /* read key file */
    if (opendcp->xml_signature.private_key) {
        key = xmlSecCryptoAppKeyLoad(opendcp->xml_signature.private_key, xmlSecKeyDataFormatPem, NULL, NULL, NULL);
    } else {
        key = xmlSecCryptoAppKeyLoadMemory(opendcp_private_key, strlen((char *)opendcp_private_key),xmlSecKeyDataFormatPem, NULL, NULL, NULL);
    }
  
    if (xmlSecCryptoAppDefaultKeysMngrAdoptKey(key_manager, key) < 0) {
        fprintf(stderr, "Error: failed to initialize keys manager.\n");
        xmlSecKeysMngrDestroy(key_manager);
        return(NULL);
    }
 
    /* load root certificate */
    if (opendcp->xml_signature.root) {
        if (xmlSecCryptoAppKeysMngrCertLoad(key_manager, opendcp->xml_signature.root, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
            fprintf(stderr,"Error: failed to load pem certificate \"%s\"\n", opendcp->xml_signature.root);
            xmlSecKeysMngrDestroy(key_manager);
            return(NULL);
        }
    } else {
        if (xmlSecCryptoAppKeysMngrCertLoadMemory(key_manager, opendcp_root_cert, strlen((char* )opendcp_root_cert), xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
            fprintf(stderr,"Error: failed to load pem certificate from memory\n");
            xmlSecKeysMngrDestroy(key_manager);
            return(NULL);
        }
    }
    
    /* load ca (intermediate) certificate */
    if (opendcp->xml_signature.ca) {
        if (xmlSecCryptoAppKeysMngrCertLoad(key_manager, opendcp->xml_signature.ca, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
            fprintf(stderr,"Error: failed to load pem certificate \"%s\"\n", opendcp->xml_signature.ca);
            xmlSecKeysMngrDestroy(key_manager);
            return(NULL);
        }
    } else {
        if (xmlSecCryptoAppKeysMngrCertLoadMemory(key_manager, opendcp_ca_cert, strlen((char *)opendcp_ca_cert), xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
            fprintf(stderr,"Error: failed to load pem certificate from memory\n");
            xmlSecKeysMngrDestroy(key_manager);
            return(NULL);
        }
    }

    return(key_manager);
}
예제 #7
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;
}
예제 #8
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);
}
예제 #9
0
파일: crypto.c 프로젝트: Arcenciel/DDReader
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);
}
예제 #10
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;

}