19 #include "dds/DCPS/RTPS/RtpsCoreC.h" 20 #include "dds/DCPS/RTPS/RtpsCoreTypeSupportImpl.h" 22 #include "ace/config-macros.h" 42 const std::vector<unsigned char>& subject_name_hash,
86 ACE_TEXT(
"AuthenticationBuiltInImpl::~AuthenticationBuiltInImpl local_participants_ %B handshake_data_ %B\n"),
96 const ::DDS::DomainParticipantQos & participant_qos,
97 const ::OpenDDS::DCPS::GUID_t & candidate_participant_guid,
103 if (!credentials->load_credentials(participant_qos.property.value, ex)) {
107 if (credentials->validate()) {
111 adjusted_participant_guid,
112 credentials->get_participant_cert());
117 local_participant->participant_guid = adjusted_participant_guid;
118 local_participant->credentials = credentials;
119 for (
unsigned i = 0; i < participant_qos.property.value.length(); ++i) {
121 participant_qos.property.value[i].name.in()) == 0) {
122 local_participant->handshake_debug =
true;
132 ACE_TEXT(
"AuthenticationBuiltInImpl::validate_local_identity local_participants_ (total %B)\n"),
144 set_security_error(ex, -1, 0,
"GUID_UNKNOWN passed in for candidate_participant_guid");
221 ACE_UNUSED_ARG(permissions_token);
231 return local_data->credentials->load_access_permissions(permissions_credential, ex);
240 const ::OpenDDS::DCPS::GUID_t & remote_participant_guid,
259 RemoteParticipantMap::iterator begin = local_data->validated_remotes.begin(),
260 end = local_data->validated_remotes.end(),
261 found = std::find_if(begin, end,
269 set_security_error(ex, -1, 0,
"Failed to generate 256-bit nonce value for future_challenge property");
278 remote_participant->participant_guid = remote_participant_guid;
279 remote_participant->local_participant = local_identity_handle;
280 remote_participant->local_auth_request = local_auth_request_token;
283 found = local_data->validated_remotes.insert(std::make_pair(remote_identity_handle, remote_participant)).first;
287 ACE_TEXT(
"AuthenticationBuiltInImpl::validate_remote_identity validated_remotes (total %B)\n"),
288 local_data->validated_remotes.size()));
293 found->second->remote_auth_request = remote_auth_request_token;
296 remote_identity_handle = found->first;
299 TokenReader remote_request(remote_auth_request_token);
300 if (remote_request.
is_nil()) {
301 local_auth_request_token = found->second->local_auth_request;
318 const ::DDS::OctetSeq & serialized_local_participant_data,
321 if (serialized_local_participant_data.length() == 0) {
330 if (! handshake_data.first) {
335 if (! handshake_data.second) {
356 serialized_local_participant_data,
359 int err =
hash(hash_c1);
370 message_out.
add_bin_property(
"c.kagree_algo", diffie_hellman->kagree_algo());
376 diffie_hellman->pub_key(dhpub);
380 if (auth_wrapper.
is_nil()) {
387 set_security_error(ex, -1, 0,
"Failed to generate 256-bit nonce value for challenge1 property");
399 remote_data.
request = handshake_message;
414 ACE_TEXT(
"AuthenticationBuiltInImpl::begin_handshake_request handshake_data_ (total %B)\n"),
426 ACE_Message_Block buffer(reinterpret_cast<const char*>(cpdata.get_buffer()), cpdata.length());
427 buffer.
wr_ptr(cpdata.length());
433 if (serializer >> params) {
434 for (
unsigned int i = 0; i < params.length(); ++i) {
445 ACE_TEXT(
"(%P|%t) WARNING: extract_participant_guid_from_cpdata, ")
446 ACE_TEXT(
"failed to deserialize guid from cpdata.\n")));
452 const std::vector<unsigned char>& subject_name_hash,
455 if (cpdata.length() > 5u) {
464 if ((prefix[0] & 0x80) != 0x80) {
465 set_security_error(ex, -1, 0,
"Malformed participant_guid in 'c.pdata'; First bit must be set.");
473 set_security_error(ex, -1, 0,
"First byte of participant_guid in 'c.pdata' does not match bits of subject-name hash in 'c.id'");
476 for (
size_t i = 1; i <= 5u; ++i) {
478 set_security_error(ex, -1, 0,
"Bits 2 - 48 of 'c.pdata' participant_guid does not match first 47 bits of subject-name hash in 'c.id'");
511 p.
name =
"challenge2";
512 p.
value = challenge2;
527 p.
name =
"challenge1";
528 p.
value = challenge1;
570 p.
name =
"challenge1";
571 p.
value = challenge1;
586 p.
name =
"challenge2";
587 p.
value = challenge2;
614 const ::DDS::OctetSeq & serialized_local_participant_data,
626 DDS::OctetSeq challenge1, challenge2, dh2, cperm, hash_c1, hash_c2;
634 if (serialized_local_participant_data.length() == 0) {
641 if (! handshake_data.first) {
646 if (! handshake_data.second) {
656 if (message_in.
is_nil()) {
657 set_security_error(ex, -1, 0,
"Handshake_message_out is an inout param and must not be nil");
664 if (! initiator_remote_auth_request.
is_nil()) {
675 if (cid.length() > 0) {
677 remote_cert->deserialize(cid);
678 if (X509_V_OK != remote_cert->validate(local_credential_data.
get_ca_cert()))
685 set_security_error(ex, -1, 0,
"Certificate validation failed due to empty 'c.id' property supplied");
693 std::vector<unsigned char>
hash;
694 if (0 != remote_cert->subject_name_digest(hash)) {
695 set_security_error(ex, -1, 0,
"Failed to generate subject-name digest from remote certificate.");
715 int err =
hash(hash_c1);
727 serialized_local_participant_data,
729 int err =
hash(hash_c2);
750 message_out.
add_bin_property(
"c.kagree_algo", diffie_hellman->kagree_algo());
756 diffie_hellman->pub_key(dh2);
767 if (! initiator_local_auth_request.
is_nil()) {
770 challenge2 = future_challenge;
801 remote_data.
c_perm = cperm;
802 remote_data.
reply = handshake_message_out;
803 remote_data.
request = request_token;
817 ACE_TEXT(
"AuthenticationBuiltInImpl::begin_handshake_reply handshake_data_ (total %B)\n"),
831 const std::string incoming_class_ext =
get_extension(handshake_message_in.class_id);
854 if (handshake_data.first && handshake_data.second) {
858 SharedSecretHandle_var handle = handshake_data.second->shared_secret;
859 result = handle._retn();
862 set_security_error(ex, -1, 0,
"Validation state must be either VALIDATION_OK or VALIDATION_OK_FINAL_MESSAGE");
883 if (handshake_data.first && handshake_data.second) {
893 p1.
value = handshake_data.second->certificate->original_bytes();
898 p2.
value = handshake_data.second->c_perm;
907 set_security_error(ex, -1, 0,
"Validation state must be either VALIDATION_OK or VALIDATION_OK_FINAL_MESSAGE");
918 ::DDS::Security::AuthenticationListener_ptr listener,
937 ACE_UNUSED_ARG(token);
948 ACE_UNUSED_ARG(token);
959 ACE_UNUSED_ARG(peer_credential_token);
970 HandshakeDataMap::iterator found =
handshake_data_.find(handshake_handle);
976 ACE_TEXT(
"AuthenticationBuiltInImpl::return_handshake_handle handshake_data_ (total %B)\n"),
1001 if (it->second.first == local->second) {
1013 ACE_TEXT(
"AuthenticationBuiltInImpl::return_identity_handle local_participants_ (total %B)\n"),
1025 const RemoteParticipantMap::iterator remote = local->second->validated_remotes.find(identity_handle);
1031 if (it->second.second == remote->second) {
1039 local->second->validated_remotes.erase(remote);
1043 ACE_TEXT(
"AuthenticationBuiltInImpl::return_identity_handle validated_remotes (total %B)\n"),
1044 local->second->validated_remotes.size()));
1059 ACE_UNUSED_ARG(sharedsecret_handle);
1081 if (!handshake_data.first || !handshake_data.second) {
1095 if (message_in.
is_nil()) {
1103 if (! auth_wrapper.
is_nil()) {
1115 if (cid.length() > 0) {
1117 remote_cert->deserialize(cid);
1119 if (X509_V_OK != remote_cert->validate(local_credential_data.
get_ca_cert()))
1126 set_security_error(ex, -1, 0,
"Certificate validation failed due to empty 'c.id' property supplied");
1133 if (handshake_request_token.
is_nil()) {
1142 set_security_error(ex, -1, 0,
"handshake-request challenge1 value does not match local challenge1");
1151 std::vector<unsigned char>
hash;
1152 if (0 != remote_cert->subject_name_digest(hash)) {
1153 set_security_error(ex, -1, 0,
"Failed to generate subject-name digest from remote certificate.");
1178 int err =
hash(hash_c2);
1201 set_security_error(ex, -1, 0,
"Remote 'signature' field failed signature verification");
1231 remote_data.
state = FinalMessage;
1233 remote_data.
hash_c2 = hash_c2;
1237 return FinalMessage;
1242 if ((c1.length()) < 1 || (c2.length() < 1)) {
1245 if (c1.length() != c2.length()) {
1249 if (0 != std::memcmp(c1.get_buffer(), c2.get_buffer(), c2.length())) {
1268 if (!handshake_data.first || !handshake_data.second) {
1282 TokenReader handshake_final_token(handshake_message_in);
1283 if (handshake_final_token.
is_nil()) {
1289 if (handshake_reply_token.
is_nil()) {
1296 if (handshake_reply_token.
is_nil()) {
1331 set_security_error(ex, -1, 0,
"Remote 'signature' field failed signature verification");
1347 return ValidationOkay;
1355 return found->second;
1365 ACE_TEXT(
"LocalParticipantData::~LocalParticipantData validated_remotes %B\n"),
1366 validated_remotes.size()));
1375 return found->second;
1401 RemoteParticipantMap::iterator found_remote = found_local->second->validated_remotes.find(other);
1402 if (found_remote != found_local->second->validated_remotes.end()) {
1403 return std::make_pair(found_local->second, found_remote->second);
1412 const unsigned char* local_ =
reinterpret_cast<const unsigned char*
>(&local);
1413 const unsigned char* remote_ =
reinterpret_cast<const unsigned char*
>(&remote);
1421 return std::lexicographical_compare(local_, local_ +
sizeof(local),
1422 remote_, remote_ +
sizeof(remote));
1428 if (!remote_class_id) {
1431 bool class_matches =
false;
1434 std::string class_id_str(remote_class_id);
1437 size_t colon_pos = class_id_str.find_last_of(
':');
1438 if (std::string::npos != colon_pos && colon_pos > 0) {
1440 std::string remote_class_name = class_id_str.substr(0, colon_pos);
1443 size_t major_start = colon_pos + 1;
1444 size_t period_pos = class_id_str.find_first_of(
'.', major_start);
1445 if (std::string::npos != period_pos && period_pos > major_start) {
1446 std::string
major_version = class_id_str.substr(major_start, period_pos - major_start);
1448 class_matches =
true;
1454 return class_matches;
1462 +
"+" + message_ext;
1464 return class_id_stream;
1469 std::string ext_string(
"");
1471 std::string class_id_str(class_id);
1472 size_t extension_delim_pos = class_id_str.find_last_of(
'+');
1473 if (extension_delim_pos != std::string::npos) {
1474 size_t start_ext_pos = extension_delim_pos + 1;
1475 if (start_ext_pos < class_id_str.length()) {
1476 ext_string = class_id_str.substr(start_ext_pos);
ACE_Thread_Mutex identity_mutex_
static DiffieHellman * factory(const DDS::OctetSeq &kagree_algo)
const DDS::OctetSeq & original_bytes() const
DDS::Security::ValidationResult_t process_final_handshake(const DDS::Security::HandshakeMessageToken &handshake_message_in, DDS::Security::HandshakeHandle handshake_handle, DDS::Security::SecurityException &ex)
SSL::Certificate::unique_ptr certificate
DDS::Security::IdentityHandle replier_identity
virtual ::DDS::Security::SharedSecretHandle * get_shared_secret(::DDS::Security::HandshakeHandle handshake_handle, ::DDS::Security::SecurityException &ex)
BinaryPropertySeq binary_properties
virtual ::DDS::Security::ValidationResult_t begin_handshake_request(::DDS::Security::HandshakeHandle &handshake_handle, ::DDS::Security::HandshakeMessageToken &handshake_message, ::DDS::Security::IdentityHandle initiator_identity_handle, ::DDS::Security::IdentityHandle replier_identity_handle, const ::DDS::OctetSeq &serialized_local_participant_data, ::DDS::Security::SecurityException &ex)
const char Auth_Peer_Cred_Token_Class_Id[]
Implements some simple wrapper functions to provide a const API around the Token data structure as sp...
const InstanceHandle_t HANDLE_NIL
static void make_reply_signature_sequence(const DDS::OctetSeq &hash_c2, const DDS::OctetSeq &challenge2, const DDS::OctetSeq &dh2, const DDS::OctetSeq &challenge1, const DDS::OctetSeq &dh1, const DDS::OctetSeq &hash_c1, DDS::BinaryPropertySeq &dst)
int make_nonce_256(std::vector< unsigned char > &nonce)
int hash(const std::vector< const DDS::OctetSeq *> &src, DDS::OctetSeq &dst)
bool is_handshake_initiator(const DCPS::GUID_t &local, const DCPS::GUID_t &remote)
int sign_serialized(const DDS::BinaryPropertySeq &src, const PrivateKey &key, DDS::OctetSeq &dst)
static void make_final_signature_sequence(const DDS::OctetSeq &hash_c1, const DDS::OctetSeq &challenge1, const DDS::OctetSeq &dh1, const DDS::OctetSeq &challenge2, const DDS::OctetSeq &dh2, const DDS::OctetSeq &hash_c2, DDS::BinaryPropertySeq &dst)
void add_bin_property(const char *prop_name, const DDS::OctetSeq &prop_value, bool propagate=true)
SharedSecret(DDS::OctetSeq challenge1, DDS::OctetSeq challenge2, DDS::OctetSeq sharedSecret)
const GUID_t GUID_UNKNOWN
Nil value for GUID.
const ParameterId_t PID_PARTICIPANT_GUID
DDS::OctetSeq * challenge2()
DDS::OctetSeq * sharedSecret()
YARD is all original work While it may rely on standard YARD does not include code from other sources We have chosen to release our work as public domain code This means that YARD has been released outside the copyright system Feel free to use the code in any way you wish especially in an academic plagiarism has very little to do with copyright In an academic or in any situation where you are expected to give credit to other people s you will need to cite YARD as a source The author is Christopher and the appropriate date is December the release date for we can t make any promises regarding whether YARD will do what you or whether we will make any changes you ask for You are free to hire your own expert for that If you choose to distribute YARD you ll probably want to read up on the laws covering warranties in your state
virtual ::DDS::Security::ValidationResult_t validate_remote_identity(::DDS::Security::IdentityHandle &remote_identity_handle, ::DDS::Security::AuthRequestMessageToken &local_auth_request_token, const ::DDS::Security::AuthRequestMessageToken &remote_auth_request_token, ::DDS::Security::IdentityHandle local_identity_handle, const ::DDS::Security::IdentityToken &remote_identity_token, const DCPS::GUID_t &remote_participant_guid, ::DDS::Security::SecurityException &ex)
DDS::OctetSeq * challenge1()
LocalParticipantData::shared_ptr get_local_participant(DDS::Security::IdentityHandle handle)
DDS::DomainId_t DomainId_t
virtual ::DDS::Security::ValidationResult_t validate_local_identity(::DDS::Security::IdentityHandle &local_identity_handle, DCPS::GUID_t &adjusted_participant_guid, ::DDS::Security::DomainId_t domain_id, const ::DDS::DomainParticipantQos &participant_qos, const DCPS::GUID_t &candidate_participant_guid, ::DDS::Security::SecurityException &ex)
DDS::Security::ValidationResult_t process_handshake_reply(DDS::Security::HandshakeMessageToken &handshake_message_out, const DDS::Security::HandshakeMessageToken &handshake_message_in, DDS::Security::HandshakeHandle handshake_handle, DDS::Security::SecurityException &ex)
SSL::DiffieHellman::unique_ptr diffie_hellman
LocalParticipantMap local_participants_
AuthenticationBuiltInImpl()
virtual ::CORBA::Boolean set_listener(::DDS::Security::AuthenticationListener_ptr listener, ::DDS::Security::SecurityException &ex)
ACE_Thread_Mutex handshake_mutex_
ACE_Thread_Mutex handle_mutex_
key GuidPrefix_t guidPrefix
HandshakeDataMap handshake_data_
T::rv_reference move(T &p)
virtual ::CORBA::Boolean return_identity_handle(::DDS::Security::IdentityHandle identity_handle, ::DDS::Security::SecurityException &ex)
const std::string Handshake_Reply_Class_Ext("Reply")
virtual ::CORBA::Boolean set_permissions_credential_and_token(::DDS::Security::IdentityHandle handle, const ::DDS::Security::PermissionsCredentialToken &permissions_credential, const ::DDS::Security::PermissionsToken &permissions_token, ::DDS::Security::SecurityException &ex)
virtual ::CORBA::Boolean return_identity_token(const ::DDS::Security::IdentityToken &token, ::DDS::Security::SecurityException &ex)
OpenDDS::internal::special_serialization typedef sequence< Parameter > ParameterList
u_int major_version(void)
unsigned char offset_1bit(const unsigned char array[], size_t i)
Gets byte from array as though it were shifted right one bit.
const SSL::Certificate & get_participant_cert() const
const char * dsign_algo() const
const std::string Auth_Plugin_Name("DDS:Auth:PKI-DH")
DDS::Security::HandshakeMessageToken reply
const std::string Auth_Plugin_Minor_Version("0")
Class to serialize and deserialize data for DDS.
DDS::Security::AuthRequestMessageToken remote_auth_request
HandshakeDataPair make_handshake_pair(DDS::Security::IdentityHandle h1, DDS::Security::IdentityHandle h2)
Finds the local and remote data objects associated with h1 and h2 and creates a new handshake pair wi...
int increment_handle(int &next)
DDS::Security::ValidationResult_t state
DDS::OctetSeq shared_secret_
const DDS::OctetSeq & get_access_permissions() const
DCPS::RcHandle< LocalParticipantData > shared_ptr
int verify_serialized(const DDS::BinaryPropertySeq &src, const Certificate &key, const DDS::OctetSeq &signed_data)
DDS::Security::IdentityHandle initiator_identity
std::string get_extension(const char *class_id)
DDS::Security::HandshakeMessageToken request
std::pair< LocalParticipantData::shared_ptr, RemoteParticipantData::shared_ptr > HandshakeDataPair
MessageToken AuthRequestMessageToken
virtual ::CORBA::Boolean return_sharedsecret_handle(::DDS::Security::SharedSecretHandle *sharedsecret_handle, ::DDS::Security::SecurityException &ex)
void add_property(const char *prop_name, const char *prop_value, bool propagate=true)
static void extract_participant_guid_from_cpdata(const DDS::OctetSeq &cpdata, DCPS::GUID_t &dst)
DDS::BinaryPropertySeq BinaryPropertySeq
char * wr_ptr(void) const
sequence< octet > OctetSeq
const std::string Handshake_Request_Class_Ext("Req")
virtual ::CORBA::Boolean get_identity_status_token(::DDS::Security::IdentityStatusToken &identity_status_token, ::DDS::Security::IdentityHandle handle, ::DDS::Security::SecurityException &ex)
LocalAuthCredentialData::shared_ptr credentials
const SSL::PrivateKey & get_participant_private_key() const
virtual ::CORBA::Boolean return_handshake_handle(::DDS::Security::HandshakeHandle handshake_handle, ::DDS::Security::SecurityException &ex)
const std::string Auth_Plugin_Major_Version("1")
virtual ::CORBA::Boolean get_authenticated_peer_credential_token(::DDS::Security::AuthenticatedPeerCredentialToken &peer_credential_token, ::DDS::Security::HandshakeHandle handshake_handle, ::DDS::Security::SecurityException &ex)
const DDS::OctetSeq & get_bin_property_value(const std::string &property_name) const
HandshakeDataPair get_handshake_data(DDS::Security::HandshakeHandle handle)
DDS::Security::SharedSecretHandle_var shared_secret
virtual ::DDS::Security::ValidationResult_t begin_handshake_reply(::DDS::Security::HandshakeHandle &handshake_handle, ::DDS::Security::HandshakeMessageToken &handshake_message_out, ::DDS::Security::IdentityHandle initiator_identity_handle, ::DDS::Security::IdentityHandle replier_identity_handle, const ::DDS::OctetSeq &serialized_local_participant_data, ::DDS::Security::SecurityException &ex)
bool check_class_versions(const char *remote_class_id)
Token IdentityStatusToken
MessageToken HandshakeMessageToken
DDS::OctetSeq challenge1_
const char Identity_Status_Token_Class_Id[]
const std::string Auth_Request_Class_Ext("AuthReq")
virtual ~AuthenticationBuiltInImpl()
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
int make_adjusted_guid(const OpenDDS::DCPS::GUID_t &src, OpenDDS::DCPS::GUID_t &dst, const Certificate &target)
int subject_name_to_str(std::string &dst, unsigned long flags=XN_FLAG_ONELINE) const
std::string build_class_id(const std::string &message_ext)
Token PermissionsCredentialToken
DDS::OctetSeq challenge2_
virtual ::CORBA::Boolean get_identity_token(::DDS::Security::IdentityToken &identity_token, ::DDS::Security::IdentityHandle handle, ::DDS::Security::SecurityException &ex)
DDS::Security::AuthenticationListener_ptr listener_ptr_
const char dds_cert_algo[]
bool set_security_error(DDS::Security::SecurityException &ex, int code, int minor_code, const char *message)
const SSL::Certificate & get_ca_cert() const
static bool challenges_match(const DDS::OctetSeq &c1, const DDS::OctetSeq &c2)
The Internal API and Implementation of OpenDDS.
enum OpenDDS::DCPS::SecurityDebug::ForceAuthRole force_auth_role
virtual ::DDS::Security::ValidationResult_t process_handshake(::DDS::Security::HandshakeMessageToken &handshake_message_out, const ::DDS::Security::HandshakeMessageToken &handshake_message_in, ::DDS::Security::HandshakeHandle handshake_handle, ::DDS::Security::SecurityException &ex)
Token AuthenticatedPeerCredentialToken
Implements some simple wrapper functions to provide a non-const API around the Token data structure a...
static bool validate_topic_data_guid(const DDS::OctetSeq &cpdata, const std::vector< unsigned char > &subject_name_hash, DDS::Security::SecurityException &ex)
OpenDDS_Dcps_Export SecurityDebug security_debug
virtual ::CORBA::Boolean return_identity_status_token(const ::DDS::Security::IdentityStatusToken &token, ::DDS::Security::SecurityException &ex)
const char * keypair_algo() const
CORBA::Long get_next_handle()
const std::string Handshake_Final_Class_Ext("Final")
DDS::Security::AuthRequestMessageToken local_auth_request
virtual ::CORBA::Boolean return_authenticated_peer_credential_token(const ::DDS::Security::AuthenticatedPeerCredentialToken &peer_credential_token, ::DDS::Security::SecurityException &ex)
static const char * PROPERTY_HANDSHAKE_DEBUG
include in PropertyQosPolicy to add optional properties to Handshake tokens