You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by ld...@apache.org on 2024/02/12 09:26:00 UTC

(plc4x) 11/12: Add Basic256Sha256 support

This is an automated email from the ASF dual-hosted git repository.

ldywicki pushed a commit to branch pg/security-policy
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit e67759379796df99e8f57400407eceeabd551eff
Author: PatrykGala <pa...@gmail.com>
AuthorDate: Sat Sep 16 21:27:20 2023 +0200

    Add Basic256Sha256 support
---
 .../opcua/context/AsymmetricEncryptionHandler.java |  2 +-
 .../java/opcua/context/EncryptionHandler.java      |  4 +-
 .../plc4x/java/opcua/context/SecureChannel.java    |  4 --
 .../opcua/context/SymmetricEncryptionHandler.java  | 13 +++---
 .../plc4x/java/opcua/security/SecurityPolicy.java  | 54 +++++++++++++++++-----
 .../plc4x/java/opcua/security/SymmetricKeys.java   |  4 +-
 .../plc4x/java/opcua/OpcuaPlcDriverTest.java       |  3 +-
 7 files changed, 56 insertions(+), 28 deletions(-)

diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/AsymmetricEncryptionHandler.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/AsymmetricEncryptionHandler.java
index 1dc72f631f..5fea2ab9fe 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/AsymmetricEncryptionHandler.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/AsymmetricEncryptionHandler.java
@@ -47,7 +47,7 @@ public class AsymmetricEncryptionHandler {
         int beforeBodyLength = unencryptedLength - messageLength; // message header, security header, sequence header
 
         int cipherTextBlockSize = (getAsymmetricKeyLength(serverCertificate) + 7) / 8;
-        int plainTextBlockSize = (getAsymmetricKeyLength(serverCertificate) + 7) / 8 - 11;
+        int plainTextBlockSize = (getAsymmetricKeyLength(serverCertificate) + 7) / 8 - policy.getAsymmetricPlainBlock();
         int signatureSize = (getAsymmetricKeyLength(clientCertificate) + 7) / 8;
 
 
diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/EncryptionHandler.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/EncryptionHandler.java
index 394abdb864..1c25f410ca 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/EncryptionHandler.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/EncryptionHandler.java
@@ -82,6 +82,7 @@ public class EncryptionHandler {
         switch (securitypolicy) {
             case NONE:
                 return new ReadBufferByteBased(message, LITTLE_ENDIAN);
+            case Basic256Sha256:
             case Basic128Rsa15:
                 if (pdu instanceof OpcuaOpenRequest) {
                     return asymmetricEncryptionHandler.encodeMessage(pdu, message);
@@ -98,7 +99,7 @@ public class EncryptionHandler {
         byte[] cert = Try.of(() -> serverCertificate.getEncoded()).getOrElse(new byte[0]);
         byte[] bytes = Bytes.concat(cert, lastServerNonce);
         byte[] signed = asymmetricEncryptionHandler.sign(bytes);
-        return new SignatureData(new PascalString("http://www.w3.org/2000/09/xmldsig#rsa-sha1"), new PascalByteString(signed.length, signed));
+        return new SignatureData(new PascalString(securitypolicy.getAsymmetricSignatureAlgorithm().getUri()), new PascalByteString(signed.length, signed));
     }
 
     public OpcuaAPU decodeMessage(OpcuaAPU pdu) {
@@ -108,6 +109,7 @@ public class EncryptionHandler {
             case NONE:
                 return pdu;
             case Basic128Rsa15:
+            case Basic256Sha256:
                 if (pdu.getMessage() instanceof OpcuaOpenResponse) {
                     return asymmetricEncryptionHandler.decodeMessage(pdu);
                 } else {
diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SecureChannel.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SecureChannel.java
index 87e61032de..ea208b0b24 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SecureChannel.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SecureChannel.java
@@ -883,10 +883,6 @@ public class SecureChannel {
 
                             try {
                                 MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
-                                Try<Boolean> of = Try.of(() -> {
-                                    configuration.openKeyStore();
-                                    return true;
-                                });
                                 byte[] digest = messageDigest.digest(this.configuration.getSenderCertificate());
                                 this.configuration.setThumbprint(new PascalByteString(digest.length, digest));
                             } catch (Exception e) {
diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SymmetricEncryptionHandler.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SymmetricEncryptionHandler.java
index ae5bcc6017..d652eed511 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SymmetricEncryptionHandler.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SymmetricEncryptionHandler.java
@@ -5,6 +5,7 @@ import org.apache.plc4x.java.opcua.readwrite.OpcuaAPU;
 import org.apache.plc4x.java.opcua.readwrite.OpcuaMessageResponse;
 import org.apache.plc4x.java.opcua.security.SecurityPolicy;
 import org.apache.plc4x.java.opcua.security.SecurityPolicy.EncryptionAlgorithm;
+import org.apache.plc4x.java.opcua.security.SecurityPolicy.MacSignatureAlgorithm;
 import org.apache.plc4x.java.opcua.security.SymmetricKeys;
 import org.apache.plc4x.java.spi.generation.*;
 
@@ -17,9 +18,6 @@ import java.nio.ByteBuffer;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.cert.Certificate;
-import java.security.interfaces.RSAPublicKey;
 
 
 public class SymmetricEncryptionHandler {
@@ -51,9 +49,9 @@ public class SymmetricEncryptionHandler {
 
         int beforeBodyLength = unencryptedLength - messageLength; // message header, security header, sequence header
 
-        int cipherTextBlockSize = 16; // different for aes
+        int cipherTextBlockSize = 16;
         int plainTextBlockSize = 16;
-        int signatureSize = 20;
+        int signatureSize = policy.getSymmetricSignatureAlgorithm().getSymmetricSignatureSize();
 
 
         int maxChunkSize = 8196;
@@ -187,8 +185,9 @@ public class SymmetricEncryptionHandler {
 
     public byte[] sign(byte[] data, SymmetricKeys.Keys symmetricKeys) {
         try {
-            Mac signature = policy.getSymmetricSignatureAlgorithm().getSignature();
-            signature.init(new SecretKeySpec(symmetricKeys.getSignatureKey(), "HmacSHA1"));
+            MacSignatureAlgorithm algorithm = policy.getSymmetricSignatureAlgorithm();
+            Mac signature = algorithm.getSignature();
+            signature.init(new SecretKeySpec(symmetricKeys.getSignatureKey(), algorithm.getName()));
             signature.update(data);
             return signature.doFinal();
         } catch (Exception e) {
diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/security/SecurityPolicy.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/security/SecurityPolicy.java
index 9ddd06e588..37aca76ac9 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/security/SecurityPolicy.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/security/SecurityPolicy.java
@@ -9,16 +9,23 @@ import java.util.Arrays;
 
 public enum SecurityPolicy {
     NONE("http://opcfoundation.org/UA/SecurityPolicy#None",
-        new MacSignatureAlgorithm(""),
+        new MacSignatureAlgorithm("", 0, 32),
         new EncryptionAlgorithm(""),
-        new SignatureAlgorithm(""),
-        new EncryptionAlgorithm("")),
+        new SignatureAlgorithm("", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"),
+        new EncryptionAlgorithm(""), 1),
+
     Basic128Rsa15("http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15",
-        new MacSignatureAlgorithm("HmacSHA1"),
+        new MacSignatureAlgorithm("HmacSHA1", 20, 16),
+        new EncryptionAlgorithm("AES/CBC/NoPadding"),
+        new SignatureAlgorithm("SHA1withRSA", "http://www.w3.org/2000/09/xmldsig#rsa-sha1"),
+        new EncryptionAlgorithm("RSA/ECB/PKCS1Padding"),
+        11),
+    Basic256Sha256("http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256",
+        new MacSignatureAlgorithm("HmacSHA256", 32, 32),
         new EncryptionAlgorithm("AES/CBC/NoPadding"),
-        new SignatureAlgorithm("SHA1withRSA"),
-        new EncryptionAlgorithm("RSA/ECB/PKCS1Padding")
-    );
+        new SignatureAlgorithm("SHA256withRSA", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"),
+        new EncryptionAlgorithm("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"),
+        42);
 
 
     private final String securityPolicyUri;
@@ -28,18 +35,20 @@ public enum SecurityPolicy {
     private final EncryptionAlgorithm symmetricEncryptionAlgorithm;
     private final SignatureAlgorithm asymmetricSignatureAlgorithm;
     private final EncryptionAlgorithm asymmetricEncryptionAlgorithm;
-
+    private final int asymmetricPlainBlock;
 
     SecurityPolicy(String securityPolicyUri,
                    MacSignatureAlgorithm symmetricSignatureAlgorithm,
                    EncryptionAlgorithm symmetricEncryptionAlgorithm,
                    SignatureAlgorithm asymmetricSignatureAlgorithm,
-                   EncryptionAlgorithm asymmetricEncryptionAlgorithm) {
+                   EncryptionAlgorithm asymmetricEncryptionAlgorithm,
+                   int asymmetricPlainBlock) {
         this.securityPolicyUri = securityPolicyUri;
         this.symmetricSignatureAlgorithm = symmetricSignatureAlgorithm;
         this.symmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm;
         this.asymmetricSignatureAlgorithm = asymmetricSignatureAlgorithm;
         this.asymmetricEncryptionAlgorithm = asymmetricEncryptionAlgorithm;
+        this.asymmetricPlainBlock = asymmetricPlainBlock;
     }
 
     public static SecurityPolicy findByName(String securityPolicy) {
@@ -69,13 +78,21 @@ public enum SecurityPolicy {
         return symmetricEncryptionAlgorithm;
     }
 
+    public int getAsymmetricPlainBlock() {
+        return asymmetricPlainBlock;
+    }
+
     public static class MacSignatureAlgorithm {
 
 
         private final String name;
+        private final int symmetricSignatureSize;
+        private final int keySize;
 
-        MacSignatureAlgorithm(String name) {
+        MacSignatureAlgorithm(String name, int symmetricSignatureSize, int keySize) {
             this.name = name;
+            this.symmetricSignatureSize = symmetricSignatureSize;
+            this.keySize = keySize;
         }
 
         public Mac getSignature() throws NoSuchAlgorithmException {
@@ -85,19 +102,33 @@ public enum SecurityPolicy {
         public String getName() {
             return name;
         }
+
+        public int getSymmetricSignatureSize() {
+            return symmetricSignatureSize;
+        }
+
+        public int getKeySize() {
+            return keySize;
+        }
     }
 
 
     public static class SignatureAlgorithm {
         private final String name;
+        private String uri;
 
-        SignatureAlgorithm(String name) {
+        SignatureAlgorithm(String name, String uri) {
             this.name = name;
+            this.uri = uri;
         }
 
         public Signature getSignature() throws NoSuchAlgorithmException {
             return Signature.getInstance(name);
         }
+
+        public String getUri() {
+            return uri;
+        }
     }
 
     public static class EncryptionAlgorithm {
@@ -110,7 +141,6 @@ public enum SecurityPolicy {
         public Cipher getCipher() throws NoSuchPaddingException, NoSuchAlgorithmException {
             return Cipher.getInstance(name);
         }
-
     }
 
 
diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/security/SymmetricKeys.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/security/SymmetricKeys.java
index 1206e46ac7..f0457128b0 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/security/SymmetricKeys.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/security/SymmetricKeys.java
@@ -26,8 +26,8 @@ public class SymmetricKeys {
     }
 
     public static SymmetricKeys generateKeyPair(byte[] clientNonce, byte[] serverNonce, MacSignatureAlgorithm policy) {
-        int signatureKeySize = 16;// different for aes
-        int encryptionKeySize = 16;
+        int signatureKeySize = policy.getKeySize();
+        int encryptionKeySize = policy.getKeySize();
         int cipherTextBlockSize = 16;
 
 
diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java
index 8ad20bb3a8..56ce6b5b1d 100644
--- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java
+++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java
@@ -466,6 +466,7 @@ public class OpcuaPlcDriverTest {
         switch (policy) {
             case NONE:
                 return tcpConnectionAddress;
+            case Basic256Sha256:
             case Basic128Rsa15:
                 Path securityTempDir = Paths.get(System.getProperty("java.io.tmpdir"), "server");
                 String keyStoreFile = securityTempDir.resolve("security").resolve("example-server.pfx").toAbsolutePath().toString();
@@ -475,7 +476,7 @@ public class OpcuaPlcDriverTest {
                         new Tuple2<>("keyStoreFile", keyStoreFile),
                         new Tuple2<>("certDirectory", certDirectory),
                         new Tuple2<>("keyStorePassword", "password"),
-                        new Tuple2<>("securityPolicy", SecurityPolicy.Basic128Rsa15)
+                        new Tuple2<>("securityPolicy", policy)
                     )
                     .map(tuple -> tuple._1() + "=" + tuple._2())
                     .collect(Collectors.joining(paramDivider));