locka99 / opcua

A client and server implementation of the OPC UA specification written in Rust
Mozilla Public License 2.0
475 stars 128 forks source link

How does the client properly use the certificate and key to connect to the server #300

Closed LongZoz closed 7 months ago

LongZoz commented 7 months ago

The server I use: The prosys opc ua simulation server and the simple-server of the code can establish the server normally, and the client can connect to the server and read and write data normally using anonymous login and account and password login. Now I want to verify the certificate key login, but I find that there are always problems. I hope I can get help. The simple-server of the code uses the default server.conf. The server configuration of the upper computer software is as follows: image image

I used the client to connect to the two servers respectively, but failed, respectively reported the following error: Software Server: “ERROR opcua::client::client Got an error while creating the default session - BadTimeout” Code server: ‘ERROR opcua::client::session::session session:2 Server's certificate was rejected ERROR opcua::client::client Got an error while creating the default session - BadSecurityChecksFailed’

This is my client code:

const DEFAULT_URL: &str = "opc.tcp://127.0.0.1:53530/OPCUA/SimulationServer";

fn main() -> Result<(), ()> {
    // Read command line arguments
    let args = Args::parse_args().map_err(|_| Args::usage())?;
    if args.help {
        Args::usage();
    } else {
        // Optional - enable OPC UA logging
        opcua::console_logging::init();
        // Make the client configuration   
        let mut client = ClientBuilder::new()
            .application_name("Rust Simple Client")
            .application_uri("urn:SimpleClient")
            .product_uri("urn:SimpleClient")
            .trust_server_certs(true)   
            .create_sample_keypair(true)
            .session_retry_limit(3)
            .client()
            .unwrap();
            println!("client ok");
         if let Ok(session) = client.connect_to_endpoint(
            (
                // args.url.as_ref(),
                DEFAULT_URL,
                SecurityPolicy::Aes256Sha256RsaPss.to_str(),
                MessageSecurityMode::SignAndEncrypt,  //   (none-->none;   sign/signandencrypt-->Aes128Sha256RsaOaep,Aes256Sha256RsaPss,Basic256Sha256,Basic256,Basic128Rsa15)
                UserTokenPolicy{
                    policy_id: UAString {
                        value: Some(
                            "0".to_string(),
                        ),
                    },
                    token_type: Certificate,
                    issued_token_type: UAString { 
                        value: Some("()".to_string()),
                    },
                    issuer_endpoint_url: UAString {
                        value: Some("()".to_string()),
                    },
                    security_policy_uri: UAString { 
                        value: Some("()".to_string()),
                    },
                }, 
            ),
            IdentityToken::X509("./pki/own/cert.der".into(), "./pki/private/private.pem".into()),
        ) {
            println!("Connected to endpoint {}", args.url);

            if let Err(result) = subscribe_to_variables(session.clone(), 2) {
                println!(
                    "ERROR: Got an error while subscribing to variables - {}",
                    result
                );
            } else {
                // Loops forever. The publish thread will call the callback with changes on the variables
                let _ = Session::run(session);
            }

        }
    }
    Ok(())
}
LongZoz commented 7 months ago

I further found some problems in the connection between my client and the server. First, I used prosys opcua software as the server. After the client ran, the server trusted the client, but the client did not generate the certificate of trusting the server (the trust server was selected in the code). The second is simple-server as a server, server.conf:trust_client_certs: true: In this case, the server trusts the client. After the client runs, the server correctly generates the certificate of the trusted client. However, the client has a problem and the generated server certificate is in both the trusted path and the rejected path. prosys server : image simple-server: image I don't know how to solve this problem. I hope you can help me @locka99

LongZoz commented 7 months ago

My client key certificate access problem has been solved, I found that the group of files simple-client/identity/sample-x509.der can be successfully connected under pki. Finally, it is found that the.der file generated by the client needs to be placed under simple-server/user on the server, which is probably because I am not very clear about the mechanism of opcua certificate