From 4ff67d61d4f8b124e27c96c951a27c3f54951d9d Mon Sep 17 00:00:00 2001 From: Olli Huopio <46792656+ohuopio@users.noreply.github.com> Date: Fri, 15 Mar 2024 11:19:42 +0200 Subject: [PATCH] Security: FastDDS compatibility mode (#328) * Sign the security config files with the -text option. This produces .ps7 files with the 'Content-Type: text/plain' header, which is what FastDDS expects * Get the identity subject name directly from the identity certificate, not the identity token. * Serialize certificate subject name to the format produced by the openssl x509_name_oneline function * Use the algorithm identifiers that FastDDS expects in IdentityToken and PermissionsToken * Change logging about protected interpreter submessages to debug level * Put the interoperability adjustments behind the feature "security_in_fastdds_compatibility_mode". Document the FastDDS-compatibility mode. * Fix latest clippy warnings and fmt. * Resolve the interoperability issues by not sending the optional CA subject name and algorithm in PermissionsToken. Remove the FastDDS interoperability feature. --------- Co-authored-by: Juhana Helovuo --- SECURITY.md | 2 +- .../security_configuration_files/cert.pem | 12 ++--- ...nerate-test-certificates-and-signatures.sh | 4 +- .../governance.p7s | 42 +++++++++-------- .../identity_ca.cert.pem | 16 +++---- .../identity_ca_private_key.pem | 10 ++-- .../identity_certificate_request.pem | 10 ++-- examples/security_configuration_files/key.pem | 6 +-- .../permissions.p7s | 42 +++++++++-------- .../permissions_ca.cert.pem | 18 ++++---- .../permissions_ca_private_key.pem | 10 ++-- .../sign-test-configurations.sh | 4 +- src/dds/pubsub.rs | 39 ++++++++-------- src/discovery/discovery_db.rs | 2 +- src/discovery/spdp_participant_data.rs | 24 +++++++--- src/ros2/ros_node.rs | 2 +- src/rtps/rtps_reader_proxy.rs | 4 +- .../participant_access_control.rs | 46 ++++++++++++------- .../authentication_builtin/types.rs | 5 +- src/security/certificate.rs | 1 + .../cryptographic_builtin/crypto_transform.rs | 4 +- src/security/types.rs | 4 -- 22 files changed, 169 insertions(+), 138 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index f567db18..f99fb654 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -72,4 +72,4 @@ The following security configuration files are needed: Configuration files can be created using any method, but the OpenSSL tool is recommended. -Please see the examples and scripts in the directory [examples/security_configuration_files](examples/security_configuration_files). +Please see the examples and scripts in the directory [examples/security_configuration_files](examples/security_configuration_files). \ No newline at end of file diff --git a/examples/security_configuration_files/cert.pem b/examples/security_configuration_files/cert.pem index d621a35a..ff60ed46 100644 --- a/examples/security_configuration_files/cert.pem +++ b/examples/security_configuration_files/cert.pem @@ -1,10 +1,10 @@ -----BEGIN CERTIFICATE----- MIIBbTCCARMCAQEwCgYIKoZIzj0EAwIwQTEdMBsGA1UECgwURXhhbXBsZSBPcmdh -bml6YXRpb24xIDAeBgNVBAMMF2lkZW50aXR5X2NhX2NvbW1vbl9uYW1lMCAXDTIz -MTEyNzEzNDUwM1oYDzQ3NjExMDIzMTM0NTAzWjBCMR0wGwYDVQQKDBRFeGFtcGxl +bml6YXRpb24xIDAeBgNVBAMMF2lkZW50aXR5X2NhX2NvbW1vbl9uYW1lMCAXDTI0 +MDMwODA4Mjk1MVoYDzQ3NjIwMjAyMDgyOTUxWjBCMR0wGwYDVQQKDBRFeGFtcGxl IE9yZ2FuaXphdGlvbjEhMB8GA1UEAwwYcGFydGljaXBhbnQxX2NvbW1vbl9uYW1l -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzhiR7GO/Ga8fOL1c0G14vFntM8gB -+NRTFKLlBbCG5b20POJmQ4mw9Y+7niTg90vXrNN8CIMmR2XF/qE6/XFSbzAKBggq -hkjOPQQDAgNIADBFAiBsvD7JF7jIx2BmiN5ZQFO42A3ToeeP87oEKQpElCw7EQIh -AM5z6IOAyzMsT5EuycjUcVkVLUtJRR4CY42JKdrDCipT +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvs3uxr9HNmkJenoSj+YRdtSCDK4B +YHpe4Oj8q2ZH++zN9xNdI3Ucw0cvhbob+C30IjaNNYeCUGkLnXFI/WIGTzAKBggq +hkjOPQQDAgNIADBFAiEAt6W+orACUZ8Q+7Rtj/kagdZ6eh/h5lxh0Chj9eMoat8C +IHABglChJDrynMX272q89kF5SCVeL+bWlytw46QbDbWa -----END CERTIFICATE----- diff --git a/examples/security_configuration_files/generate-test-certificates-and-signatures.sh b/examples/security_configuration_files/generate-test-certificates-and-signatures.sh index 6925112e..0c271dae 100755 --- a/examples/security_configuration_files/generate-test-certificates-and-signatures.sh +++ b/examples/security_configuration_files/generate-test-certificates-and-signatures.sh @@ -7,8 +7,8 @@ openssl ecparam -name prime256v1 -out ec_parameters.pem openssl req -x509 -newkey param:ec_parameters.pem -keyout permissions_ca_private_key.pem -passout file:password -out permissions_ca.cert.pem -days 999999 -subj "/O=Example Organization/CN=permissions_ca_common_name" # Sign the configuration documents -openssl smime -sign -in governance_unsigned.xml -out governance.p7s -signer permissions_ca.cert.pem -inkey permissions_ca_private_key.pem -passin file:password -openssl smime -sign -in permissions_unsigned.xml -out permissions.p7s -signer permissions_ca.cert.pem -inkey permissions_ca_private_key.pem -passin file:password +openssl smime -sign -in governance_unsigned.xml -text -out governance.p7s -signer permissions_ca.cert.pem -inkey permissions_ca_private_key.pem -passin file:password +openssl smime -sign -in permissions_unsigned.xml -text -out permissions.p7s -signer permissions_ca.cert.pem -inkey permissions_ca_private_key.pem -passin file:password # Create the identity CA diff --git a/examples/security_configuration_files/governance.p7s b/examples/security_configuration_files/governance.p7s index f69d4981..b9f58a72 100644 --- a/examples/security_configuration_files/governance.p7s +++ b/examples/security_configuration_files/governance.p7s @@ -1,9 +1,11 @@ MIME-Version: 1.0 -Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----0306BCAF9E9FC6C9C12A431F68A469AF" +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----0793F24F1D3500E3B22E6166CF512EF7" This is an S/MIME signed message -------0306BCAF9E9FC6C9C12A431F68A469AF +------0793F24F1D3500E3B22E6166CF512EF7 +Content-Type: text/plain + @@ -35,32 +37,32 @@ xsi:noNamespaceSchemaLocation="http://www.omg.org/spec/DDS-SECURITY/20170901/omg -------0306BCAF9E9FC6C9C12A431F68A469AF +------0793F24F1D3500E3B22E6166CF512EF7 Content-Type: application/x-pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" MIIDzwYJKoZIhvcNAQcCoIIDwDCCA7wCAQExDzANBglghkgBZQMEAgEFADALBgkq -hkiG9w0BBwGgggHjMIIB3zCCAYWgAwIBAgIUArkFHlgvGsil7TuYvQqROBhEJU4w +hkiG9w0BBwGgggHjMIIB3zCCAYWgAwIBAgIUZ15lOVw1lFhBNlKlgdqzkhBHDsww CgYIKoZIzj0EAwIwRDEdMBsGA1UECgwURXhhbXBsZSBPcmdhbml6YXRpb24xIzAh -BgNVBAMMGnBlcm1pc3Npb25zX2NhX2NvbW1vbl9uYW1lMCAXDTIzMTEyNzEzNDUw -M1oYDzQ3NjExMDIzMTM0NTAzWjBEMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXph +BgNVBAMMGnBlcm1pc3Npb25zX2NhX2NvbW1vbl9uYW1lMCAXDTI0MDMwODA4Mjk1 +MVoYDzQ3NjIwMjAyMDgyOTUxWjBEMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXph dGlvbjEjMCEGA1UEAwwacGVybWlzc2lvbnNfY2FfY29tbW9uX25hbWUwWTATBgcq -hkjOPQIBBggqhkjOPQMBBwNCAATEROqDZhxrXDXM0gWDxy+wavkwB/Gl32rF+bdW -fPf2oQAkuy0+nqXx7KPAWfBSHEWxyjxnXnNkzVy7S60vsaEto1MwUTAdBgNVHQ4E -FgQUCbDH5hkTzYiyO2fiDM1kiOXz8wkwHwYDVR0jBBgwFoAUCbDH5hkTzYiyO2fi -DM1kiOXz8wkwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEArYKx -izKj1wpRriFmSDncj9T+bocWStWIGDynJUZtZ8sCIEsMHMD9iG0JakUMxZHFfJfm -t5B+FBfN3Oj18kiBMnnxMYIBsDCCAawCAQEwXDBEMR0wGwYDVQQKDBRFeGFtcGxl +hkjOPQIBBggqhkjOPQMBBwNCAAQwHk/PoxLxEP27ez5jzmof7KDXkcm9APMamnHe +G1E4TbBNZr7FVn5MbsW+5HeklhPSAPC1FefXsOb4AcbO4T/xo1MwUTAdBgNVHQ4E +FgQU1771sTC5VjQST2vWBFVoc6XwiRUwHwYDVR0jBBgwFoAU1771sTC5VjQST2vW +BFVoc6XwiRUwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiBIb4Ro +lJ6v4JYqORbipeqKCLV7TuNlayxv6962VSk3yQIhAIjkrqBU9QSO+EIP6bsK+jcc +47gvd+cnf3/zPWJbNt21MYIBsDCCAawCAQEwXDBEMR0wGwYDVQQKDBRFeGFtcGxl IE9yZ2FuaXphdGlvbjEjMCEGA1UEAwwacGVybWlzc2lvbnNfY2FfY29tbW9uX25h -bWUCFAK5BR5YLxrIpe07mL0KkTgYRCVOMA0GCWCGSAFlAwQCAQUAoIHkMBgGCSqG -SIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIzMTEyNzEzNDUw -M1owLwYJKoZIhvcNAQkEMSIEIFe1thS1OysYioiONd81Avy3O2h5/z8Qox6D3y1g -YsulMHkGCSqGSIb3DQEJDzFsMGowCwYJYIZIAWUDBAEqMAsGCWCGSAFlAwQBFjAL +bWUCFGdeZTlcNZRYQTZSpYHas5IQRw7MMA0GCWCGSAFlAwQCAQUAoIHkMBgGCSqG +SIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI0MDMwODA4Mjk1 +MVowLwYJKoZIhvcNAQkEMSIEILsmD3IAiSdc8ecU97iBACutVtUs1vIkAFJD9GA6 +2eFnMHkGCSqGSIb3DQEJDzFsMGowCwYJYIZIAWUDBAEqMAsGCWCGSAFlAwQBFjAL BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3 -DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMAoGCCqGSM49BAMCBEcwRQIh -AMEkHzCvzWcJwpIRges7P5+dz8GwtT5EhkijKws4dcSiAiAtOoxP8C3tsiwY7oaF -lKYuUSDF4YPE/eahOuelWOQkag== +DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMAoGCCqGSM49BAMCBEcwRQIg +IFxvwTkp1LSD4se94lKBNIuI3JINJdLcDkOuS8GL7DoCIQCtLq0gdAgK+qB1voxN +TsFSIgqX1s0uBtgJhgUde2Qh6g== -------0306BCAF9E9FC6C9C12A431F68A469AF-- +------0793F24F1D3500E3B22E6166CF512EF7-- diff --git a/examples/security_configuration_files/identity_ca.cert.pem b/examples/security_configuration_files/identity_ca.cert.pem index 89ce179d..592fe7f8 100644 --- a/examples/security_configuration_files/identity_ca.cert.pem +++ b/examples/security_configuration_files/identity_ca.cert.pem @@ -1,12 +1,12 @@ -----BEGIN CERTIFICATE----- -MIIB2TCCAX+gAwIBAgIUW0oyDuzmDq+g+uUs9+i62a5eNBEwCgYIKoZIzj0EAwIw +MIIB2jCCAX+gAwIBAgIUY/OV21LPUNPB1eb8EAkNzd/4hAswCgYIKoZIzj0EAwIw QTEdMBsGA1UECgwURXhhbXBsZSBPcmdhbml6YXRpb24xIDAeBgNVBAMMF2lkZW50 -aXR5X2NhX2NvbW1vbl9uYW1lMCAXDTIzMTEyNzEzNDUwM1oYDzQ3NjExMDIzMTM0 -NTAzWjBBMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjEgMB4GA1UEAwwX +aXR5X2NhX2NvbW1vbl9uYW1lMCAXDTI0MDMwODA4Mjk1MVoYDzQ3NjIwMjAyMDgy +OTUxWjBBMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjEgMB4GA1UEAwwX aWRlbnRpdHlfY2FfY29tbW9uX25hbWUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC -AAS8pbgENNkfzuiNJj/UJAKXkHuhnZvCpUSBsrQ6BbvErBL9HD2iuva63bgj6IZC -7ziSzCpgRgAlfmgHp4XguuXpo1MwUTAdBgNVHQ4EFgQU7E5CjzZeBUNQ4QIUDz5M -3GjM8OEwHwYDVR0jBBgwFoAU7E5CjzZeBUNQ4QIUDz5M3GjM8OEwDwYDVR0TAQH/ -BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiAx+XreJabZ7RBdBk3bzo3AonU4fCwy -ap/8wy0fPEi5wgIhAPwgZfuaBYgmCLdCTlKLHLub7phl96PjMMHKSZX1zjFm +AARBn3Bj3cUezGOooSb9FQUGpCGmZTY9nnkaKYSYjp2Z0s23xZoMxwhjlu3M9GgC +lyLeuaqodxsPp/+y26Rj0aT3o1MwUTAdBgNVHQ4EFgQUanyJvwa5bc/RyQo0tRGx +QKKIS10wHwYDVR0jBBgwFoAUanyJvwa5bc/RyQo0tRGxQKKIS10wDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAgNJADBGAiEAsE3SzbcvlxhBhswa3l3RmL87V3TT +728A4h5ah6pfEy4CIQDtFu6vyO95VH3fvHNJS5e5nBpQfYCWoUhSIsUXm8PUsA== -----END CERTIFICATE----- diff --git a/examples/security_configuration_files/identity_ca_private_key.pem b/examples/security_configuration_files/identity_ca_private_key.pem index 86c8e099..1c0f4e9b 100644 --- a/examples/security_configuration_files/identity_ca_private_key.pem +++ b/examples/security_configuration_files/identity_ca_private_key.pem @@ -1,7 +1,7 @@ -----BEGIN ENCRYPTED PRIVATE KEY----- -MIHjME4GCSqGSIb3DQEFDTBBMCkGCSqGSIb3DQEFDDAcBAh5ff1fsdQGlAICCAAw -DAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQItWF0QRI2FNIEgZBZeKtWNHSbMnLv -vWEwmummxhjwW+vq4TjPTew2Dp0mkm1R3ZtpUNBoZXIipKuw5/Av/vPNwTzXu3Wl -I8sc1KlXWkgc9xajAHowaEv2azKASvBm+cXvdkUqAi9/rJIKPsf+scOkL4ZrnLkC -OpcNrs0jb5PzRWO4pBMRw+5VNRZNK71eJF2DDmL6p1e+NLVnYUY= +MIHjME4GCSqGSIb3DQEFDTBBMCkGCSqGSIb3DQEFDDAcBAhJGY5NxXyseQICCAAw +DAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQIkbzbgpXSbCQEgZDmMUeVyXa72lbJ +3aheKK0lxlLZkFPeuCkFxoaW1VPHwqd9aX+dasng+1y0X36enYWfTClVlXJWhbgL +m9BfQpzpHBgc/jaqMjLUOWF3XRF57harZrZ7ARoyWH5kcRUFgBmaxnuMgxu1zcNN +FO4l3JBKhCjCU99RUKjsU7mdkkdr0hjEdeuuaw5f/huI1OHUqKI= -----END ENCRYPTED PRIVATE KEY----- diff --git a/examples/security_configuration_files/identity_certificate_request.pem b/examples/security_configuration_files/identity_certificate_request.pem index 74cdf795..4fc5ec86 100644 --- a/examples/security_configuration_files/identity_certificate_request.pem +++ b/examples/security_configuration_files/identity_certificate_request.pem @@ -1,8 +1,8 @@ -----BEGIN CERTIFICATE REQUEST----- -MIH+MIGkAgEAMEIxHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0aW9uMSEwHwYD +MIH9MIGkAgEAMEIxHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0aW9uMSEwHwYD VQQDDBhwYXJ0aWNpcGFudDFfY29tbW9uX25hbWUwWTATBgcqhkjOPQIBBggqhkjO -PQMBBwNCAATOGJHsY78Zrx84vVzQbXi8We0zyAH41FMUouUFsIblvbQ84mZDibD1 -j7ueJOD3S9es03wIgyZHZcX+oTr9cVJvoAAwCgYIKoZIzj0EAwIDSQAwRgIhAMaQ -VLpcxYb5iTkR6YftS8v7EXjdtoaYv4qpEHFkeazRAiEAn5lQepC9PMisZAMcajwI -lXarBzWPkojvNKnMy3PpjNQ= +PQMBBwNCAAS+ze7Gv0c2aQl6ehKP5hF21IIMrgFgel7g6PyrZkf77M33E10jdRzD +Ry+Fuhv4LfQiNo01h4JQaQudcUj9YgZPoAAwCgYIKoZIzj0EAwIDSAAwRQIhAOSi +Z6mCOeqUXjmscdJLtu7CHknZISSCXDYRf7xQCXqtAiB8WMnijplDFbV+ab+0duSo +dS7daJnttMXczfuhUvX9IQ== -----END CERTIFICATE REQUEST----- diff --git a/examples/security_configuration_files/key.pem b/examples/security_configuration_files/key.pem index 6f436858..eafe0a1b 100644 --- a/examples/security_configuration_files/key.pem +++ b/examples/security_configuration_files/key.pem @@ -1,5 +1,5 @@ -----BEGIN PRIVATE KEY----- -MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg+jJ2YcczH0gTaxjb -c6znOfDSfpexymhkuFxtS/O6J7ehRANCAATOGJHsY78Zrx84vVzQbXi8We0zyAH4 -1FMUouUFsIblvbQ84mZDibD1j7ueJOD3S9es03wIgyZHZcX+oTr9cVJv +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgolJ0IlvkuB71WxUQ +R9j0d/qj2ucMn05Ex4BWK/b9ipqhRANCAAS+ze7Gv0c2aQl6ehKP5hF21IIMrgFg +el7g6PyrZkf77M33E10jdRzDRy+Fuhv4LfQiNo01h4JQaQudcUj9YgZP -----END PRIVATE KEY----- diff --git a/examples/security_configuration_files/permissions.p7s b/examples/security_configuration_files/permissions.p7s index bcb5d411..a65fb7bd 100644 --- a/examples/security_configuration_files/permissions.p7s +++ b/examples/security_configuration_files/permissions.p7s @@ -1,9 +1,11 @@ MIME-Version: 1.0 -Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----0ACE8DCADB156B6CFC73CD44A50EB831" +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----7811F8EBB0502A372D26F1854BDFC3AA" This is an S/MIME signed message -------0ACE8DCADB156B6CFC73CD44A50EB831 +------7811F8EBB0502A372D26F1854BDFC3AA +Content-Type: text/plain + @@ -61,32 +63,32 @@ This is an S/MIME signed message -------0ACE8DCADB156B6CFC73CD44A50EB831 +------7811F8EBB0502A372D26F1854BDFC3AA Content-Type: application/x-pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" MIIDzwYJKoZIhvcNAQcCoIIDwDCCA7wCAQExDzANBglghkgBZQMEAgEFADALBgkq -hkiG9w0BBwGgggHjMIIB3zCCAYWgAwIBAgIUArkFHlgvGsil7TuYvQqROBhEJU4w +hkiG9w0BBwGgggHjMIIB3zCCAYWgAwIBAgIUZ15lOVw1lFhBNlKlgdqzkhBHDsww CgYIKoZIzj0EAwIwRDEdMBsGA1UECgwURXhhbXBsZSBPcmdhbml6YXRpb24xIzAh -BgNVBAMMGnBlcm1pc3Npb25zX2NhX2NvbW1vbl9uYW1lMCAXDTIzMTEyNzEzNDUw -M1oYDzQ3NjExMDIzMTM0NTAzWjBEMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXph +BgNVBAMMGnBlcm1pc3Npb25zX2NhX2NvbW1vbl9uYW1lMCAXDTI0MDMwODA4Mjk1 +MVoYDzQ3NjIwMjAyMDgyOTUxWjBEMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXph dGlvbjEjMCEGA1UEAwwacGVybWlzc2lvbnNfY2FfY29tbW9uX25hbWUwWTATBgcq -hkjOPQIBBggqhkjOPQMBBwNCAATEROqDZhxrXDXM0gWDxy+wavkwB/Gl32rF+bdW -fPf2oQAkuy0+nqXx7KPAWfBSHEWxyjxnXnNkzVy7S60vsaEto1MwUTAdBgNVHQ4E -FgQUCbDH5hkTzYiyO2fiDM1kiOXz8wkwHwYDVR0jBBgwFoAUCbDH5hkTzYiyO2fi -DM1kiOXz8wkwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEArYKx -izKj1wpRriFmSDncj9T+bocWStWIGDynJUZtZ8sCIEsMHMD9iG0JakUMxZHFfJfm -t5B+FBfN3Oj18kiBMnnxMYIBsDCCAawCAQEwXDBEMR0wGwYDVQQKDBRFeGFtcGxl +hkjOPQIBBggqhkjOPQMBBwNCAAQwHk/PoxLxEP27ez5jzmof7KDXkcm9APMamnHe +G1E4TbBNZr7FVn5MbsW+5HeklhPSAPC1FefXsOb4AcbO4T/xo1MwUTAdBgNVHQ4E +FgQU1771sTC5VjQST2vWBFVoc6XwiRUwHwYDVR0jBBgwFoAU1771sTC5VjQST2vW +BFVoc6XwiRUwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiBIb4Ro +lJ6v4JYqORbipeqKCLV7TuNlayxv6962VSk3yQIhAIjkrqBU9QSO+EIP6bsK+jcc +47gvd+cnf3/zPWJbNt21MYIBsDCCAawCAQEwXDBEMR0wGwYDVQQKDBRFeGFtcGxl IE9yZ2FuaXphdGlvbjEjMCEGA1UEAwwacGVybWlzc2lvbnNfY2FfY29tbW9uX25h -bWUCFAK5BR5YLxrIpe07mL0KkTgYRCVOMA0GCWCGSAFlAwQCAQUAoIHkMBgGCSqG -SIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIzMTEyNzEzNDUw -M1owLwYJKoZIhvcNAQkEMSIEIEjonjTFRKfHUE3pci4O1ZL15hhKex62/rN/I9tq -GFz+MHkGCSqGSIb3DQEJDzFsMGowCwYJYIZIAWUDBAEqMAsGCWCGSAFlAwQBFjAL +bWUCFGdeZTlcNZRYQTZSpYHas5IQRw7MMA0GCWCGSAFlAwQCAQUAoIHkMBgGCSqG +SIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI0MDMwODA4Mjk1 +MVowLwYJKoZIhvcNAQkEMSIEICqm9+7kfEaMW0WDNZtawrxhPJdzdEEcoaWHjM+i +vzxHMHkGCSqGSIb3DQEJDzFsMGowCwYJYIZIAWUDBAEqMAsGCWCGSAFlAwQBFjAL BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3 -DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMAoGCCqGSM49BAMCBEcwRQIg -GZCH97FMki/HtAzmUvdY6kot55MUArOXNaFCSy8soSMCIQDwq1i+UlZ9IVoKsNGY -CiIb+CtznA8D+gwr/HC5R1gsBQ== +DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMAoGCCqGSM49BAMCBEcwRQIh +AL1Rk3WhK4MceexeI4p9tRDcP8KVdILfE3s/WvEpDK4RAiBdSJ8rFegC1PE4ON25 +0AYNqkzG6spC+Y5f71ky7LO7gQ== -------0ACE8DCADB156B6CFC73CD44A50EB831-- +------7811F8EBB0502A372D26F1854BDFC3AA-- diff --git a/examples/security_configuration_files/permissions_ca.cert.pem b/examples/security_configuration_files/permissions_ca.cert.pem index 274bdfe1..8f8ccd34 100644 --- a/examples/security_configuration_files/permissions_ca.cert.pem +++ b/examples/security_configuration_files/permissions_ca.cert.pem @@ -1,13 +1,13 @@ -----BEGIN CERTIFICATE----- -MIIB3zCCAYWgAwIBAgIUArkFHlgvGsil7TuYvQqROBhEJU4wCgYIKoZIzj0EAwIw +MIIB3zCCAYWgAwIBAgIUZ15lOVw1lFhBNlKlgdqzkhBHDswwCgYIKoZIzj0EAwIw RDEdMBsGA1UECgwURXhhbXBsZSBPcmdhbml6YXRpb24xIzAhBgNVBAMMGnBlcm1p -c3Npb25zX2NhX2NvbW1vbl9uYW1lMCAXDTIzMTEyNzEzNDUwM1oYDzQ3NjExMDIz -MTM0NTAzWjBEMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjEjMCEGA1UE +c3Npb25zX2NhX2NvbW1vbl9uYW1lMCAXDTI0MDMwODA4Mjk1MVoYDzQ3NjIwMjAy +MDgyOTUxWjBEMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjEjMCEGA1UE AwwacGVybWlzc2lvbnNfY2FfY29tbW9uX25hbWUwWTATBgcqhkjOPQIBBggqhkjO -PQMBBwNCAATEROqDZhxrXDXM0gWDxy+wavkwB/Gl32rF+bdWfPf2oQAkuy0+nqXx -7KPAWfBSHEWxyjxnXnNkzVy7S60vsaEto1MwUTAdBgNVHQ4EFgQUCbDH5hkTzYiy -O2fiDM1kiOXz8wkwHwYDVR0jBBgwFoAUCbDH5hkTzYiyO2fiDM1kiOXz8wkwDwYD -VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEArYKxizKj1wpRriFmSDnc -j9T+bocWStWIGDynJUZtZ8sCIEsMHMD9iG0JakUMxZHFfJfmt5B+FBfN3Oj18kiB -Mnnx +PQMBBwNCAAQwHk/PoxLxEP27ez5jzmof7KDXkcm9APMamnHeG1E4TbBNZr7FVn5M +bsW+5HeklhPSAPC1FefXsOb4AcbO4T/xo1MwUTAdBgNVHQ4EFgQU1771sTC5VjQS +T2vWBFVoc6XwiRUwHwYDVR0jBBgwFoAU1771sTC5VjQST2vWBFVoc6XwiRUwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiBIb4RolJ6v4JYqORbipeqK +CLV7TuNlayxv6962VSk3yQIhAIjkrqBU9QSO+EIP6bsK+jcc47gvd+cnf3/zPWJb +Nt21 -----END CERTIFICATE----- diff --git a/examples/security_configuration_files/permissions_ca_private_key.pem b/examples/security_configuration_files/permissions_ca_private_key.pem index d31f9704..8f0f1361 100644 --- a/examples/security_configuration_files/permissions_ca_private_key.pem +++ b/examples/security_configuration_files/permissions_ca_private_key.pem @@ -1,7 +1,7 @@ -----BEGIN ENCRYPTED PRIVATE KEY----- -MIHjME4GCSqGSIb3DQEFDTBBMCkGCSqGSIb3DQEFDDAcBAgYhktmNPUKMAICCAAw -DAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQIj1ydXc/n75gEgZBzFLDBxbRVlwwa -i1YeDkIj9Y88OrSpq2alM8FXcyTD2BKXGqcrmKnuadBeCzgvTLjaAwAB1jj+qNJv -elbr8/gPcxekTtAYHWLi1zs5pFSXe3kzIQHKd8dsAwTOkPbDLo7K23pfClKavJ3k -P8/ZtngzfxcEafg2kbXEqE31or9bRUNBFyr4ufholfYdLkGNjFI= +MIHjME4GCSqGSIb3DQEFDTBBMCkGCSqGSIb3DQEFDDAcBAhmjvldsMft4AICCAAw +DAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQI2yilsIvDjOMEgZBbl1NjP9RgQqfk +6i6niP7e9nvGa8TdcZDG0AdRqRHiCkW8cbHsij6Vu2Gir7D4NC77/u963KIlknKF +pBv/hK7zKrjWsQzzdkRxtPR4+exS1negnnRIK7gD5E9HLl28kq2vI9/zHfCC6RAp +YbO8paG13/Ed9otvAycNI2hqi7fuy0B11jx6SeEFPzGzuadqxOs= -----END ENCRYPTED PRIVATE KEY----- diff --git a/examples/security_configuration_files/sign-test-configurations.sh b/examples/security_configuration_files/sign-test-configurations.sh index ff0623af..d8cd33d8 100755 --- a/examples/security_configuration_files/sign-test-configurations.sh +++ b/examples/security_configuration_files/sign-test-configurations.sh @@ -1,5 +1,5 @@ #!/bin/bash # Sign test configurations -openssl smime -sign -in governance_unsigned.xml -out governance.p7s -signer permissions_ca.cert.pem -inkey permissions_ca_private_key.pem -passin file:password -openssl smime -sign -in permissions_unsigned.xml -out permissions.p7s -signer permissions_ca.cert.pem -inkey permissions_ca_private_key.pem -passin file:password \ No newline at end of file +openssl smime -sign -in governance_unsigned.xml -text -out governance.p7s -signer permissions_ca.cert.pem -inkey permissions_ca_private_key.pem -passin file:password +openssl smime -sign -in permissions_unsigned.xml -text -out permissions.p7s -signer permissions_ca.cert.pem -inkey permissions_ca_private_key.pem -passin file:password \ No newline at end of file diff --git a/src/dds/pubsub.rs b/src/dds/pubsub.rs index 8f1dcaca..5b2c6f73 100644 --- a/src/dds/pubsub.rs +++ b/src/dds/pubsub.rs @@ -795,25 +795,25 @@ impl Subscriber { /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap(); /// let data_reader = subscriber.create_datareader::>(&topic, None); /// ``` - pub fn create_datareader( + pub fn create_datareader( &self, topic: &Topic, qos: Option, ) -> CreateResult> where - D: Keyed, + D: 'static + Keyed, SA: adapters::with_key::DeserializerAdapter, { self.inner.create_datareader(self, topic, None, qos, false) } - pub fn create_datareader_cdr( + pub fn create_datareader_cdr( &self, topic: &Topic, qos: Option, ) -> CreateResult>> where - D: serde::de::DeserializeOwned + Keyed, + D: 'static + serde::de::DeserializeOwned + Keyed, for<'de> ::K: Deserialize<'de>, { self.create_datareader::>(topic, qos) @@ -848,12 +848,13 @@ impl Subscriber { /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::NoKey).unwrap(); /// let data_reader = subscriber.create_datareader_no_key::>(&topic, None); /// ``` - pub fn create_datareader_no_key( + pub fn create_datareader_no_key( &self, topic: &Topic, qos: Option, ) -> CreateResult> where + D: 'static, SA: adapters::no_key::DeserializerAdapter, { self @@ -861,33 +862,34 @@ impl Subscriber { .create_datareader_no_key(self, topic, None, qos, false) } - pub fn create_simple_datareader_no_key( + pub fn create_simple_datareader_no_key( &self, topic: &Topic, qos: Option, ) -> CreateResult> where - DA: adapters::no_key::DeserializerAdapter, + D: 'static, + DA: 'static + adapters::no_key::DeserializerAdapter, { self .inner .create_simple_datareader_no_key(self, topic, None, qos) } - pub fn create_datareader_no_key_cdr( + pub fn create_datareader_no_key_cdr( &self, topic: &Topic, qos: Option, ) -> CreateResult>> where - D: serde::de::DeserializeOwned, + D: 'static + serde::de::DeserializeOwned, { self.create_datareader_no_key::>(topic, qos) } // versions with callee-specified EntityId. These are for Discovery use only. - pub(crate) fn create_datareader_with_entity_id_with_key( + pub(crate) fn create_datareader_with_entity_id_with_key( &self, topic: &Topic, entity_id: EntityId, @@ -895,7 +897,7 @@ impl Subscriber { reader_like_stateless: bool, // Create a stateless-like RTPS reader? ) -> CreateResult> where - D: Keyed, + D: 'static + Keyed, SA: adapters::with_key::DeserializerAdapter, { self @@ -904,7 +906,7 @@ impl Subscriber { } #[cfg(feature = "security")] // to avoid "never used" warning - pub(crate) fn create_datareader_with_entity_id_no_key( + pub(crate) fn create_datareader_with_entity_id_no_key( &self, topic: &Topic, entity_id: EntityId, @@ -912,6 +914,7 @@ impl Subscriber { reader_like_stateless: bool, // Create a stateless-like RTPS reader? ) -> CreateResult> where + D: 'static, SA: adapters::no_key::DeserializerAdapter, { self @@ -992,7 +995,7 @@ impl InnerSubscriber { } } - fn create_datareader_internal( + fn create_datareader_internal( &self, outer: &Subscriber, entity_id_opt: Option, @@ -1001,7 +1004,7 @@ impl InnerSubscriber { reader_like_stateless: bool, // Create a stateless-like RTPS reader? Usually false ) -> CreateResult> where - D: Keyed, + D: 'static + Keyed, SA: adapters::with_key::DeserializerAdapter, { let simple_dr = self.create_simple_datareader_internal( @@ -1016,7 +1019,7 @@ impl InnerSubscriber { )) } - fn create_simple_datareader_internal( + fn create_simple_datareader_internal( &self, outer: &Subscriber, entity_id_opt: Option, @@ -1025,7 +1028,7 @@ impl InnerSubscriber { reader_like_stateless: bool, // Create a stateless-like RTPS reader? Usually false ) -> CreateResult> where - D: Keyed, + D: 'static + Keyed, SA: adapters::with_key::DeserializerAdapter, { // incoming data notification channel from Reader to DataReader @@ -1225,7 +1228,7 @@ impl InnerSubscriber { Ok(datareader) } - pub fn create_datareader( + pub fn create_datareader( &self, outer: &Subscriber, topic: &Topic, @@ -1234,7 +1237,7 @@ impl InnerSubscriber { reader_like_stateless: bool, // Create a stateless-like RTPS reader? Usually false ) -> CreateResult> where - D: Keyed, + D: 'static + Keyed, SA: adapters::with_key::DeserializerAdapter, { if topic.kind() != TopicKind::WithKey { diff --git a/src/discovery/discovery_db.rs b/src/discovery/discovery_db.rs index 45a6ed2a..bd231ddc 100644 --- a/src/discovery/discovery_db.rs +++ b/src/discovery/discovery_db.rs @@ -176,7 +176,7 @@ impl DiscoveryDB { // } let mut new_participant = false; - if self.participant_proxies.get(&guid.prefix).is_none() { + if !self.participant_proxies.contains_key(&guid.prefix) { info!("New remote participant: {:?}", &data); new_participant = true; if guid == self.my_guid { diff --git a/src/discovery/spdp_participant_data.rs b/src/discovery/spdp_participant_data.rs index 5b942744..24fa849d 100644 --- a/src/discovery/spdp_participant_data.rs +++ b/src/discovery/spdp_participant_data.rs @@ -110,11 +110,19 @@ impl SpdpDiscoveredParticipantData { ); if !is_metatraffic { - proxy.multicast_locator_list = self.default_multicast_locators.clone(); - proxy.unicast_locator_list = self.default_unicast_locators.clone(); + proxy + .multicast_locator_list + .clone_from(&self.default_multicast_locators); + proxy + .unicast_locator_list + .clone_from(&self.default_unicast_locators); } else { - proxy.multicast_locator_list = self.metatraffic_multicast_locators.clone(); - proxy.unicast_locator_list = self.metatraffic_unicast_locators.clone(); + proxy + .multicast_locator_list + .clone_from(&self.metatraffic_multicast_locators); + proxy + .unicast_locator_list + .clone_from(&self.metatraffic_unicast_locators); } proxy @@ -142,10 +150,14 @@ impl SpdpDiscoveredParticipantData { if is_metatraffic { // TODO: possible multicast addresses - proxy.unicast_locator_list = self.metatraffic_unicast_locators.clone(); + proxy + .unicast_locator_list + .clone_from(&self.metatraffic_unicast_locators); } else { // TODO: possible multicast addresses - proxy.unicast_locator_list = self.default_unicast_locators.clone(); + proxy + .unicast_locator_list + .clone_from(&self.default_unicast_locators); } proxy diff --git a/src/ros2/ros_node.rs b/src/ros2/ros_node.rs index 8d3aa201..cf1c2bf8 100644 --- a/src/ros2/ros_node.rs +++ b/src/ros2/ros_node.rs @@ -239,7 +239,7 @@ impl RosParticipantInner { let rpi = sample.value(); match self.external_nodes.get_mut(&rpi.guid()) { Some(rpi2) => { - *rpi2 = rpi.nodes().clone(); + rpi2.clone_from(rpi.nodes()); } None => { self.external_nodes.insert(rpi.guid(), rpi.nodes().clone()); diff --git a/src/rtps/rtps_reader_proxy.rs b/src/rtps/rtps_reader_proxy.rs index 27158555..c4d059f0 100644 --- a/src/rtps/rtps_reader_proxy.rs +++ b/src/rtps/rtps_reader_proxy.rs @@ -99,7 +99,9 @@ impl RtpsReaderProxy { let mut unicasts = update.unicast_locator_list.clone(); unicasts.retain(Self::not_loopback); self.unicast_locator_list = unicasts; - self.multicast_locator_list = update.multicast_locator_list.clone(); + self + .multicast_locator_list + .clone_from(&update.multicast_locator_list); } self.expects_in_line_qos = update.expects_in_line_qos; diff --git a/src/security/access_control/access_control_builtin/participant_access_control.rs b/src/security/access_control/access_control_builtin/participant_access_control.rs index 53e2f6c1..69c856c5 100644 --- a/src/security/access_control/access_control_builtin/participant_access_control.rs +++ b/src/security/access_control/access_control_builtin/participant_access_control.rs @@ -15,7 +15,8 @@ use crate::{ authentication::{ authentication_builtin::types::{ AUTHENTICATED_PEER_TOKEN_IDENTITY_CERTIFICATE_PROPERTY_NAME, - AUTHENTICATED_PEER_TOKEN_PERMISSIONS_DOCUMENT_PROPERTY_NAME, CERT_SN_PROPERTY_NAME, + AUTHENTICATED_PEER_TOKEN_PERMISSIONS_DOCUMENT_PROPERTY_NAME, + QOS_IDENTITY_CERTIFICATE_PROPERTY_NAME, }, *, }, @@ -67,7 +68,7 @@ impl AccessControlBuiltin { impl ParticipantAccessControl for AccessControlBuiltin { fn validate_local_permissions( &mut self, - auth_plugin: &dyn Authentication, + _auth_plugin: &dyn Authentication, identity_handle: IdentityHandle, domain_id: u16, participant_qos: &QosPolicies, @@ -116,17 +117,6 @@ impl ParticipantAccessControl for AccessControlBuiltin { .cloned() })?; - let subject_name: DistinguishedName = auth_plugin - .get_identity_token(identity_handle) - .and_then(|identity_token| { - identity_token - .data_holder - .get_property(CERT_SN_PROPERTY_NAME) - }) - .and_then(|name| { - DistinguishedName::parse(&name).map_err(|e| create_security_error!("{e:?}")) - })?; - let signed_permissions = participant_qos .get_property(QOS_PERMISSIONS_DOCUMENT_PROPERTY_NAME) .and_then(|permissions_uri| { @@ -148,12 +138,30 @@ impl ParticipantAccessControl for AccessControlBuiltin { // Check the subject name in the identity certificate matches the one from the // permissions document. + // First get the subject name from the certificate + let subject_name: DistinguishedName = participant_qos + .get_property(QOS_IDENTITY_CERTIFICATE_PROPERTY_NAME) + .and_then(|certificate_uri| { + read_uri(&certificate_uri).map_err(|conf_err| { + create_security_error!( + "Failed to read the identity certificate from {}: {:?}", + certificate_uri, + conf_err + ) + }) + }) + .and_then(|certificate_contents_pem| { + Certificate::from_pem(certificate_contents_pem).map_err(|e| create_security_error!("{e:?}")) + }) + .map(|cert| cert.subject_name().clone())?; + + // Then verify that we have permissions for this subject name if domain_participant_permissions .find_grant(&subject_name, &Utc::now()) .is_none() { Err(create_security_error!( - "No valid grants with the subject name {:?} found", + "The subject name '{}' from the ID certificate not found in the permissions document", subject_name ))?; } @@ -310,10 +318,14 @@ impl ParticipantAccessControl for AccessControlBuiltin { fn get_permissions_token(&self, handle: PermissionsHandle) -> SecurityResult { self .get_permissions_ca_certificate(&handle) - .map(|certificate| { + .map(|_certificate| { + // The CA subject name and algorithm identifier are optional properties + // according to the spec. We do not set values for them, since this has + // caused interoperability issues with FastDDS. In RustDDS we do not + // use them for anything, since they don't provide any additional security. BuiltinPermissionsToken { - permissions_ca_subject_name: Some(certificate.subject_name().clone()), - permissions_ca_algorithm: certificate.algorithm(), + permissions_ca_subject_name: None, + permissions_ca_algorithm: None, } .into() }) diff --git a/src/security/authentication/authentication_builtin/types.rs b/src/security/authentication/authentication_builtin/types.rs index cec9dc90..89269c74 100644 --- a/src/security/authentication/authentication_builtin/types.rs +++ b/src/security/authentication/authentication_builtin/types.rs @@ -24,11 +24,12 @@ const CERT_ALGO_PROPERTY_NAME: &str = "dds.cert.algo"; const CA_SN_PROPERTY_NAME: &str = "dds.ca.sn"; const CA_ALGO_PROPERTY_NAME: &str = "dds.ca.algo"; -// Accepted values for the algorithm properties in IdentityToken +// Algorithm identifiers used in IdentityToken and PermissionsToken const RSA_2048_ALGO_NAME: &str = "RSA-2048"; -pub(in crate::security) const RSA_2048_KEY_LENGTH: usize = 256; const EC_PRIME_ALGO_NAME: &str = "EC-prime256v1"; +pub(in crate::security) const RSA_2048_KEY_LENGTH: usize = 256; + #[derive(Debug, Clone, Copy)] pub(in crate::security) enum CertificateAlgorithm { RSA2048, diff --git a/src/security/certificate.rs b/src/security/certificate.rs index d7633afa..9e24df85 100644 --- a/src/security/certificate.rs +++ b/src/security/certificate.rs @@ -175,6 +175,7 @@ impl DistinguishedName { } pub fn serialize(&self) -> String { + // This returns the RFC 4514 Distinguished Name string representation self.0.to_string() } diff --git a/src/security/cryptographic/cryptographic_builtin/crypto_transform.rs b/src/security/cryptographic/cryptographic_builtin/crypto_transform.rs index 717a73ab..73976a7d 100644 --- a/src/security/cryptographic/cryptographic_builtin/crypto_transform.rs +++ b/src/security/cryptographic/cryptographic_builtin/crypto_transform.rs @@ -1,7 +1,7 @@ use bytes::Bytes; use enumflags2::BitFlags; use speedy::{Readable, Writable}; -use log::{info, warn}; +use log::{debug, warn}; use crate::{ create_security_error, @@ -734,7 +734,7 @@ impl CryptoTransform for CryptographicBuiltin { } SubmessageBody::Interpreter(interpreter_submessage) => { - info!( + debug!( "Interpreter submessage after successful submessage decryption. This is not in the \ specification, but we accept for compatibility as we also accept unprotected \ interpreter submessages." diff --git a/src/security/types.rs b/src/security/types.rs index 94eb8ad5..429efa1f 100644 --- a/src/security/types.rs +++ b/src/security/types.rs @@ -452,10 +452,6 @@ impl DataHolder { } } - pub(super) fn get_property(&self, property_name: &str) -> SecurityResult { - get_property(&self.properties, property_name) - } - pub(super) fn get_binary_property(&self, binary_property_name: &str) -> SecurityResult { get_binary_property(&self.binary_properties, binary_property_name) }