📄 process_request.c
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include <string.h>#include <libxml/tree.h>#include <libxml/xmlmemory.h>#include <libxml/parser.h>#if 0#ifndef XMLSEC_NO_XSLT#include <libxslt/xslt.h>#endif /* XMLSEC_NO_XSLT */#endif#include <xmlsec/xmlsec.h>#include <xmlsec/xmltree.h>#include <xmlsec/xmlenc.h>#include <xmlsec/xmldsig.h>#include <xmlsec/crypto.h>#include <libxml/xpath.h>#include <libxml/xpathInternals.h>#include <xmlsec/x509.h>#include "process_request.h"#include "process_request_defines.h"/* "/saml:Assertion" */#define XPATH_ASSERTION "/" SAML_PFX ":" ASSERTION/* "/saml:Assertion/dsig:Signature" */#define XPATH_SIGNATURE XPATH_ASSERTION "/" DSIG_PFX ":" \ SIGNATURE/* "/saml:Assertion/dsig:Signature/dsig:KeyInfo" */#define XPATH_KEY_INFO XPATH_SIGNATURE "/" DSIG_PFX ":" KEY_INFO/* "/saml:Assertion/dsig:Signature/dsig:KeyInfo/dsig:KeyValue/dsig:RSAKeyValue" */#define XPATH_RSA_KEY_VALUE XPATH_KEY_INFO "/" DSIG_PFX ":" KEY_VALUE "/" \ DSIG_PFX ":" RSA_KEY_VALUE/* "/saml:Assertion/dsig:Signature/dsig:KeyInfo/dsig:KeyValue/dsig:RSAKeyValue/dsig:Modulus" */#define XPATH_MODULUS XPATH_RSA_KEY_VALUE "/" DSIG_PFX ":" MODULUS/* "/saml:Assertion/dsig:Signature/dsig:KeyInfo/dsig:KeyValue/dsig:RSAKeyValue/dsig:Exponent" */#define XPATH_EXPONENT XPATH_RSA_KEY_VALUE "/" DSIG_PFX ":" EXPONENT /* "/saml:Assertion/dsig:Signature/dsig:KeyInfo/dsig:X509Data" */#define XPATH_X509_DATA XPATH_KEY_INFO "/" DSIG_PFX ":" X509_DATA /* "/saml:Assertion/dsig:Signature/dsig:KeyInfo/dsig:X509Data/ * dsig:X509Certificate" */#define XPATH_X509_CERT XPATH_X509_DATA "/" DSIG_PFX ":" X509_CERT/* "/enc:EncryptedData" */#define XPATH_ENC_DATA "/" ENC_PFX ":" ENCRYPTED_DATA/* "/saml:Assertion/saml:AttributeStatement/saml:Attribute" */#define XPATH_ATTRIBUTE XPATH_ASSERTION "/" SAML_PFX ":" ATTRIBUTE_STATEMENT \ "/" SAML_PFX ":" ATTRIBUTE#define XPATH_OBJ_SIZE(obj) ((obj) ? (((obj)->nodesetval) ? \ ((obj)->nodesetval->nodeNr) : 0) : 0)#define XPATH_OBJ_TO_NODE(obj, i) \ ((xmlNode *) \ (obj) ? (((obj)->nodesetval) ? \ ((obj)->nodesetval->nodeTab[(i)]) : NULL) : NULL)static void *malloc_def(size_t size, void *cb_ctx);static void free_def(void *ptr, void *cb_ctx);static void logger_def(const char *msg, pc_log_level_t level, void *cb_ctx);static int decrypt_token(xmlDoc *doc, process_context_t *ctx);static int register_namespaces(xmlXPathContext *xpath_ctx);static xmlSecKeysMngr *keys_mnrg_create_and_load_priv_key(process_context_t *ctx);static xmlXPathObject *cspace_xpath_evaluate(xmlDoc *doc, xmlChar *xpath_exp);static int verify_signature(xmlDoc *doc, process_context_t *ctx);static int register_id(xmlDoc *doc, xmlNodePtr node, const xmlChar* idName);static int extract_info(process_context_t *ctx, xmlDoc *doc);int cspace_process_request(process_context_t *ctx, const char *req){ int res = FAIL; xmlDoc *doc = NULL; /* Load XML document */ doc = xmlReadMemory(req, (int)strlen(req), NULL, NULL, 0); if (!decrypt_token(doc, ctx)) { /*log*/ goto done; } if (!ctx->set_header_fn) { /*log*/ goto done; } if (!extract_info(ctx, doc)) { goto done; } /* verify signature */ if (!verify_signature(doc, ctx)) { /*log*/ goto done; } res = SUCC;done: if (doc) xmlFreeDoc(doc); /*add the "cardspace_state" header*/ if (res) { (*ctx->set_header_fn)(NULL, cspace_strdup(CARDSPACE_HEADER_STATE, ctx->allocator), cspace_strdup(CARDSPACE_STATE_SUCCESS, ctx->allocator), ctx->header_container, ctx->set_header_cb_ctx); } else { (*ctx->set_header_fn)(NULL, cspace_strdup(CARDSPACE_HEADER_STATE, ctx->allocator), cspace_strdup(CARDSPACE_STATE_FAIL, ctx->allocator), ctx->header_container, ctx->set_header_cb_ctx); } return res;}void cspace_process_context_set_logger(process_context_t *ctx, logger_cb_t logger, void *cb_ctx){ ctx->logger_fn = logger; ctx->logger_cb_ctx = cb_ctx;}void cspace_process_context_set_header_callback_context(process_context_t *ctx, void *cb_ctx){ ctx->set_header_cb_ctx = cb_ctx;}/*caller must free the return xmlXPathObject*/static xmlXPathObject *cspace_xpath_evaluate(xmlDoc *doc, xmlChar *xpath_exp){ xmlXPathContext *xpath_ctx = NULL; xmlXPathObject *xpath_obj = NULL; /*need to be init to NULL, it will returned even in the error path*/ /* Create xpath evaluation context */ xpath_ctx = xmlXPathNewContext(doc); if (!xpath_ctx) { goto done; } /* Register namespaces from list (if any) */ if (!register_namespaces(xpath_ctx)) { goto done; } xpath_obj = xmlXPathEvalExpression(xpath_exp, xpath_ctx);done: if (xpath_ctx) xmlXPathFreeContext(xpath_ctx); return xpath_obj;}static int verify_signature(xmlDoc *doc, process_context_t *ctx){ int res = FAIL; xmlSecKeysMngr *vfy_mngr = NULL; xmlXPathObject *xpath_obj = NULL; xmlSecDSigCtx *dsig_ctx = NULL; xmlNode *vfy_node = NULL; vfy_mngr = xmlSecKeysMngrCreate(); if(vfy_mngr == NULL) { fprintf(stderr, "Error: failed to create keys manager.\n"); goto done; } if(xmlSecCryptoAppDefaultKeysMngrInit(vfy_mngr) < 0) { fprintf(stderr, "Error: failed to initialize keys manager.\n"); goto done; } if (ctx->ca_file) { if(xmlSecCryptoAppKeysMngrCertLoad(vfy_mngr, ctx->ca_file, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { fprintf(stderr,"Error: failed to load pem certificate from \n" ); goto done; } } /* Add the ID for non-standard reference refer to http://ml.osdir.com/text.xml.xmlsec/2003-12/msg00019.html */ if (!register_id(doc, xmlDocGetRootElement(doc), BAD_CAST ASSERTION_ID)) { /*log*/ goto done; } dsig_ctx = xmlSecDSigCtxCreate(vfy_mngr); if (!dsig_ctx) { goto done; } xpath_obj = cspace_xpath_evaluate(doc, BAD_CAST XPATH_SIGNATURE); if (!xpath_obj) { goto done; } vfy_node = XPATH_OBJ_TO_NODE(xpath_obj, 0); if (xmlSecDSigCtxVerify(dsig_ctx, vfy_node) < 0) { goto done; } if (dsig_ctx->status != xmlSecDSigStatusSucceeded) { goto done; } res = SUCC;#ifdef CSPACE_DEBUG printf("\nVERIFICATION SUCCESS!\n");#endifdone: if (xpath_obj) xmlXPathFreeObject(xpath_obj); if (dsig_ctx) xmlSecDSigCtxDestroy(dsig_ctx); if (vfy_mngr) xmlSecKeysMngrDestroy(vfy_mngr); /* TODO: Add the free code */ return res;}static int extract_info(process_context_t *ctx, xmlDoc *doc){ int res = FAIL; int i; xmlXPathObject *attrs_obj = NULL; xmlNode *attr_node = NULL; xmlNode *text_node = NULL; xmlXPathObject *mod_obj = NULL; xmlNode *mod_node = NULL; xmlXPathObject *exp_obj = NULL; xmlNode *exp_node = NULL; xmlXPathObject *assertion_obj = NULL; xmlNode *assertion_node = NULL; xmlXPathObject *x509_obj = NULL; xmlNode *x509_node = NULL; char *attr_name = NULL; char *attr_val = NULL; char *attr_ns = NULL; char *x509_data = NULL; char *issuer = NULL; char *modulus = NULL; char *exponent = NULL; char *mod_exp = NULL; assertion_obj = cspace_xpath_evaluate(doc, BAD_CAST XPATH_ASSERTION); if (!assertion_obj) { goto done; } else { assertion_node = XPATH_OBJ_TO_NODE(assertion_obj, 0); issuer = (char *) xmlGetProp(assertion_node, BAD_CAST ISSUER); } (*ctx->set_header_fn)(NULL, CARDSPACE_HEADER_ISSUER, issuer, ctx->header_container, ctx->set_header_cb_ctx); attrs_obj = cspace_xpath_evaluate(doc, BAD_CAST XPATH_ATTRIBUTE); if (!attrs_obj) { goto done; } for (i = 0; i < XPATH_OBJ_SIZE(attrs_obj); i++) { attr_val = NULL; attr_node = XPATH_OBJ_TO_NODE(attrs_obj, i); attr_name = (char *) xmlGetProp(attr_node, BAD_CAST ATTRIBUTE_NAME); attr_ns = (char *) xmlGetProp(attr_node, BAD_CAST ATTRIBUTE_NAMESPACE); /*TODO: validate the node structure*/ attr_node = attr_node->children; if (!attr_node) { continue; } text_node = attr_node->children; if (text_node && xmlNodeIsText(text_node)) { attr_val = cspace_strdup((char *) text_node->content, ctx->allocator); } (*ctx->set_header_fn)(attr_ns, attr_name, attr_val, ctx->header_container, ctx->set_header_cb_ctx); } /* if (self issued) res = SUCC & goto done; */ if (strcmp(issuer, ISSUER_SELF) == 0) { char *t = NULL; mod_obj = cspace_xpath_evaluate(doc, BAD_CAST XPATH_MODULUS); if (!mod_obj) { goto done; } mod_node = XPATH_OBJ_TO_NODE(mod_obj, 0); mod_node = mod_node->children; if (!mod_node) { /* Modulus not found */ goto done; } modulus = (char *) mod_node->content; exp_obj = cspace_xpath_evaluate(doc, BAD_CAST XPATH_EXPONENT); if (!exp_obj) { goto done; } exp_node = XPATH_OBJ_TO_NODE(exp_obj, 0); exp_node = exp_node->children; if (!exp_node) { goto done; } exponent = (char *) exp_node->content; mod_exp = pc_malloc(strlen(modulus) + strlen(exponent) + 2, ctx); t = mod_exp; cspace_strcpy(t, modulus); t += strlen(modulus); *t = ','; t++; cspace_strcpy(t, exponent); t += strlen(exponent); *t = '\0'; (*ctx->set_header_fn)(NULL, cspace_strdup(CARDSPACE_HEADER_CERTIFICATE, ctx->allocator), mod_exp, ctx->header_container, ctx->set_header_cb_ctx); /* TODO:DONE add the Exp & Mod to headers */ res = SUCC; goto done; } x509_obj = cspace_xpath_evaluate(doc, BAD_CAST XPATH_X509_CERT); if (!x509_obj) { goto done; } x509_node = XPATH_OBJ_TO_NODE(x509_obj, 0); x509_node = x509_node->children; /*now it is the text node containing the cert*/ if (x509_node && xmlNodeIsText(x509_node)) { x509_data = cspace_strdup((char *)x509_node->content, ctx->allocator);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -