Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Types | Public Member Functions | Private Member Functions | Private Attributes
Arc::X509Token Class Reference

Class for manipulating X.509 Token Profile. More...

#include <X509Token.h>

Collaboration diagram for Arc::X509Token:
Collaboration graph
[legend]

List of all members.

Public Types

enum  X509TokenType { Signature, Encryption }
 X509TokeType is for distinguishing two types of operation. More...

Public Member Functions

 X509Token (SOAPEnvelope &soap, const std::string &keyfile="")
 Constructor.Parse X509 Token information from SOAP header.
 X509Token (SOAPEnvelope &soap, const std::string &certfile, const std::string &keyfile, X509TokenType token_type=Signature)
 Constructor.
 ~X509Token (void)
 Deconstructor.
 operator bool (void)
 Returns true of constructor succeeded.
bool Authenticate (const std::string &cafile, const std::string &capath)
 Check signature by using the certificare information in X509Token which is parsed by the constructor, and the trusted certificates specified as one of the two parameters.
bool Authenticate (void)
 Check signature by using the cert information in soap message.

Private Member Functions

bool Check (SOAPEnvelope &soap)
 Tells if specified SOAP header has WSSE element and X509Token inside the WSSE element.

Private Attributes

xmlNodePtr signature_nd
std::string cert_str
X509TokenType tokentype

Detailed Description

Class for manipulating X.509 Token Profile.

This class is for generating/consuming X.509 Token profile. Currently it is used by x509token handler (src/hed/pdc/x509tokensh/) It is not necessary to directly called this class. If we need to use X.509 Token functionality, we only need to configure the x509token handler into service and client.

Definition at line 19 of file X509Token.h.


Member Enumeration Documentation

X509TokeType is for distinguishing two types of operation.

*It is used as the parameter of constuctor.

Enumerator:
Signature 
Encryption 

Definition at line 24 of file X509Token.h.


Constructor & Destructor Documentation

Arc::X509Token::X509Token ( SOAPEnvelope &  soap,
const std::string &  keyfile = "" 
)

Constructor.Parse X509 Token information from SOAP header.

X509 Token related information is extracted from SOAP header and stored in class variables. And then it the X509Token object will be used for authentication if the tokentype is Signature; otherwise if the tokentype is Encryption, the encrypted soap body will be decrypted and replaced by decrypted message. keyfile is only needed when the X509Token is encryption token

Definition at line 88 of file X509Token.cpp.

                                                                 : SOAPEnvelope(soap){
  if(!Check(soap)){
    return;    
  }

  //if(!init_xmlsec()) return; 
 
  if(tokentype == Signature) {
    // Apply predefined namespace prefix
    NS ns;
    ns["wsse"]=WSSE_NAMESPACE;
    ns["wsse11"]=WSSE11_NAMESPACE;
    ns["wsu"]=WSU_NAMESPACE;
    header.Namespaces(ns);

    XMLNode xt = header["wsse:Security"];   
    XMLNode signature = xt["Signature"];
    XMLNode token = xt["wsse:BinarySecurityToken"];
    cert_str = (std::string)token;

    //Body reference
    xmlNodePtr bodyPtr = ((X509Token*)(&body))->node_;
    xmlDocPtr docPtr = bodyPtr->doc;
    xmlChar* id = xmlGetProp(bodyPtr, (xmlChar *)"Id");
    xmlAttrPtr id_attr = xmlHasProp(bodyPtr, (xmlChar *)"Id");
    xmlAddID(NULL, docPtr, (xmlChar *)id, id_attr);
    xmlFree(id);

    //BinaryToken reference
    xmlNodePtr tokenPtr = ((X509Token*)(&token))->node_;
    id_attr = xmlHasProp(tokenPtr, (xmlChar *)"Id");
    xmlAddID(NULL, docPtr, (xmlChar *)"binarytoken", id_attr);

    //Signature 
    signature_nd = ((X509Token*)(&signature))->node_; 
    if(!signature_nd) { std::cerr<<"No Signature node in SOAP header"<<std::endl; return; }
  }
  else{
    //Compose the xml structure
    NS ns;
    ns["xenc"] = XENC_NAMESPACE;
    ns["ds"] = DSIG_NAMESPACE;
    XMLNode encrypted_data(ns,"xenc:EncryptedData");
    encrypted_data.NewAttribute("Id") = (std::string)(body["xenc:EncryptedData"].Attribute("Id"));
    encrypted_data.NewAttribute("Type") = (std::string)(body["xenc:EncryptedData"].Attribute("Type"));
    XMLNode enc_method1 = get_node(encrypted_data, "xenc:EncryptionMethod");
    enc_method1.NewAttribute("Algorithm") = "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"; 
    XMLNode keyinfo1 = get_node(encrypted_data, "ds:KeyInfo");
    XMLNode enc_key = get_node(keyinfo1, "xenc:EncryptedKey");
    XMLNode enc_method2 = get_node(enc_key, "xenc:EncryptionMethod");
    enc_method2.NewAttribute("Algorithm") = (std::string)(header["wsse:Security"]["xenc:EncryptedKey"]["xenc:EncryptionMethod"].Attribute("Algorithm"));
    XMLNode keyinfo2 = get_node(enc_key, "ds:KeyInfo");
    XMLNode key_cipherdata = get_node(enc_key, "xenc:CipherData");
    XMLNode key_ciphervalue = get_node(key_cipherdata, "xenc:CipherValue") = (std::string)(header["wsse:Security"]["xenc:EncryptedKey"]["xenc:CipherData"]["xenc:CipherValue"]);

    XMLNode cipherdata = get_node(encrypted_data, "xenc:CipherData");
    XMLNode ciphervalue = get_node(cipherdata, "xenc:CipherValue");
    ciphervalue = (std::string)(body["xenc:EncryptedData"]["xenc:CipherData"]["xenc:CipherValue"]); 

    std::string str;
    encrypted_data.GetXML(str);
    //std::cout<<"Before Decryption++++: "<<str<<std::endl;

    xmlNodePtr todecrypt_nd = ((X509Token*)(&encrypted_data))->node_;

    //Create encryption context
    xmlSecKeysMngr* keys_mngr = NULL;
    //TODO: which key file will be used should be got according to the issuer name and 
    //serial number information in incoming soap head
    std::string issuer_name = (std::string)(header["wsse:Security"]["xenc:EncryptedKey"]["ds:KeyInfo"]["wsse:SecurityTokenReference"]["ds:X509Data"]["ds:X509IssuerSerial"]["ds:X509IssuerName"]);
    std::string serial_number = (std::string)(header["wsse:Security"]["xenc:EncryptedKey"]["ds:KeyInfo"]["wsse:SecurityTokenReference"]["ds:X509Data"]["ds:X509IssuerSerial"]["ds:X509SerialNumber"]);
 
    keys_mngr = load_key_from_keyfile(&keys_mngr, keyfile.c_str());

    xmlSecEncCtxPtr encCtx = NULL;
    encCtx = xmlSecEncCtxCreate(keys_mngr);
    if(encCtx == NULL) {
      std::cerr<<"Failed to create encryption context"<<std::endl;
      return;
    }

    // Decrypt the soap body
    xmlSecBufferPtr decrypted_buf;
    decrypted_buf = xmlSecEncCtxDecryptToBuffer(encCtx, todecrypt_nd);
    if(decrypted_buf == NULL) {
      std::cerr<<"Decryption failed"<<std::endl;
      if(encCtx != NULL) xmlSecEncCtxDestroy(encCtx);
    }
    else { std::cout<<"Decryption succeed"<<std::endl; }

    //encrypted_data.GetXML(str);
    //std::cout<<"After Decryption: "<<str<<std::endl;

    std::cout<<"Decrypted data: "<<decrypted_buf->data<<std::endl;

    //Insert the decrypted data into soap body
    std::string decrypted_str((const char*)decrypted_buf->data);
    XMLNode decrypted_data(decrypted_str); 
    // TODO: less copies
    body.Replace(decrypted_data);

    //Destroy the wsse:Security in header
    header["wsse:Security"].Destroy();

    //Ajust namespaces, delete mutiple definition
    ns = envelope.Namespaces();
    envelope.Namespaces(ns);

    //if(decrypted_buf != NULL)xmlSecBufferDestroy(decrypted_buf);
    if(encCtx != NULL) xmlSecEncCtxDestroy(encCtx);
    if(keys_mngr != NULL)xmlSecKeysMngrDestroy(keys_mngr);
  }

} 

Here is the call graph for this function:

Arc::X509Token::X509Token ( SOAPEnvelope &  soap,
const std::string &  certfile,
const std::string &  keyfile,
X509TokenType  token_type = Signature 
)

Constructor.

Add X509 Token information into the SOAP header. *Generated token contains elements X509 token and signature, and is *meant to be used for authentication on the consuming side.

Parameters:
soapThe SOAP message to which the X509 Token will be inserted
certfileThe certificate file which will be used to encrypt the SOAP body (if parameter tokentype is Encryption), or be used as <wsse:BinarySecurityToken/> (if parameter tokentype is Signature).
keyfileThe key file which will be used to create signature. Not needed when create encryption.
tokentypeToken type: Signature or Encryption.

Definition at line 263 of file X509Token.cpp.

                                                                                                                      : SOAPEnvelope (soap), tokentype(token_type) {

  //if(!init_xmlsec()) return;

  if(tokentype == Signature) {
    // Apply predefined namespace prefix
    NS header_ns, ns;
    header_ns["wsse"]=WSSE_NAMESPACE;
    header_ns["wsse11"]=WSSE11_NAMESPACE;
    header.Namespaces(header_ns);

    ns = envelope.Namespaces();
    ns["wsu"]=WSU_NAMESPACE;
    envelope.Namespaces(ns);

    xmlNodePtr signature = NULL;
    xmlNodePtr reference = NULL;

    // Insert the wsse:Security element
    XMLNode wsse = get_node(header,"wsse:Security");

    //Here only "Reference to a Binary Security Token" is generated, see:
    //Web service security X.509 Certificate Token Profile 1.1
    // Insert the wsse:BinarySecurityToken
    std::string cert;
    cert = get_cert_str(certfile.c_str());
    XMLNode token = wsse.NewChild("wsse:BinarySecurityToken");
    token.NewAttribute("wsu:Id") = "binarytoken";
    token.NewAttribute("ValueType") = X509V3;
    token.NewAttribute("EncodingType") = BASE64BINARY;
    token = cert; 

    //Add signature template 
    signature = xmlSecTmplSignatureCreate(NULL,
                            xmlSecTransformExclC14NId,
                            xmlSecTransformRsaSha1Id, NULL);

    //Add signature into wsse
    xmlNodePtr wsse_nd = ((X509Token*)(&wsse))->node_;
    xmlAddChild(wsse_nd, signature);

    //Add reference for signature
    //Body reference
    xmlNodePtr bodyPtr = ((X509Token*)(&body))->node_;
    xmlDocPtr docPtr = bodyPtr->doc;

    xmlChar* id = NULL;
    id =  xmlGetProp(bodyPtr, (xmlChar *)"Id");
    if(!id) { 
      std::cout<<"There is not wsu:Id attribute in soap body, add a new one"<<std::endl;
      body.NewAttribute("wsu:Id") = "body";
    }
    id =  xmlGetProp(bodyPtr, (xmlChar *)"Id");

    std::string body_uri; body_uri.append("#"); body_uri.append((char*)id);

    reference = xmlSecTmplSignatureAddReference(signature, xmlSecTransformSha1Id,
                                              NULL, (xmlChar *)(body_uri.c_str()), NULL);
    xmlSecTmplReferenceAddTransform(reference, xmlSecTransformEnvelopedId);
    xmlSecTmplReferenceAddTransform(reference, xmlSecTransformExclC14NId);
  
    xmlAttrPtr id_attr = xmlHasProp(bodyPtr, (xmlChar *)"Id");
    xmlAddID(NULL, docPtr, (xmlChar *)id, id_attr);
    xmlFree(id);

    //BinaryToken reference
    xmlNodePtr tokenPtr = ((X509Token*)(&token))->node_;
 
    std::string token_uri; token_uri.append("#").append("binarytoken");

    reference = xmlSecTmplSignatureAddReference(signature, xmlSecTransformSha1Id,
                                                    NULL, (xmlChar *)(token_uri.c_str()), NULL);
    xmlSecTmplReferenceAddTransform(reference, xmlSecTransformEnvelopedId);
    xmlSecTmplReferenceAddTransform(reference, xmlSecTransformExclC14NId);
  
    id_attr = xmlHasProp(tokenPtr, (xmlChar *)"Id");
    xmlAddID(NULL, docPtr, (xmlChar *)"binarytoken", id_attr);

    xmlNodePtr key_info = xmlSecTmplSignatureEnsureKeyInfo(signature, NULL);
    //xmlSecTmplKeyInfoAddX509Data(key_info);

    XMLNode keyinfo_nd = wsse["Signature"]["KeyInfo"];
    XMLNode st_ref_nd = keyinfo_nd.NewChild("wsse:SecurityTokenReference");
    XMLNode ref_nd = st_ref_nd.NewChild("wsse:Reference");
    ref_nd.NewAttribute("URI") = token_uri;

    //Sign the SOAP message
    xmlSecDSigCtx *dsigCtx = xmlSecDSigCtxCreate(NULL);
    //load private key, assuming there is no need for passphrase
    dsigCtx->signKey = xmlSecCryptoAppKeyLoad(keyfile.c_str(), xmlSecKeyDataFormatPem, NULL, NULL, NULL);
    //dsigCtx->signKey = xmlSecCryptoAppKeyLoad(keyfile.c_str(), xmlSecKeyDataFormatPem, NULL, (void*)passphrase_callback, NULL);
    if(dsigCtx->signKey == NULL) {
      xmlSecDSigCtxDestroy(dsigCtx);
      std::cerr<<"Can not load key"<<std::endl; return;
    }
    /* the following code could be necessary if we need <dsig:X509Data/>
    if(xmlSecCryptoAppKeyCertLoad(dsigCtx->signKey, certfile.c_str(), xmlSecKeyDataFormatPem) < 0) {
      xmlSecDSigCtxDestroy(dsigCtx);
      std::cerr<<"Can not load certificate"<<std::endl; return;       
    }
    */
    if (xmlSecDSigCtxSign(dsigCtx, signature) < 0) {
      xmlSecDSigCtxDestroy(dsigCtx);
      std::cerr<<"Can not sign soap message"<<std::endl; return;
    }

    if(dsigCtx != NULL)xmlSecDSigCtxDestroy(dsigCtx);

    std::string str;
    envelope.GetXML(str);
    std::cout<<"Envelope: "<<str<<std::endl;
  }
  else {
    // Apply predefined namespace prefix
    NS ns, header_ns;
    header_ns["wsse"]=WSSE_NAMESPACE;
    header_ns["wsse11"]=WSSE11_NAMESPACE;
    header_ns["wsu"]=WSU_NAMESPACE;
    header_ns["ds"]=DSIG_NAMESPACE;
    header.Namespaces(header_ns);

    ns = envelope.Namespaces();
    ns["xenc"]=XENC_NAMESPACE;
    envelope.Namespaces(ns);
 
    // Insert the wsse:Security element
    XMLNode wsse = get_node(header,"wsse:Security");

    //Generate a copy of body node, now all of the things will based on this node;
    //After the encryption, the body node will be copy back to original one
    XMLNode body_cp;
    body.New(body_cp);

    xmlNodePtr bodyPtr = ((X509Token*)(&body_cp))->node_;
    xmlDocPtr docPtr = bodyPtr->doc;

    xmlNodePtr encDataNode = NULL;
    xmlNodePtr keyInfoNode = NULL;
    xmlNodePtr encKeyNode = NULL;
    xmlNodePtr keyInfoNode2 = NULL;
    xmlSecEncCtxPtr encCtx = NULL;
 
    //Create encryption template for a specific symetric key type
    encDataNode = xmlSecTmplEncDataCreate(docPtr , xmlSecTransformDes3CbcId,
                            (const xmlChar*)"encrypted", xmlSecTypeEncElement, NULL, NULL);
    if(encDataNode == NULL) { std::cerr<<"Failed to create encryption template"<<std::endl; return; }

    // Put encrypted data in the <enc:CipherValue/> node
    if(xmlSecTmplEncDataEnsureCipherValue(encDataNode) == NULL){
     std::cerr<<"Failed to add CipherValue node"<<std::endl;   
     if(encDataNode != NULL) xmlFreeNode(encDataNode);
     return;
    }

    // Add <dsig:KeyInfo/>
    keyInfoNode = xmlSecTmplEncDataEnsureKeyInfo(encDataNode, NULL);
    if(keyInfoNode == NULL) { 
      std::cerr<<"Failed to add key info"<<std::endl;
      if(encDataNode != NULL) xmlFreeNode(encDataNode);
      return;
    }

    // Add <enc:EncryptedKey/> to store the encrypted session key
    encKeyNode = xmlSecTmplKeyInfoAddEncryptedKey(keyInfoNode, 
                                xmlSecTransformRsaPkcs1Id, 
                                NULL, NULL, NULL);
    if(encKeyNode == NULL) { 
      std::cerr<<"Failed to add key info"<<std::endl;
      if(encDataNode != NULL) xmlFreeNode(encDataNode);
      return;
    }

    // Put encrypted key in the <enc:CipherValue/> node
    if(xmlSecTmplEncDataEnsureCipherValue(encKeyNode) == NULL) std::cerr<<"Error: failed to add CipherValue node"<<std::endl;

    // Add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to <enc:EncryptedKey/> 
    keyInfoNode2 = xmlSecTmplEncDataEnsureKeyInfo(encKeyNode, NULL);
    if(keyInfoNode2 == NULL){
      std::cerr<<"Failed to add key info"<<std::endl;
      if(encDataNode != NULL) xmlFreeNode(encDataNode);
      return;
    }

    //Create encryption context
    xmlSecKeysMngr* keys_mngr = NULL;
    keys_mngr = load_key_from_certfile(&keys_mngr, certfile.c_str());

    encCtx = xmlSecEncCtxCreate(keys_mngr);
    if(encCtx == NULL) {
      std::cerr<<"Failed to create encryption context"<<std::endl;
      if(encDataNode != NULL) xmlFreeNode(encDataNode);
      return;
    }

    // Generate a Triple DES key
    encCtx->encKey = xmlSecKeyGenerate(xmlSecKeyDataDesId, 192, xmlSecKeyDataTypeSession);
    if(encCtx->encKey == NULL) {
      std::cerr<<"Failed to generate session des key"<<std::endl;
      if(encCtx != NULL) xmlSecEncCtxDestroy(encCtx);
      if(encDataNode != NULL) xmlFreeNode(encDataNode);
      return;
    }
    // Encrypt the soap body, here the body node is encrypted, not only the content under body node
    // TODO: not sure whether the body node, or the content under body node shoud be encrypted
    if(xmlSecEncCtxXmlEncrypt(encCtx, encDataNode, bodyPtr) < 0) { 
      std::cerr<<"Encryption failed"<<std::endl;
      if(encCtx != NULL) xmlSecEncCtxDestroy(encCtx);
      if(encDataNode != NULL) xmlFreeNode(encDataNode);
    }

    //The template has been inserted in the doc
    ((X509Token*)(&body_cp))->node_ = (bodyPtr=encDataNode);
    encDataNode = NULL;

    //if(encCtx != NULL){ xmlSecEncCtxDestroy(encCtx); encCtx = NULL; }
    
    std::string str;
    body_cp.GetDoc(str);
    std::cout<<"Body new : "<<str<<std::endl;

    //Put the encrypted information into soap head and soap body according to x509token specification

    XMLNode encrypted_data = body_cp;//.GetRoot();
    encrypted_data.GetXML(str);
    std::cout<<"Encrypted data : "<<str<<std::endl; 

    //Delete the existing element under <Body/>
    for(int i=0;;i++) {
      XMLNode nd = body.Child(i);
      if(!nd) break;
      nd.Destroy();
    }

    XMLNode body_encdata = get_node(body,"xenc:EncryptedData");
    body_encdata.NewAttribute("wsu:Id") = (std::string)(encrypted_data.Attribute("Id"));
    body_encdata.NewAttribute("Type") = (std::string)(encrypted_data.Attribute("Type"));
    
    XMLNode body_cipherdata = get_node(body_encdata,"xenc:CipherData");
    get_node(body_cipherdata,"xenc:CipherValue") = (std::string)(encrypted_data["CipherData"]["CipherValue"]); 

 
    XMLNode enc_key = get_node(wsse,"xenc:EncryptedKey");

    XMLNode enc_method = get_node(enc_key,"xenc:EncryptionMethod");   
    enc_method.NewAttribute("Algorithm") = (std::string)(encrypted_data["KeyInfo"]["EncryptedKey"]["EncryptionMethod"].Attribute("Algorithm"));  

    XMLNode keyinfo = get_node(enc_key, "ds:KeyInfo");
    XMLNode sec_token_ref = get_node(keyinfo, "wsse:SecurityTokenReference");
    XMLNode x509_data =  get_node(sec_token_ref, "ds:X509Data");
    XMLNode x509_issuer_serial = get_node(x509_data, "ds:X509IssuerSerial");
    XMLNode x509_issuer_name = get_node(x509_issuer_serial, "ds:X509IssuerName");
    XMLNode x509_serial_number = get_node(x509_issuer_serial, "ds:X509SerialNumber");
    //TODO: issuer name and issuer number should be extracted from certificate
    //There should be some way by which the sender could get the peer certificate
    //and use the public key inside this certificate to encrypt the message. 
    X509* cert = NULL;
    BIO* certbio = NULL;
    certbio = BIO_new_file(certfile.c_str(), "r");
    cert = PEM_read_bio_X509(certbio, NULL, NULL, NULL);

    //get formated issuer name from certificate
    BIO* namebio = NULL;
    namebio = BIO_new(BIO_s_mem());
    X509_NAME_print_ex(namebio, X509_get_issuer_name(cert), 0, XN_FLAG_SEP_CPLUS_SPC);
    char name[256]; 
    memset(name,0,256);
    int length = BIO_read(namebio, name, 256);
    //char* name = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);

    std::string issuer_name(name);
    //OPENSSL_free(name);
    int serial = (int) ASN1_INTEGER_get(X509_get_serialNumber(cert));
    std::stringstream ss; std::string serial_number;
    ss<<serial; ss>>serial_number;
    x509_issuer_name = issuer_name;
    x509_serial_number = serial_number;

    XMLNode key_cipherdata = get_node(enc_key, "xenc:CipherData");
    key_cipherdata.NewChild("xenc:CipherValue") = (std::string)(encrypted_data["KeyInfo"]["EncryptedKey"]["CipherData"]["CipherValue"]);

    XMLNode ref_list = get_node(enc_key, "xenc:ReferenceList");
    XMLNode ref_item = get_node(ref_list,"xenc:DataReference");
    ref_item.NewAttribute("URI") = "#" + (std::string)(encrypted_data.Attribute("Id"));

    if(encCtx != NULL) xmlSecEncCtxDestroy(encCtx);
    if(keys_mngr != NULL)xmlSecKeysMngrDestroy(keys_mngr);

    envelope.GetXML(str);
    std::cout<<"Envelope: "<<str<<std::endl;
  }
}

Here is the call graph for this function:

Deconstructor.

Nothing to be done except finalizing the xmlsec library.

Definition at line 555 of file X509Token.cpp.

                          {
  //final_xmlsec();
}

Member Function Documentation

bool Arc::X509Token::Authenticate ( const std::string &  cafile,
const std::string &  capath 
)

Check signature by using the certificare information in X509Token which is parsed by the constructor, and the trusted certificates specified as one of the two parameters.

Not only the signature (in the X509Token) itself is checked, but also the certificate which is supposed to check the signature needs to be trused (which means the certificate is issued by the ca certificate from CA file or CA directory). At least one the the two parameters should be set.

Parameters:
cafileThe CA file
capathThe CA directory
Returns:
true if authentication passes; otherwise false

Definition at line 228 of file X509Token.cpp.

                                                                             {
  xmlSecKeysMngr* keys_manager = NULL;
  xmlSecDSigCtx *dsigCtx;

  keys_manager = load_trusted_certs(&keys_manager, cafile.c_str(), capath.c_str());
  //Load keyInfo. Because xmlsec only accept standard <X509Data/>, here we are using some 
  //kind of hack method by insertinga <X509Data/> into <KeyInfo/>, after verification, we 
  //delete the node.
  //TODO. The other option is to implement a "key data" object and some "read" "write" method as 
  //xmlsec does, it will be more complicated but it is a more correct way. Put it as TODO
  XMLNode keyinfo_nd = header["wsse:Security"]["Signature"]["KeyInfo"];
  XMLNode st_ref_nd = keyinfo_nd["wsse:SecurityTokenReference"];
  XMLNode x509data_node = get_node(keyinfo_nd, "X509Data");
  XMLNode x509cert_node = get_node(x509data_node, "X509Certificate");
  x509cert_node = cert_str;

  dsigCtx = xmlSecDSigCtxCreate(keys_manager);
  if (xmlSecDSigCtxVerify(dsigCtx, signature_nd) < 0) {
    xmlSecDSigCtxDestroy(dsigCtx);
    if (keys_manager) xmlSecKeysMngrDestroy(keys_manager);
    std::cerr<<"Signature verification failed (with trusted certificate checking)"<<std::endl;
    x509data_node.Destroy();
    return false;
  }
  
  if(keys_manager != NULL)xmlSecKeysMngrDestroy(keys_manager);
  if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
    std::cout<<"Succeed to verify the signature in SOAP message (with trusted certificate checking)"<<std::endl;
    xmlSecDSigCtxDestroy(dsigCtx); x509data_node.Destroy(); return true;
  }
  else { std::cerr<<"Invalid signature"<<std::endl; xmlSecDSigCtxDestroy(dsigCtx); x509data_node.Destroy(); return false; }

}

Here is the call graph for this function:

Here is the caller graph for this function:

Check signature by using the cert information in soap message.

Only the signature itself is checked, and it is not guranteed that the certificate which is supposed to check the signature is trusted.

Definition at line 203 of file X509Token.cpp.

                                 {
  xmlSecDSigCtx *dsigCtx;
  dsigCtx = xmlSecDSigCtxCreate(NULL);

  //Load public key from incoming soap's security token
  xmlSecKey* pubkey = get_key_from_certstr(cert_str);
  if (pubkey == NULL){
    xmlSecDSigCtxDestroy(dsigCtx);
    std::cerr<<"Can not load public key"<<std::endl; return false;
  }
  dsigCtx->signKey = pubkey;

  if (xmlSecDSigCtxVerify(dsigCtx, signature_nd) < 0) {
    xmlSecDSigCtxDestroy(dsigCtx);
    std::cerr<<"Signature verification failed"<<std::endl;
    return false;
  }

  if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
    std::cout<<"Succeed to verify the signature in SOAP message"<<std::endl;
    xmlSecDSigCtxDestroy(dsigCtx); return true;
  }
  else { std::cerr<<"Invalid signature"<<std::endl; xmlSecDSigCtxDestroy(dsigCtx); return false; }
}

Here is the call graph for this function:

bool Arc::X509Token::Check ( SOAPEnvelope &  soap) [private]

Tells if specified SOAP header has WSSE element and X509Token inside the WSSE element.

Definition at line 60 of file X509Token.cpp.

                                        {
  XMLNode header = soap.Header();
  if(header.NamespacePrefix(WSSE_NAMESPACE).empty()){
    std::cerr<<"No wsse namespace in SOAP Header"<<std::endl;
    return false;
  }
  XMLNode wsse;
  if(!(wsse=header["wsse:Security"])) {
    std::cerr<<"No Security element in SOAP Header"<<std::endl;
    return false;
  };
  if((bool)(wsse["wsse:BinarySecurityToken"])) {
    tokentype = Signature;
  }
  else if((bool)(wsse["xenc:EncryptedKey"])) {
    tokentype = Encryption;
  }
  else {
    std::cerr<<"No wsse:Security or xenc:EncryptedKey element in SOAP Header"<<std::endl;
    return false;
  };
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Arc::X509Token::operator bool ( void  )

Returns true of constructor succeeded.

Definition at line 84 of file X509Token.cpp.

                             {
  return (bool)header;
}

Member Data Documentation

std::string Arc::X509Token::cert_str [private]

Definition at line 87 of file X509Token.h.

xmlNodePtr Arc::X509Token::signature_nd [private]

Definition at line 86 of file X509Token.h.

Definition at line 88 of file X509Token.h.


The documentation for this class was generated from the following files: