readme: add cert guide
This commit is contained in:
parent
99f92f84ba
commit
5e11fd664e
59
README.md
59
README.md
@ -69,7 +69,7 @@ Use `TlsSocketHandle` to gain access to a TLS Socket indirectly.
|
|||||||
```rust
|
```rust
|
||||||
// Prepare a socket set for TLS sockets
|
// Prepare a socket set for TLS sockets
|
||||||
let mut tls_socket_entries: [_; 1] = Default::default();
|
let mut tls_socket_entries: [_; 1] = Default::default();
|
||||||
let mut tls_socket_set = smoltcp_tls::set::TlsSocketSet::new(
|
let mut tls_socket_set = SaiTLS::set::TlsSocketSet::new(
|
||||||
&mut tls_socket_entries[..]
|
&mut tls_socket_entries[..]
|
||||||
);
|
);
|
||||||
// Use TLS socket set & handle to access TLS socket
|
// Use TLS socket set & handle to access TLS socket
|
||||||
@ -83,7 +83,7 @@ Use `TlsSocketHandle` to gain access to a TLS Socket indirectly.
|
|||||||
## Polling
|
## Polling
|
||||||
The `poll(..)` function substitutes the `EthernetInterface.poll(..)` function in smoltcp.
|
The `poll(..)` function substitutes the `EthernetInterface.poll(..)` function in smoltcp.
|
||||||
```rust
|
```rust
|
||||||
smoltcp_tls::poll(
|
SaiTLS::poll(
|
||||||
Some(&mut smoltcp_sockets), // Optional socket set from smoltcp
|
Some(&mut smoltcp_sockets), // Optional socket set from smoltcp
|
||||||
&mut tls_socket_set,
|
&mut tls_socket_set,
|
||||||
&mut ethernet_interface,
|
&mut ethernet_interface,
|
||||||
@ -92,5 +92,60 @@ The `poll(..)` function substitutes the `EthernetInterface.poll(..)` function in
|
|||||||
```
|
```
|
||||||
Sockets in either `smoltcp_sockets` or `tls_socket_set` will be updated.
|
Sockets in either `smoltcp_sockets` or `tls_socket_set` will be updated.
|
||||||
|
|
||||||
|
## Authentication on SaiTLS side
|
||||||
|
If necessary, SaiTLS will send X.509 certificate to the remote side, designated in the constructor. This requires X.509 certificate and its associated private key to be loaded onto the socket. A X.509 self-signed certificate and the signature private key can be generated by OpenSSL using the following command:
|
||||||
|
```
|
||||||
|
openssl req -x509 -newkey rsa:1024 -sha256 -nodes -keyout key.der -out cert.der -days 30 -outform DER
|
||||||
|
```
|
||||||
|
This will generate a self-signed certificate in DER format as `cert.der`, signed by an RSA key with 1024 bits as `key.der`. The certificate supplied to SaiTLS must be in DER format.
|
||||||
|
|
||||||
|
The `include_bytes!()` Rust macro can load the DER certificate as a binary slice.
|
||||||
|
Private/Secrete key needs to be instantiated by the corresponding RustCrypto/Dalek library. The following is an example of loading `cert.der` and `key.der` into the constructor of `TLSSocket`.
|
||||||
|
|
||||||
|
```Rust
|
||||||
|
// This line includes the certificate in DER format
|
||||||
|
const CERT: &'static [u8] = include_bytes!( `<path-to-certificate>` );
|
||||||
|
// These lines contains components of the RSA private key
|
||||||
|
const PRIVATE_KEY_MOD: &'static [u8] = ... ;
|
||||||
|
const PUBLIC_KEY_EXP: &'static [u8] = &[ 0x01, 0x00, 0x01 ];
|
||||||
|
const PRIVATE_KEY_EXP: &'static [u8] = ... ;
|
||||||
|
const CLIENT_PRIME_1: &'static [u8] = ... ;
|
||||||
|
const CLIENT_PRIME_2: &'static [u8] = ... ;
|
||||||
|
```
|
||||||
|
The exact values of these constants can be found by printing out the content using OpenSSL, such as the following command.
|
||||||
|
```
|
||||||
|
openssl rsa -in key.der -text
|
||||||
|
```
|
||||||
|
The private key can then be assembled as such:
|
||||||
|
```Rust
|
||||||
|
let mut prime_vec = alloc::vec::Vec::new();
|
||||||
|
prime_vec.push(rsa::BigUint::from_bytes_be(&CLIENT_PRIME_1));
|
||||||
|
prime_vec.push(rsa::BigUint::from_bytes_be(&CLIENT_PRIME_2));
|
||||||
|
|
||||||
|
let rsa_key = rsa::RSAPrivateKey::from_components(
|
||||||
|
rsa::BigUint::from_bytes_be(CLIENT_PRIVATE_KEY_MOD),
|
||||||
|
rsa::BigUint::from_bytes_be(CLIENT_PUBLIC_KEY_EXP),
|
||||||
|
rsa::BigUint::from_bytes_be(CLIENT_PRIVATE_KEY_EXP),
|
||||||
|
prime_vec
|
||||||
|
);
|
||||||
|
```
|
||||||
|
Finally, the private key and the certificate are loaded onto the socket.
|
||||||
|
```Rust
|
||||||
|
let mut tls_socket = TlsSocket::new(
|
||||||
|
tcp_socket,
|
||||||
|
&mut rng_struct,
|
||||||
|
Some((cert_private_key, alloc::vec![CLIENT_CERT]))
|
||||||
|
);
|
||||||
|
```
|
||||||
|
Loading more than 1 certificate (i.e. a certificate chain) is experimental. Use at your own risk!
|
||||||
|
|
||||||
|
Note that the remote side may not necessarily accept the self-signed certificate. It is entirely up to the remote side to accept or reject your provided certificate. Designation of trusted files might be helpful (e.g. the `--trustfile` option in Ncat).
|
||||||
|
|
||||||
## Feature `nal_tcp_stack`
|
## Feature `nal_tcp_stack`
|
||||||
Implements `TcpStack` in embedded-nal (v0.1.0) for `TlsSocket`. This disguises `TlsSocket` as just another TCP socket, potentially useful for implementating application layer protocols (e.g. MQTT in minimq).
|
Implements `TcpStack` in embedded-nal (v0.1.0) for `TlsSocket`. This disguises `TlsSocket` as just another TCP socket, potentially useful for implementating application layer protocols (e.g. MQTT in minimq).
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
```Rust
|
||||||
|
let tls_socket_set = SaiTLS::set::TlsSocketSet::new( .. );
|
||||||
|
let tls_stack = NetworkStack::new(tls_socket_set);
|
||||||
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user