Ejemplo n.º 1
0
axis2_status_t verify(axutil_env_t *env,
        axis2_char_t *filename,
        openssl_pkey_t *prvkey ,
        oxs_x509_cert_t *cert)
{
    oxs_sign_ctx_t *sign_ctx = NULL;
    axiom_node_t *tmpl = NULL;
    axis2_status_t status = AXIS2_FAILURE;

    tmpl = load_sample_xml(env , tmpl, filename);
    printf("File : \n%s\n", axiom_node_to_string(tmpl, env));
    sign_ctx = oxs_sign_ctx_create(env);
    if(sign_ctx){
        axiom_node_t *sig_node = NULL;
        /*Set the operation*/
        oxs_sign_ctx_set_operation(sign_ctx, env, OXS_SIGN_OPERATION_VERIFY);
        
        sig_node = oxs_axiom_get_first_child_node_by_name(env, tmpl,
                                    OXS_NODE_SIGNATURE, OXS_DSIG_NS, OXS_DS );
        if(!sig_node){
            printf("Verification : Cannot find ds:Signature node\n");
            return AXIS2_FAILURE;
        }
       
        /**If the certificate is not given check key information*/
        if(!cert){
            axiom_node_t *ki_node = NULL;
            axiom_node_t *x509_node = NULL;
            ki_node = oxs_axiom_get_first_child_node_by_name(env, sig_node, OXS_NODE_KEY_INFO, OXS_DSIG_NS, OXS_DS);
            x509_node = oxs_axiom_get_first_child_node_by_name(env, ki_node, OXS_NODE_X509_DATA, OXS_DSIG_NS, OXS_DS);
           
            cert = oxs_x509_cert_create(env);
            printf("No certificate is given. Fetching certificate from the KeyInfo\n");
            status =  oxs_xml_key_process_X509Data(env, x509_node, cert);
            if(AXIS2_FAILURE == status){
                printf("Error reading KeyInfo\n");
                return AXIS2_FAILURE;
            }
        }            

        
        /*Set certificate*/
        if(cert){
            oxs_sign_ctx_set_certificate(sign_ctx, env, cert);
        }else{
            printf("Certificate is NULL\n");
            return AXIS2_FAILURE;
        }
        /*Verify*/
        status = oxs_xml_sig_verify(env, sign_ctx, sig_node, tmpl);
        if(AXIS2_SUCCESS != status){
            printf("\nSignature Failed :-(\n");
        }else{
            printf("\nSignature Verified :-)\n");
        }
    }

    return status;
}
Ejemplo n.º 2
0
static axis2_status_t
oxs_xml_enc_process_key_info(
    const axutil_env_t *env,
    oxs_asym_ctx_t *asym_ctx,
    axiom_node_t *key_info_node,
    axiom_node_t *parent_node)
{
    axiom_node_t *st_ref_node = NULL;

    st_ref_node = oxs_axiom_get_first_child_node_by_name(env, key_info_node,
        OXS_NODE_SECURITY_TOKEN_REFRENCE, OXS_WSSE_XMLNS, OXS_WSSE);
    if(!st_ref_node)
    {
        return AXIS2_FAILURE;
    }
    /*
     WSS-Core specification suggests
     1. Resolve any <wsse:Reference> elements (specified within
     <wsse:SecurityTokenReference>).
     2. Resolve any <wsse:KeyIdentifier> elements (specified within
     <wsse:SecurityTokenReference>).
     3. Resolve any <ds:KeyName> elements. NOT PERMITTED by WS-i
     4. Resolve any other <ds:KeyInfo> elements. NOT PERMITTED by WS-i
     */

    /*
     * TODO: This method should get the key from the key_node. Currently key is taken from 
     * given private key file
     */

    return AXIS2_SUCCESS;
}
Ejemplo n.º 3
0
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
oxs_token_get_cipher_value_from_cipher_data(
    const axutil_env_t *env,
    axiom_node_t *cd_node)
{
    axiom_node_t *cv_node = NULL;
    axis2_char_t *value = NULL;
    
    /* First check direct <CipherValue> */
    cv_node = oxs_axiom_get_first_child_node_by_name(
        env, cd_node, OXS_NODE_CIPHER_VALUE, OXS_ENC_NS, OXS_XENC);
    
    if(cv_node)
    {
        value = oxs_token_get_cipher_value(env, cv_node);
    }
    else
    {
        /* If not then check for <CipherReference URI?> */
        /* TODO */
    }

    return value;
}
Ejemplo n.º 4
0
axis2_status_t __euca_authenticate(const axutil_env_t *env,axis2_msg_ctx_t *out_msg_ctx, axis2_op_ctx_t *op_ctx)
{
  //***** First get the message context before doing anything dumb w/ a NULL pointer *****/
  axis2_msg_ctx_t *msg_ctx = NULL; //<--- incoming msg context, it is NULL, see?
  msg_ctx = axis2_op_ctx_get_msg_ctx(op_ctx, env, AXIS2_WSDL_MESSAGE_LABEL_IN);  

  //***** Print everything from the security results, just for testing now *****//
  rampart_context_t *rampart_context = NULL;
  axutil_property_t *property = NULL;

  property = axis2_msg_ctx_get_property(msg_ctx, env, RAMPART_CONTEXT);
  if(property)
  {
     rampart_context = (rampart_context_t *)axutil_property_get_value(property, env);
     //     AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," ======== PRINTING PROCESSED WSSEC TOKENS ======== ");
     rampart_print_security_processed_results_set(env,msg_ctx);
  }

  //***** Extract Security Node from header from enveloper from msg_ctx *****//
  axiom_soap_envelope_t *soap_envelope = NULL;
  axiom_soap_header_t *soap_header = NULL;
  axiom_node_t *sec_node = NULL;


  soap_envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env);
  if(!soap_envelope) NO_U_FAIL("SOAP envelope cannot be found."); 
  soap_header = axiom_soap_envelope_get_header(soap_envelope, env);
  if (!soap_header) NO_U_FAIL("SOAP header cannot be found.");
  sec_node = rampart_get_security_header(env, msg_ctx, soap_header); // <---- here it is!
  if(!sec_node)NO_U_FAIL("No node wsse:Security -- required: ws-security");

  //***** Find the wsse:Reference to the BinarySecurityToken *****//
  //** Path is: Security/
  //** *sec_node must be non-NULL, kkthx **//
  axiom_node_t *sig_node = NULL;
  axiom_node_t *key_info_node = NULL;
  axiom_node_t *sec_token_ref_node = NULL;
  /** the ds:Signature node **/
  sig_node = oxs_axiom_get_first_child_node_by_name(env,sec_node, OXS_NODE_SIGNATURE, OXS_DSIG_NS, OXS_DS );
  if(!sig_node)NO_U_FAIL("No node ds:Signature -- required: signature");
  /** the ds:KeyInfo **/
  key_info_node = oxs_axiom_get_first_child_node_by_name(env, sig_node, OXS_NODE_KEY_INFO, OXS_DSIG_NS, NULL );
  if(!key_info_node)NO_U_FAIL("No node ds:KeyInfo -- required: signature key");
  /** the wsse:SecurityTokenReference **/ 
  sec_token_ref_node = oxs_axiom_get_first_child_node_by_name(env, key_info_node,OXS_NODE_SECURITY_TOKEN_REFRENCE, OXS_WSSE_XMLNS, NULL);
  if(!sec_token_ref_node)NO_U_FAIL("No node wsse:SecurityTokenReference -- required: signing token");
  //** in theory this is the branching point for supporting all kinds of tokens -- we only do BST Direct Reference **/

  //***** Find the wsse:Reference to the BinarySecurityToken *****//
  //** *sec_token_ref_node must be non-NULL **/
  axis2_char_t *ref = NULL;
  axis2_char_t *ref_id = NULL;
  axiom_node_t *token_ref_node = NULL;
  axiom_node_t *bst_node = NULL;
  /** the wsse:Reference node **/
  token_ref_node = oxs_axiom_get_first_child_node_by_name(env, sec_token_ref_node,OXS_NODE_REFERENCE, OXS_WSSE_XMLNS, NULL);
  /** pull out the name of the BST node **/
  ref = oxs_token_get_reference(env, token_ref_node);
  ref_id = axutil_string_substring_starting_at(axutil_strdup(env, ref), 1);
  /** get the wsse:BinarySecurityToken used to sign the message **/
  bst_node = oxs_axiom_get_node_by_id(env, sec_node, "Id", ref_id, OXS_WSU_XMLNS);
  if(!bst_node){oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Error retrieving elementwith ID=%s", ref_id);NO_U_FAIL("Cant find the required node");}


  //***** Find the wsse:Reference to the BinarySecurityToken *****//
  //** *bst_node must be non-NULL **/
  axis2_char_t *data = NULL;
  oxs_x509_cert_t *_cert = NULL;
  oxs_x509_cert_t *recv_cert = NULL;
  axis2_char_t *file_name = NULL;
  axis2_char_t *recv_x509_buf = NULL;
  axis2_char_t *msg_x509_buf = NULL;

  /** pull out the data from the BST **/
  data = oxs_axiom_get_node_content(env, bst_node);
  /** create an oxs_X509_cert **/
  _cert = oxs_key_mgr_load_x509_cert_from_string(env, data);
  if(_cert)
  {
    //***** FINALLY -- we have the certificate used to sign the message.  authenticate it HERE *****//
    msg_x509_buf = oxs_x509_cert_get_data(_cert,env);
    if(!msg_x509_buf)NO_U_FAIL("OMG WHAT NOW?!");
    /*
    recv_x509_buf = (axis2_char_t *)rampart_context_get_receiver_certificate(rampart_context, env);
    if(recv_x509_buf)
        recv_cert = oxs_key_mgr_load_x509_cert_from_string(env, recv_x509_buf);
    else
    {
        file_name = rampart_context_get_receiver_certificate_file(rampart_context, env);
        if(!file_name) NO_U_FAIL("Policy for the service is incorrect -- ReceiverCertificate is not set!!");
	if (check_file(file_name)) NO_U_FAIL("No cert file ($EUCALYPTUS/var/lib/eucalyptus/keys/cloud-cert.pem) found, failing");
        recv_cert = oxs_key_mgr_load_x509_cert_from_pem_file(env, file_name);
    }
    */

    file_name = rampart_context_get_receiver_certificate_file(rampart_context, env);
    if(!file_name) NO_U_FAIL("Policy for the service is incorrect -- ReceiverCertificate is not set!!");
    if (check_file(file_name)) NO_U_FAIL("No cert file ($EUCALYPTUS/var/lib/eucalyptus/keys/cloud-cert.pem) found, failing");
    recv_cert = oxs_key_mgr_load_x509_cert_from_pem_file(env, file_name);

    if (recv_cert) {
      recv_x509_buf = oxs_x509_cert_get_data(recv_cert,env);
    } else {
      NO_U_FAIL("could not populate receiver cert");
    }

    if( axutil_strcmp(recv_x509_buf,msg_x509_buf)!=0){
      AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," --------- Received x509 certificate value ---------" );
      AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI, msg_x509_buf );
      AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," --------- Local x509 certificate value! ---------" );
      AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI, recv_x509_buf );
      AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," ---------------------------------------------------" );
      NO_U_FAIL("The certificate specified is invalid!");
    }
  }
  else 
  {
    oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_DEFAULT, "Cannot load certificate from string =%s", data); 
    NO_U_FAIL("Failed to build certificate from BinarySecurityToken");
  }
  oxs_x509_cert_free(_cert, env);
  oxs_x509_cert_free(recv_cert, env);
  return AXIS2_SUCCESS;

}
Ejemplo n.º 5
0
/**
 * Verifes that Body, Timestamp, To, Action, and MessageId elements are signed and located
 * where expected by the application logic. Timestamp is checked for expiration regardless
 * of its actual location.
 */
axis2_status_t verify_references(axiom_node_t *sig_node, const axutil_env_t *env, axis2_msg_ctx_t *msg_ctx, axiom_soap_envelope_t *envelope) {
  axiom_node_t *si_node = NULL;
  axiom_node_t *ref_node = NULL;
  axis2_status_t status = AXIS2_SUCCESS;

  si_node = oxs_axiom_get_first_child_node_by_name(env,sig_node, OXS_NODE_SIGNEDINFO, OXS_DSIG_NS, OXS_DS);

  if(!si_node) {
    axis2_char_t *tmp = axiom_node_to_string(sig_node, env);
    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart]sig = %s", tmp);
    NO_U_FAIL("Couldn't find SignedInfo!");
  }

  axutil_qname_t *qname = NULL;
  axiom_element_t *parent_elem = NULL; 
  axiom_children_qname_iterator_t *qname_iter = NULL; 

  parent_elem = axiom_node_get_data_element(si_node, env);  
  if(!parent_elem)                                                                                                                          
    {                                                                                                                                        
       NO_U_FAIL("Could not get Reference elem");                                                                                                                           
    }     

  axis2_char_t *ref = NULL;
  axis2_char_t *ref_id = NULL;
  axiom_node_t *signed_node = NULL;
  axiom_node_t *envelope_node = NULL;

  short signed_elems[5] = {0,0,0,0,0};

  envelope_node = axiom_soap_envelope_get_base_node(envelope, env);

  qname = axutil_qname_create(env, OXS_NODE_REFERENCE, OXS_DSIG_NS, NULL);                                                                            
  qname_iter = axiom_element_get_children_with_qname(parent_elem, env, qname, si_node); 
  while (axiom_children_qname_iterator_has_next(qname_iter , env)) {
      ref_node = axiom_children_qname_iterator_next(qname_iter, env);     
      axis2_char_t *txt = axiom_node_to_string(ref_node, env); 

      /* get reference to a signed element */
      ref = oxs_token_get_reference(env, ref_node);
      if(ref == NULL || strlen(ref) == 0 || ref[0] != '#') {
	oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Unsupported reference ID in %s", txt);
	status = AXIS2_FAILURE;
	break;
      }

      AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] %s, ref = %s", txt, ref); 
  
      /* get rid of '#' */
      ref_id = axutil_string_substring_starting_at(axutil_strdup(env, ref), 1);
      signed_node = oxs_axiom_get_node_by_id(env, envelope_node, OXS_ATTR_ID, ref_id, OXS_WSU_XMLNS);
      if(!signed_node) {
	  oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Error retrieving elementwith ID=%s", ref_id);
	  status = AXIS2_FAILURE;
	  break;
      }
      if(verify_node(signed_node, env, msg_ctx, ref, signed_elems)) {
	status = AXIS2_FAILURE;
	break;
      }
    }         

  
  axutil_qname_free(qname, env);                                                                                                           
  qname = NULL;                   
  
  if(status == AXIS2_FAILURE) {
    NO_U_FAIL("Failed to verify location of signed elements!");
  }

  /* This is needed to make sure that all security-critical elements are signed */
  for(int i = 0; i < 5; i++) {
    if(signed_elems[i] == 0) {
      NO_U_FAIL("Not all required elements are signed");
    }
  }

  return status;

}
Ejemplo n.º 6
0
/**
* Inspect the key node. Then populate the sym_key
*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_xml_enc_decrypt_key(
    const axutil_env_t *env,
    oxs_asym_ctx_t * asym_ctx,
    axiom_node_t *parent,
    axiom_node_t *encrypted_key_node,
    oxs_key_t *key)
{
    axiom_node_t *enc_mtd_node = NULL;
    axiom_node_t *key_info_node = NULL;
    axiom_node_t *cd_node = NULL;
    axis2_char_t *enc_mtd_algo = NULL;
    axis2_char_t *cipher_val = NULL;
    axis2_char_t *new_cipher_val = NULL;
    axis2_status_t status = AXIS2_FAILURE;
    oxs_buffer_t *input_buf = NULL;
    oxs_buffer_t *result_buf = NULL;
    axis2_char_t *key_name = NULL;

    axis2_char_t* encrypted_key_hash = NULL;
    int decoded_len = 0;
    axis2_char_t *decoded_enc_sec = NULL;

    /*Get encryption method algorithm*/
    enc_mtd_node = oxs_axiom_get_first_child_node_by_name(env, encrypted_key_node,
        OXS_NODE_ENCRYPTION_METHOD, OXS_ENC_NS, OXS_XENC);
    enc_mtd_algo = oxs_token_get_encryption_method(env, enc_mtd_node);
    if(!enc_mtd_algo)
    {
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ENCRYPT_FAILED,
            "Cannot find the Encryption method");
        return AXIS2_FAILURE;
    }
    /*Get cipher data*/
    cd_node = oxs_axiom_get_first_child_node_by_name(env, encrypted_key_node, OXS_NODE_CIPHER_DATA,
        OXS_ENC_NS, OXS_XENC);
    cipher_val = oxs_token_get_cipher_value_from_cipher_data(env, cd_node);
    if(!cipher_val)
    {
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ENCRYPT_FAILED,
            "Cannot find the cipher value for key decryption");
        return AXIS2_FAILURE;
    }

    new_cipher_val = oxs_util_get_newline_removed_string(env, cipher_val);

    /*Get key used to encrypt*/
    key_info_node = oxs_axiom_get_first_child_node_by_name(env, encrypted_key_node,
        OXS_NODE_KEY_INFO, OXS_DSIG_NS, OXS_DS);
    status = oxs_xml_enc_process_key_info(env, asym_ctx, key_info_node, parent);
    /*Right now we support KeyInfo -> SecurityTokenReference -> Reference
     KeyInfo -> SecurityTokenReference -> X509IssuerSerial */

    /*Get the pkey used to decrypt the session key. If found set it to the asym_ctx*/
    /*Create the input buffer*/
    input_buf = oxs_buffer_create(env);
    oxs_buffer_populate(input_buf, env, (unsigned char*)new_cipher_val, axutil_strlen(
        new_cipher_val));

    /*Create a results buffer*/
    result_buf = oxs_buffer_create(env);

    /*Call decryption*/
    status = oxs_encryption_asymmetric_crypt(env, asym_ctx, input_buf, result_buf);
    /*Free input*/
    oxs_buffer_free(input_buf, env);
    input_buf = NULL;

    /*calculate the EncryptedKeySHA1 and set as the key_sha*/
    decoded_len = axutil_base64_decode_len(new_cipher_val);
    decoded_enc_sec = AXIS2_MALLOC(env->allocator, decoded_len);
    axutil_base64_decode_binary((unsigned char*)decoded_enc_sec, new_cipher_val);
    encrypted_key_hash = openssl_sha1(env, decoded_enc_sec, decoded_len);
    AXIS2_FREE(env->allocator, decoded_enc_sec);

    AXIS2_FREE(env->allocator, new_cipher_val);
    new_cipher_val = NULL;

    if(AXIS2_FAILURE == status)
    {
        return AXIS2_FAILURE;
    }

    key_name = oxs_axiom_get_attribute_value_of_node_by_name(env, encrypted_key_node, OXS_ATTR_ID,
        NULL);
    /*Populate the key with the data in the result buffer*/
    oxs_key_populate(key, env, oxs_buffer_get_data(result_buf, env), key_name, oxs_buffer_get_size(
        result_buf, env), OXS_KEY_USAGE_SESSION);
    oxs_key_set_key_sha(key, env, encrypted_key_hash);

    /*Free*/
    oxs_buffer_free(result_buf, env);
    result_buf = NULL;

    return AXIS2_SUCCESS;
}
Ejemplo n.º 7
0
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_xml_enc_decrypt_data(
    const axutil_env_t *env,
    oxs_ctx_t * enc_ctx,
    axiom_node_t *enc_type_node,
    oxs_buffer_t *result_buf)
{
    axiom_node_t *enc_mtd_node = NULL;
    axiom_node_t *cd_node = NULL;
    axiom_node_t *cv_node = NULL;
    axis2_char_t *cipher_val = NULL;
    axis2_char_t *new_cipher_val = NULL;
    axis2_char_t *sym_algo = NULL;
    axis2_char_t *type = NULL;
    axis2_char_t *id = NULL;
    oxs_buffer_t *input_buf = NULL;
    axis2_status_t status = AXIS2_FAILURE;

    /* Get the symmetric encryption algorithm */
    enc_mtd_node = oxs_axiom_get_first_child_node_by_name(env, enc_type_node,
        OXS_NODE_ENCRYPTION_METHOD, OXS_ENC_NS, OXS_XENC);
    if(!enc_mtd_node)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find encryption method node");
        return AXIS2_FAILURE;
    }

    sym_algo = oxs_token_get_encryption_method(env, enc_mtd_node);
    if(!sym_algo)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find encryption method");
        return AXIS2_FAILURE;
    }

    /* Get ID, Type, MimeType attributes from the EncryptedDataNode */
    id = oxs_axiom_get_attribute_value_of_node_by_name(env, enc_type_node, OXS_ATTR_ID, NULL);
    type = oxs_axiom_get_attribute_value_of_node_by_name(env, enc_type_node, OXS_ATTR_TYPE, NULL);

    /* Populate the context for future use */
    oxs_ctx_set_enc_mtd_algorithm(enc_ctx, env, sym_algo);
    oxs_ctx_set_id(enc_ctx, env, id);
    oxs_ctx_set_type(enc_ctx, env, type);

    /* Get the cipher value */
    cd_node = oxs_axiom_get_first_child_node_by_name(env, enc_type_node, OXS_NODE_CIPHER_DATA,
        OXS_ENC_NS, OXS_XENC);
    if(!cd_node)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find cipher data node");
        return AXIS2_FAILURE;
    }

    cv_node = oxs_axiom_get_first_child_node_by_name(env, cd_node, OXS_NODE_CIPHER_VALUE,
        OXS_ENC_NS, OXS_XENC);
    if(!cv_node)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find cipher value node");
        return AXIS2_FAILURE;
    }

    cipher_val = oxs_token_get_cipher_value(env, cv_node);
    if(!cipher_val)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find cipher value");
        return AXIS2_FAILURE;
    }

    /* We need to remove new lines if any */
    new_cipher_val = oxs_util_get_newline_removed_string(env, cipher_val);

    /* Create input buffer with cipher data obtained */
    input_buf = oxs_buffer_create(env);
    oxs_buffer_populate(input_buf, env, (unsigned char*)new_cipher_val,
        axutil_strlen(new_cipher_val));

    /* Decrypt */
    oxs_ctx_set_operation(enc_ctx, env, OXS_CTX_OPERATION_DECRYPT);
    status = oxs_encryption_symmetric_crypt(env, enc_ctx, input_buf, result_buf);

    /*Free*/
    oxs_buffer_free(input_buf, env);
    input_buf = NULL;
    AXIS2_FREE(env->allocator, new_cipher_val);
    new_cipher_val = NULL;

    return status;
}
/*Public functions*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
rampart_shb_ensure_sec_header_order(const axutil_env_t *env,
                                    axis2_msg_ctx_t *msg_ctx,
                                    rampart_context_t *rampart_context,
                                    axiom_node_t* sec_node)
{
    axis2_bool_t signature_protection = AXIS2_FALSE;
    axis2_bool_t is_encrypt_before_sign = AXIS2_FALSE;
    axiom_node_t *sig_node = NULL;
    axiom_node_t *enc_key_node = NULL;
    axiom_node_t *ref_list_node = NULL;
    axiom_node_t *h_node = NULL;
    axutil_array_list_t *dk_list = NULL;
    axutil_array_list_t *enc_key_list = NULL;
    axiom_node_t* first_protection_item = NULL;
    int i = 0;

    signature_protection = rampart_context_is_encrypt_signature(rampart_context, env);
    is_encrypt_before_sign = rampart_context_is_encrypt_before_sign(rampart_context, env);

    dk_list = axutil_array_list_create(env, 5);
    enc_key_list = axutil_array_list_create(env, 2);

    h_node = axiom_node_get_first_child(sec_node, env);
    while(h_node)
    {
        if(0 == axutil_strcmp(OXS_NODE_DERIVED_KEY_TOKEN, axiom_util_get_localname(h_node, env)) ||
                (0 == axutil_strcmp(OXS_NODE_BINARY_SECURITY_TOKEN, axiom_util_get_localname(h_node, env))))
        {
            axutil_array_list_add(dk_list, env, h_node);
        }
        else if((0 == axutil_strcmp(OXS_NODE_ENCRYPTED_KEY, axiom_util_get_localname(h_node, env))) ||
                (0 == axutil_strcmp(OXS_NODE_SECURITY_CONTEXT_TOKEN, axiom_util_get_localname(h_node, env))))
        {
            axutil_array_list_add(enc_key_list, env, h_node);
        }
        h_node = axiom_node_get_next_sibling(h_node, env);
    }

    ref_list_node = oxs_axiom_get_first_child_node_by_name(env, sec_node, OXS_NODE_REFERENCE_LIST, OXS_ENC_NS, NULL);
    sig_node = oxs_axiom_get_first_child_node_by_name(env, sec_node, OXS_NODE_SIGNATURE, OXS_DSIG_NS, NULL);

    /*Ensure the protection order in the header*/
    if(sig_node && ref_list_node)
    {
        if(is_encrypt_before_sign)
        {
            int no_of_sig_node = 0;
            /*Encrypt->Sig         <Sig><RefList>*/
            oxs_axiom_interchange_nodes(env,  sig_node, ref_list_node );
            first_protection_item = sig_node;
            no_of_sig_node = oxs_axiom_get_number_of_children_with_qname(env, sec_node, OXS_NODE_SIGNATURE, OXS_DSIG_NS, NULL);
            if(no_of_sig_node > 1)
            {
                axiom_node_t* cur_node = NULL;
                cur_node = axiom_node_get_first_child(sec_node, env);
                while(cur_node)
                {
                    axis2_char_t *cur_local_name = NULL;
                    cur_local_name = axiom_util_get_localname(cur_node, env);

                    if(0 == axutil_strcmp(cur_local_name, OXS_NODE_SIGNATURE))
                    {
                        oxs_axiom_interchange_nodes(env,  cur_node, ref_list_node);
                    }
                    cur_node = axiom_node_get_next_sibling(cur_node, env);
                }
            }
        }
        else
        {
            /*Sig->Encrypt         <RefList> <Sig>*/
            oxs_axiom_interchange_nodes(env, ref_list_node, sig_node );
            first_protection_item = ref_list_node;
        }
    }
    else if(sig_node)
    {
        first_protection_item = sig_node;
    }
    else
    {
        first_protection_item = ref_list_node;
    }

    /*makesure enc_key_node is appearing before first protection item*/
    if(first_protection_item)
    {
        for(i = 0; i < axutil_array_list_size(enc_key_list, env); i++)
        {
            axiom_node_t *tmp_node = NULL;
            tmp_node = (axiom_node_t*)axutil_array_list_get(enc_key_list, env, i);
            enc_key_node = axiom_node_detach_without_namespaces(tmp_node, env);
            axiom_node_insert_sibling_before(first_protection_item, env, enc_key_node);
        }
    }

    /*
     * If there are derived keys, make sure they come after the EncryptedKey/security context token
        1. First we get all the derived keys
        2. Then we attach after the EncryptedKey(hidden sessionkey)/security context token 
        3. If key is not available, then attach derived keys before sig_node and ref_list_node (whichever is first)
     */

    if(enc_key_node)
    {
        for(i = 0; i < axutil_array_list_size(dk_list, env); i++)
        {
            axiom_node_t *dk_node = NULL;
            axiom_node_t *tmp_node = NULL;

            dk_node = (axiom_node_t*)axutil_array_list_get(dk_list, env, i);
            tmp_node = axiom_node_detach(dk_node, env);
            axiom_node_insert_sibling_after(enc_key_node, env, tmp_node);
        }
    }
    else
    {
        if(first_protection_item)
        {
            for(i = 0; i < axutil_array_list_size(dk_list, env); i++)
            {
                axiom_node_t *dk_node = NULL;
                axiom_node_t *tmp_node = NULL;
                dk_node = (axiom_node_t*)axutil_array_list_get(dk_list, env, i);
                tmp_node = axiom_node_detach(dk_node, env);
                axiom_node_insert_sibling_before(first_protection_item, env, tmp_node);
            }
        }
    }
    
    axutil_array_list_free(dk_list, env);
    axutil_array_list_free(enc_key_list, env);
    return AXIS2_SUCCESS;
}
/**
 * Extract certificate/session_key related information using given key_info node and scope node
 * This will extract either certificate(asymmetric signing) or session_key (symmetric signing)
 * @param env Environment structure
 * @param key_info_node key info node.
 * @param rampart_context rampart context where key details could be found.
 * @param msg_ctx message context
 * @param is_signature boolean denoting whether the key_info is for signature
 * @param cert where the certificate extracted (if any) should be populated
 * @param key where the session key extracted (if any) should be populated
 * @return status of the operation
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
rampart_token_process_key_info(
    const axutil_env_t *env,
    axiom_node_t *key_info_node,
    axiom_node_t *sec_node,
    rampart_context_t* rampart_context,
    axis2_msg_ctx_t *msg_ctx,
    axis2_bool_t is_signature,
    oxs_x509_cert_t **cert,
    oxs_key_t **key,
    axis2_char_t **token_type,
    axis2_char_t **reference_method)
{
    axiom_node_t *str_node = NULL;
    axis2_status_t status = AXIS2_FAILURE;

    /* Get the SecurityTokenReference, which is the common case, but not the only case */
    str_node = oxs_axiom_get_first_child_node_by_name(env, key_info_node,
        OXS_NODE_SECURITY_TOKEN_REFRENCE, OXS_WSSE_XMLNS, NULL);

    if(str_node)
    {
        axiom_node_t *str_child_node = NULL;

        /* A <wsse:SecurityTokenReference> element MAY reference an X.509 token type
         * by one of the following means:
         *  - Reference to a Subject Key Identifier (<wsse:KeyIdentifier>)
         *  - Reference to a Binary Security Token (<wsse:Reference> element that
         *    references a local <wsse:BinarySecurityToken> element or a remote data
         *    source that contains the token data itself)
         *  - Reference to an Issuer and Serial Number (<ds:X509Data> element that
         *    contains a <ds:X509IssuerSerial> element that uniquely identifies an
         *    end entity certificate)
         */
        str_child_node = axiom_node_get_first_element(str_node, env);
        if(!str_child_node)
        {
             AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "No Child node in the Security Token Reference Element.");
            return AXIS2_FAILURE;
        }

        *reference_method = axiom_util_get_localname(str_child_node, env);
        if(!*reference_method)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Cannot get the key Reference Type from the message.");
            return AXIS2_FAILURE;
        }

        if(0 == axutil_strcmp(*reference_method, OXS_NODE_REFERENCE))
        {
            status = rampart_token_process_direct_ref(env, str_child_node, sec_node, msg_ctx,
                rampart_context, cert, key, token_type);
        }
        else if(0 == axutil_strcmp(*reference_method, OXS_NODE_EMBEDDED))
        {
            /* embedded tokens are only possible with x509 token */
            status = rampart_token_process_embedded(env, str_child_node, cert);
        }
        else if(0 == axutil_strcmp(*reference_method, OXS_NODE_KEY_IDENTIFIER))
        {
            status = rampart_token_process_key_identifier(env, str_child_node, sec_node, str_node,
                rampart_context, is_signature, cert, key, token_type);
        }
        else if(0 == axutil_strcmp(*reference_method, OXS_NODE_X509_DATA))
        {
            /* <ds:X509Data> contains a <ds:X509IssuerSerial> element which is used to specify a
             * reference to an X.509 security token by means of the certificate issuer name and
             * serial number. */
            *cert = rampart_token_process_issuer_serial(env, rampart_context, str_child_node);
            status = AXIS2_SUCCESS;
        }
        else
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Key Reference %s not supported ",
                *reference_method);
            return AXIS2_FAILURE;
        }
    }
    else
    {
        /* There may be scenarios where there is no Security Token Reference Element. */

        /*In such case policy support only Isssuer Serial scenario.*/

        /*if(axutil_strcmp(eki, RAMPART_STR_ISSUER_SERIAL) == 0)
        {
            key_info_child_node = axiom_node_get_first_element(key_info_node, env);
            if(key_info_child_node)
            {
                axis2_char_t *key_info_child_name = NULL;
                key_info_child_name = axiom_util_get_localname(key_info_child_node, env);
                if(key_info_child_name)
                {
                    if(0 == axutil_strcmp(key_info_child_name, OXS_NODE_X509_DATA))
                    {
                        status = rampart_token_process_x509_data(env, key_info_child_node, cert);
                        if(status != AXIS2_SUCCESS || !cert)
                        {
                            rampart_create_fault_envelope(env,
                                RAMPART_FAULT_INVALID_SECURITY_TOKEN,
                                "Cannot load the key to verify the message .",
                                RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
                            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[Rampart][shp] Cannot load the key to verify the message");
                            return AXIS2_FAILURE;
                        }
                    }
                    else
                    {
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[Rampart][shp]Cannot get the key Reference Type from the message.");
                        return AXIS2_FAILURE;
                    }
                }
                else
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[Rampart][shp]Cannot get the key Reference Type from the message.");
                    return AXIS2_FAILURE;
                }
            }
            else
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "[Rampart][shp]Cannot get the key Reference Type from the message.");
                return AXIS2_FAILURE;
            }
        }

        else
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "[Rampart][shp]Can't be used as a direct child of Key Info");
            return AXIS2_FAILURE;
        }*/

        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to key from key_info node");
        return AXIS2_FAILURE;
    }

    if((status != AXIS2_SUCCESS) || ((!*cert) && (!*key)))
    {
        /* either status is AXIS2_FAILURE or both cert and key are NULL. This means error */
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get key/certificate from key info node");
        return AXIS2_FAILURE;
    }

    return AXIS2_SUCCESS;
}
Ejemplo n.º 10
0
AXIS2_EXTERN oxs_key_t * AXIS2_CALL
saml_assertion_get_session_key(const axutil_env_t *env, axiom_node_t *assertion, 
                               openssl_pkey_t *pvt_key)
{
    axiom_node_t *encrypted_key_node = NULL;
    axiom_node_t *enc_mtd_node = NULL;
    axis2_char_t *enc_asym_algo = NULL;
    oxs_asym_ctx_t *asym_ctx = NULL;
    oxs_key_t *decrypted_sym_key = NULL;
    axis2_status_t status = AXIS2_FAILURE;    

	if (!pvt_key)
	{
		AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[oxs][saml] Private key not specified");
		return NULL;
	}

    encrypted_key_node = oxs_axiom_get_node_by_local_name(env, assertion, OXS_NODE_ENCRYPTED_KEY);
	if (!encrypted_key_node)
	{
		AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[oxs][saml] Encrypted key cannot be found");
		return NULL;
	}

    enc_mtd_node = oxs_axiom_get_first_child_node_by_name(
                       env, encrypted_key_node, OXS_NODE_ENCRYPTION_METHOD, OXS_ENC_NS, NULL);

	if (!enc_mtd_node)
	{
		AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[oxs][saml] EncryptedKey node cannot be found");
		return NULL;
	}
    enc_asym_algo = oxs_token_get_encryption_method(env, enc_mtd_node); 
	if (!enc_asym_algo)
	{
		AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[oxs][saml] Encryption Algorithm cannot be found");
		return NULL;
	}
    asym_ctx = oxs_asym_ctx_create(env);
    oxs_asym_ctx_set_algorithm(asym_ctx, env, enc_asym_algo);
		    	
	oxs_asym_ctx_set_private_key(asym_ctx, env, pvt_key);
    oxs_asym_ctx_set_operation(asym_ctx, env, OXS_ASYM_CTX_OPERATION_PRV_DECRYPT);

    decrypted_sym_key = oxs_key_create(env);

    /*Call decrypt for the EncryptedKey*/
    status = oxs_xml_enc_decrypt_key(env, asym_ctx,
                                     NULL, encrypted_key_node,  decrypted_sym_key);
    if (status == AXIS2_FAILURE)
    {
		oxs_key_free(decrypted_sym_key, env);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[oxs][saml] Decryption failed in SAML encrypted key");
		return NULL;
    }
    return decrypted_sym_key;
}