Search in sources :

Example 1 with SecurityAlgorithm

use of org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm in project milo by eclipse.

the class AbstractX509IdentityValidator method validateX509Token.

@Override
protected T validateX509Token(Session session, X509IdentityToken token, UserTokenPolicy tokenPolicy, SignatureData tokenSignature) throws UaException {
    ByteString clientCertificateBs = token.getCertificateData();
    X509Certificate identityCertificate = CertificateUtil.decodeCertificate(clientCertificateBs.bytesOrEmpty());
    // verify the algorithm matches the one specified by the tokenPolicy or else the channel itself
    if (tokenPolicy.getSecurityPolicyUri() != null) {
        SecurityPolicy securityPolicy = SecurityPolicy.fromUri(tokenPolicy.getSecurityPolicyUri());
        if (!securityPolicy.getAsymmetricSignatureAlgorithm().getUri().equals(tokenSignature.getAlgorithm())) {
            throw new UaException(StatusCodes.Bad_SecurityChecksFailed, "algorithm in token signature did not match algorithm specified by token policy");
        }
    } else {
        SecurityPolicy securityPolicy = session.getSecurityConfiguration().getSecurityPolicy();
        if (!securityPolicy.getAsymmetricSignatureAlgorithm().getUri().equals(tokenSignature.getAlgorithm())) {
            throw new UaException(StatusCodes.Bad_SecurityChecksFailed, "algorithm in token signature did not match algorithm specified by secure channel");
        }
    }
    SecurityAlgorithm algorithm = SecurityAlgorithm.fromUri(tokenSignature.getAlgorithm());
    if (algorithm != SecurityAlgorithm.None) {
        verifySignature(session, tokenSignature, identityCertificate, algorithm);
    }
    return authenticateIdentityCertificateOrThrow(session, identityCertificate);
}
Also used : ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) UaException(org.eclipse.milo.opcua.stack.core.UaException) SecurityPolicy(org.eclipse.milo.opcua.stack.core.security.SecurityPolicy) SecurityAlgorithm(org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm) X509Certificate(java.security.cert.X509Certificate)

Example 2 with SecurityAlgorithm

use of org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm in project milo by eclipse.

the class SessionManager method getServerSignature.

private SignatureData getServerSignature(SecurityPolicy securityPolicy, KeyPair keyPair, ByteString clientNonce, ByteString clientCertificate) throws UaException {
    if (securityPolicy == SecurityPolicy.None) {
        return new SignatureData(null, null);
    } else {
        try {
            SecurityAlgorithm algorithm = securityPolicy.getAsymmetricSignatureAlgorithm();
            byte[] data = Bytes.concat(clientCertificate.bytes(), clientNonce.bytes());
            byte[] signature = SignatureUtil.sign(algorithm, keyPair.getPrivate(), ByteBuffer.wrap(data));
            return new SignatureData(algorithm.getUri(), ByteString.of(signature));
        } catch (UaRuntimeException e) {
            throw new UaException(StatusCodes.Bad_SecurityChecksFailed);
        }
    }
}
Also used : SignatureData(org.eclipse.milo.opcua.stack.core.types.structured.SignatureData) UaRuntimeException(org.eclipse.milo.opcua.stack.core.UaRuntimeException) UaException(org.eclipse.milo.opcua.stack.core.UaException) SecurityAlgorithm(org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm)

Example 3 with SecurityAlgorithm

use of org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm in project milo by eclipse.

the class SessionFsmFactory method buildClientSignature.

@SuppressWarnings("Duplicates")
private static SignatureData buildClientSignature(OpcUaClientConfig config, ByteString serverNonce) throws Exception {
    EndpointDescription endpoint = config.getEndpoint();
    SecurityPolicy securityPolicy = SecurityPolicy.fromUri(endpoint.getSecurityPolicyUri());
    if (securityPolicy == SecurityPolicy.None) {
        return new SignatureData(null, null);
    } else {
        SecurityAlgorithm signatureAlgorithm = securityPolicy.getAsymmetricSignatureAlgorithm();
        PrivateKey privateKey = config.getKeyPair().map(KeyPair::getPrivate).orElse(null);
        List<X509Certificate> serverCertificates = CertificateUtil.decodeCertificates(endpoint.getServerCertificate().bytesOrEmpty());
        // Signature data is serverCert + serverNonce signed with our private key.
        byte[] serverNonceBytes = serverNonce.bytesOrEmpty();
        byte[] serverCertificateBytes = serverCertificates.get(0).getEncoded();
        byte[] dataToSign = Bytes.concat(serverCertificateBytes, serverNonceBytes);
        byte[] signature = SignatureUtil.sign(signatureAlgorithm, privateKey, ByteBuffer.wrap(dataToSign));
        return new SignatureData(signatureAlgorithm.getUri(), ByteString.of(signature));
    }
}
Also used : SignatureData(org.eclipse.milo.opcua.stack.core.types.structured.SignatureData) PrivateKey(java.security.PrivateKey) SecurityPolicy(org.eclipse.milo.opcua.stack.core.security.SecurityPolicy) SecurityAlgorithm(org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm) EndpointDescription(org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription) X509Certificate(java.security.cert.X509Certificate)

Example 4 with SecurityAlgorithm

use of org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm in project milo by eclipse.

the class ChannelSecurity method generateKeyPair.

public static SecurityKeys generateKeyPair(SecureChannel channel, ByteString clientNonce, ByteString serverNonce) {
    SecurityAlgorithm keyDerivation = channel.getSecurityPolicy().getKeyDerivationAlgorithm();
    int signatureKeySize = channel.getSymmetricSignatureKeySize();
    int encryptionKeySize = channel.getSymmetricEncryptionKeySize();
    int cipherTextBlockSize = channel.getSymmetricBlockSize();
    assert (clientNonce != null);
    assert (serverNonce != null);
    byte[] clientSignatureKey = (keyDerivation == SecurityAlgorithm.PSha1) ? PShaUtil.createPSha1Key(serverNonce.bytes(), clientNonce.bytes(), 0, signatureKeySize) : PShaUtil.createPSha256Key(serverNonce.bytes(), clientNonce.bytes(), 0, signatureKeySize);
    byte[] clientEncryptionKey = (keyDerivation == SecurityAlgorithm.PSha1) ? PShaUtil.createPSha1Key(serverNonce.bytes(), clientNonce.bytes(), signatureKeySize, encryptionKeySize) : PShaUtil.createPSha256Key(serverNonce.bytes(), clientNonce.bytes(), signatureKeySize, encryptionKeySize);
    byte[] clientInitializationVector = (keyDerivation == SecurityAlgorithm.PSha1) ? PShaUtil.createPSha1Key(serverNonce.bytes(), clientNonce.bytes(), signatureKeySize + encryptionKeySize, cipherTextBlockSize) : PShaUtil.createPSha256Key(serverNonce.bytes(), clientNonce.bytes(), signatureKeySize + encryptionKeySize, cipherTextBlockSize);
    byte[] serverSignatureKey = (keyDerivation == SecurityAlgorithm.PSha1) ? PShaUtil.createPSha1Key(clientNonce.bytes(), serverNonce.bytes(), 0, signatureKeySize) : PShaUtil.createPSha256Key(clientNonce.bytes(), serverNonce.bytes(), 0, signatureKeySize);
    byte[] serverEncryptionKey = (keyDerivation == SecurityAlgorithm.PSha1) ? PShaUtil.createPSha1Key(clientNonce.bytes(), serverNonce.bytes(), signatureKeySize, encryptionKeySize) : PShaUtil.createPSha256Key(clientNonce.bytes(), serverNonce.bytes(), signatureKeySize, encryptionKeySize);
    byte[] serverInitializationVector = (keyDerivation == SecurityAlgorithm.PSha1) ? PShaUtil.createPSha1Key(clientNonce.bytes(), serverNonce.bytes(), signatureKeySize + encryptionKeySize, cipherTextBlockSize) : PShaUtil.createPSha256Key(clientNonce.bytes(), serverNonce.bytes(), signatureKeySize + encryptionKeySize, cipherTextBlockSize);
    return new SecurityKeys(new SecretKeys(clientSignatureKey, clientEncryptionKey, clientInitializationVector), new SecretKeys(serverSignatureKey, serverEncryptionKey, serverInitializationVector));
}
Also used : SecurityAlgorithm(org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm)

Example 5 with SecurityAlgorithm

use of org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm in project milo by eclipse.

the class AbstractUsernameIdentityValidator method validateUsernameToken.

@Override
protected T validateUsernameToken(Session session, UserNameIdentityToken token, UserTokenPolicy tokenPolicy, SignatureData tokenSignature) throws UaException {
    String username = token.getUserName();
    ByteString lastNonce = session.getLastNonce();
    int lastNonceLength = lastNonce.length();
    if (username == null || username.isEmpty()) {
        throw new UaException(StatusCodes.Bad_IdentityTokenInvalid);
    }
    SecurityAlgorithm algorithm;
    String algorithmUri = token.getEncryptionAlgorithm();
    if (algorithmUri == null || algorithmUri.isEmpty()) {
        SecurityPolicy securityPolicy = session.getSecurityConfiguration().getSecurityPolicy();
        algorithm = securityPolicy.getAsymmetricEncryptionAlgorithm();
    } else {
        try {
            algorithm = SecurityAlgorithm.fromUri(algorithmUri);
        } catch (UaException e) {
            throw new UaException(StatusCodes.Bad_IdentityTokenInvalid);
        }
        if (algorithm != SecurityAlgorithm.Rsa15 && algorithm != SecurityAlgorithm.RsaOaepSha1 && algorithm != SecurityAlgorithm.RsaOaepSha256) {
            throw new UaException(StatusCodes.Bad_IdentityTokenInvalid);
        }
    }
    byte[] tokenBytes = token.getPassword().bytesOrEmpty();
    if (algorithm != SecurityAlgorithm.None) {
        byte[] plainTextBytes = decryptTokenData(session, algorithm, tokenBytes);
        // @formatter:off
        long length = ((plainTextBytes[3] & 0xFFL) << 24) | ((plainTextBytes[2] & 0xFFL) << 16) | ((plainTextBytes[1] & 0xFFL) << 8) | (plainTextBytes[0] & 0xFFL);
        if (length > plainTextBytes.length - 4) {
            throw new UaException(StatusCodes.Bad_IdentityTokenInvalid, "invalid token data");
        }
        int passwordLength = (int) length - lastNonceLength;
        if (passwordLength < 0) {
            throw new UaException(StatusCodes.Bad_IdentityTokenInvalid, "invalid password length");
        }
        if (passwordLength > session.getServer().getConfig().getLimits().getMaxPasswordLength().longValue()) {
            throw new UaException(StatusCodes.Bad_EncodingLimitsExceeded, "password length exceeds limits");
        }
        byte[] passwordBytes = new byte[passwordLength];
        byte[] nonceBytes = new byte[lastNonceLength];
        System.arraycopy(plainTextBytes, 4, passwordBytes, 0, passwordBytes.length);
        System.arraycopy(plainTextBytes, 4 + passwordBytes.length, nonceBytes, 0, lastNonceLength);
        if (MessageDigest.isEqual(lastNonce.bytes(), nonceBytes)) {
            String password = new String(passwordBytes, StandardCharsets.UTF_8);
            return authenticateUsernameOrThrow(session, username, password);
        } else {
            throw new UaException(StatusCodes.Bad_UserAccessDenied);
        }
    } else {
        String password = new String(tokenBytes, StandardCharsets.UTF_8);
        return authenticateUsernameOrThrow(session, username, password);
    }
}
Also used : ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) UaException(org.eclipse.milo.opcua.stack.core.UaException) SecurityPolicy(org.eclipse.milo.opcua.stack.core.security.SecurityPolicy) SecurityAlgorithm(org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString)

Aggregations

SecurityAlgorithm (org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm)5 UaException (org.eclipse.milo.opcua.stack.core.UaException)3 SecurityPolicy (org.eclipse.milo.opcua.stack.core.security.SecurityPolicy)3 X509Certificate (java.security.cert.X509Certificate)2 ByteString (org.eclipse.milo.opcua.stack.core.types.builtin.ByteString)2 SignatureData (org.eclipse.milo.opcua.stack.core.types.structured.SignatureData)2 PrivateKey (java.security.PrivateKey)1 UaRuntimeException (org.eclipse.milo.opcua.stack.core.UaRuntimeException)1 EndpointDescription (org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription)1