pub struct KeygenCtx { /* private fields */ }Expand description
Context for generating asymmetric key pairs (EVP_PKEY_CTX in keygen mode).
Implementations§
Source§impl KeygenCtx
impl KeygenCtx
Sourcepub fn new(name: &CStr) -> Result<Self, ErrorStack>
pub fn new(name: &CStr) -> Result<Self, ErrorStack>
Create a keygen context for the named algorithm.
Common names: c"RSA", c"EC", c"ED25519", c"X25519".
§Errors
Examples found in repository?
9fn main() -> Result<(), Box<dyn std::error::Error>> {
10 // ── Generate key and self-signed certificate ───────────────────────────────
11
12 let mut kgen = KeygenCtx::new(c"ED25519")?;
13 let priv_key = kgen.generate()?;
14 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
15
16 let mut name = X509NameOwned::new()?;
17 name.add_entry_by_txt(c"CN", b"example.com")?;
18
19 let cert = X509Builder::new()?
20 .set_version(2)?
21 .set_serial_number(1)?
22 .set_not_before_offset(0)?
23 .set_not_after_offset(365 * 86400)?
24 .set_subject_name(&name)?
25 .set_issuer_name(&name)?
26 .set_public_key(&pub_key)?
27 .sign(&priv_key, None)?
28 .build();
29
30 // ── Create the PKCS#12 bundle ─────────────────────────────────────────────
31
32 let password = "correct horse battery staple";
33 let p12 = Pkcs12::create(password, "example.com", &priv_key, &cert, &[])?;
34 let der = p12.to_der()?;
35 println!("PKCS#12 bundle: {} bytes", der.len());
36
37 // ── Parse it back ─────────────────────────────────────────────────────────
38
39 let loaded = Pkcs12::from_der(&der)?;
40 let (recovered_key, recovered_cert, ca_chain) = loaded.parse(password)?;
41
42 println!(
43 "Recovered key algorithm: Ed25519 = {}",
44 recovered_key.is_a(c"ED25519")
45 );
46 if let Some(subject) = recovered_cert.subject_name().to_string() {
47 println!("Recovered cert subject: {subject}");
48 }
49 println!("CA chain length: {}", ca_chain.len());
50
51 // Public keys must match.
52 assert!(priv_key.public_eq(&recovered_key));
53 assert_eq!(cert.to_der()?, recovered_cert.to_der()?);
54 println!("Key and certificate match original: OK");
55
56 // ── DER round-trip ────────────────────────────────────────────────────────
57
58 let der2 = loaded.to_der()?;
59 assert_eq!(der, der2);
60 println!("DER round-trip: OK");
61
62 Ok(())
63}More examples
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9 // ── Generate an Ed25519 key pair ──────────────────────────────────────────
10
11 let mut kgen = KeygenCtx::new(c"ED25519")?;
12 let priv_key = kgen.generate()?;
13 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
14
15 // ── Build a self-signed certificate ──────────────────────────────────────
16
17 let mut name = X509NameOwned::new()?;
18 name.add_entry_by_txt(c"CN", b"example.com")?;
19 name.add_entry_by_txt(c"O", b"Example Org")?;
20 name.add_entry_by_txt(c"C", b"US")?;
21
22 let cert = X509Builder::new()?
23 .set_version(2)? // X.509 v3
24 .set_serial_number(42)?
25 .set_not_before_offset(0)? // valid from now
26 .set_not_after_offset(365 * 86400)? // valid for 1 year
27 .set_subject_name(&name)?
28 .set_issuer_name(&name)? // self-signed
29 .set_public_key(&pub_key)?
30 .sign(&priv_key, None)? // Ed25519 (no explicit digest needed)
31 .build();
32
33 // ── Inspect fields ────────────────────────────────────────────────────────
34
35 if let Some(subject) = cert.subject_name().to_string() {
36 println!("Subject: {subject}");
37 }
38 if let Some(issuer) = cert.issuer_name().to_string() {
39 println!("Issuer: {issuer}");
40 }
41 if let Some(serial) = cert.serial_number() {
42 println!("Serial: {serial}");
43 }
44 if let Some(nb) = cert.not_before_str() {
45 println!("NotBefore: {nb}");
46 }
47 if let Some(na) = cert.not_after_str() {
48 println!("NotAfter: {na}");
49 }
50 println!("Valid now: {}", cert.is_valid_now());
51 println!("Self-signed: {}", cert.is_self_signed());
52
53 // ── DER round-trip ────────────────────────────────────────────────────────
54
55 let der = cert.to_der()?;
56 let reloaded = native_ossl::x509::X509::from_der(&der)?;
57 assert_eq!(cert.to_der()?, reloaded.to_der()?);
58 println!("DER round-trip: OK ({} bytes)", der.len());
59
60 // ── PEM output ────────────────────────────────────────────────────────────
61
62 let pem = cert.to_pem()?;
63 println!("\nPEM certificate:\n{}", std::str::from_utf8(&pem)?);
64
65 // ── Signature verification ────────────────────────────────────────────────
66
67 cert.verify(&pub_key)?;
68 println!("Signature verification: OK");
69
70 Ok(())
71}14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 // ── Key pair and self-signed certificate ───────────────────────────────────
16
17 let mut kgen = KeygenCtx::new(c"ED25519")?;
18 let priv_key = kgen.generate()?;
19 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
20
21 let mut name = X509NameOwned::new()?;
22 name.add_entry_by_txt(c"CN", b"localhost")?;
23
24 let cert = X509Builder::new()?
25 .set_version(2)?
26 .set_serial_number(1)?
27 .set_not_before_offset(0)?
28 .set_not_after_offset(86400)?
29 .set_subject_name(&name)?
30 .set_issuer_name(&name)?
31 .set_public_key(&pub_key)?
32 .sign(&priv_key, None)?
33 .build();
34
35 // ── Server context ─────────────────────────────────────────────────────────
36
37 let server_ctx = SslCtx::new_server()?;
38 server_ctx.set_min_proto_version(TlsVersion::Tls13)?;
39 server_ctx.use_certificate(&cert)?;
40 server_ctx.use_private_key(&priv_key)?;
41 server_ctx.check_private_key()?;
42
43 // ── Client context ─────────────────────────────────────────────────────────
44
45 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 // Skip certificate verification for this self-signed example.
48 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 // ── SSL objects ────────────────────────────────────────────────────────────
51
52 let mut client = client_ctx.new_ssl()?;
53 let mut server = server_ctx.new_ssl()?;
54
55 client.set_connect_state();
56 client.set_hostname(c"localhost")?;
57 server.set_accept_state();
58
59 // ── In-process BIO pair ────────────────────────────────────────────────────
60 // Data written to client_bio is readable from server_bio and vice-versa.
61
62 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 // ── Drive the handshake ────────────────────────────────────────────────────
67 // Alternate between client and server until both report success.
68
69 let mut client_done = false;
70 let mut server_done = false;
71
72 for step in 0..20 {
73 if !client_done {
74 match client.connect() {
75 Ok(()) => {
76 client_done = true;
77 println!("Client handshake done at step {step}");
78 }
79 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
80 Err(e) => return Err(format!("client error: {e}").into()),
81 }
82 }
83 if !server_done {
84 match server.accept() {
85 Ok(()) => {
86 server_done = true;
87 println!("Server handshake done at step {step}");
88 }
89 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
90 Err(e) => return Err(format!("server error: {e}").into()),
91 }
92 }
93 if client_done && server_done {
94 break;
95 }
96 }
97 assert!(client_done && server_done, "handshake did not complete");
98
99 // ── Inspect the peer certificate on the client ─────────────────────────────
100
101 if let Some(peer_cert) = client.peer_certificate() {
102 if let Some(subject) = peer_cert.subject_name().to_string() {
103 println!("Server cert subject: {subject}");
104 }
105 }
106
107 // ── Application data exchange ──────────────────────────────────────────────
108
109 let request = b"GET / HTTP/1.0\r\n\r\n";
110 let response = b"HTTP/1.0 200 OK\r\n\r\nHello, TLS!";
111
112 let written = client.write(request)?;
113 assert_eq!(written, request.len());
114
115 let mut rbuf = [0u8; 64];
116 let n = server.read(&mut rbuf)?;
117 assert_eq!(&rbuf[..n], request);
118 println!("Server received: {:?}", std::str::from_utf8(&rbuf[..n])?);
119
120 let written = server.write(response)?;
121 assert_eq!(written, response.len());
122
123 let n = client.read(&mut rbuf)?;
124 assert_eq!(&rbuf[..n], response);
125 println!("Client received: {:?}", std::str::from_utf8(&rbuf[..n])?);
126
127 println!("In-process TLS 1.3 round-trip: OK");
128
129 Ok(())
130}Sourcepub fn set_params(&mut self, params: &Params<'_>) -> Result<(), ErrorStack>
pub fn set_params(&mut self, params: &Params<'_>) -> Result<(), ErrorStack>
Configure parameters before calling generate.
§Errors
Sourcepub fn get_params(&self, params: &mut Params<'_>) -> Result<(), ErrorStack>
pub fn get_params(&self, params: &mut Params<'_>) -> Result<(), ErrorStack>
Retrieve parameter values from this keygen context.
Build a Params with placeholder values for the
keys you want, call this method, then read back with params.get_*.
Useful for reading algorithm-negotiated parameters after keygen initialisation (e.g. security strength, EC group name, RSA modulus size).
§Errors
Returns Err if EVP_PKEY_CTX_get_params fails.
Sourcepub fn security_bits(&self) -> Result<u32, ErrorStack>
pub fn security_bits(&self) -> Result<u32, ErrorStack>
Return the security strength of the key operation in bits.
Available after keygen initialisation; reads OSSL_PKEY_PARAM_SECURITY_BITS
("security-bits").
§Errors
Returns Err if the context does not support this parameter or is not
sufficiently initialised.
Sourcepub fn generate(&mut self) -> Result<Pkey<Private>, ErrorStack>
pub fn generate(&mut self) -> Result<Pkey<Private>, ErrorStack>
Generate a key pair.
§Errors
Examples found in repository?
9fn main() -> Result<(), Box<dyn std::error::Error>> {
10 // ── Generate key and self-signed certificate ───────────────────────────────
11
12 let mut kgen = KeygenCtx::new(c"ED25519")?;
13 let priv_key = kgen.generate()?;
14 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
15
16 let mut name = X509NameOwned::new()?;
17 name.add_entry_by_txt(c"CN", b"example.com")?;
18
19 let cert = X509Builder::new()?
20 .set_version(2)?
21 .set_serial_number(1)?
22 .set_not_before_offset(0)?
23 .set_not_after_offset(365 * 86400)?
24 .set_subject_name(&name)?
25 .set_issuer_name(&name)?
26 .set_public_key(&pub_key)?
27 .sign(&priv_key, None)?
28 .build();
29
30 // ── Create the PKCS#12 bundle ─────────────────────────────────────────────
31
32 let password = "correct horse battery staple";
33 let p12 = Pkcs12::create(password, "example.com", &priv_key, &cert, &[])?;
34 let der = p12.to_der()?;
35 println!("PKCS#12 bundle: {} bytes", der.len());
36
37 // ── Parse it back ─────────────────────────────────────────────────────────
38
39 let loaded = Pkcs12::from_der(&der)?;
40 let (recovered_key, recovered_cert, ca_chain) = loaded.parse(password)?;
41
42 println!(
43 "Recovered key algorithm: Ed25519 = {}",
44 recovered_key.is_a(c"ED25519")
45 );
46 if let Some(subject) = recovered_cert.subject_name().to_string() {
47 println!("Recovered cert subject: {subject}");
48 }
49 println!("CA chain length: {}", ca_chain.len());
50
51 // Public keys must match.
52 assert!(priv_key.public_eq(&recovered_key));
53 assert_eq!(cert.to_der()?, recovered_cert.to_der()?);
54 println!("Key and certificate match original: OK");
55
56 // ── DER round-trip ────────────────────────────────────────────────────────
57
58 let der2 = loaded.to_der()?;
59 assert_eq!(der, der2);
60 println!("DER round-trip: OK");
61
62 Ok(())
63}More examples
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9 // ── Generate an Ed25519 key pair ──────────────────────────────────────────
10
11 let mut kgen = KeygenCtx::new(c"ED25519")?;
12 let priv_key = kgen.generate()?;
13 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
14
15 // ── Build a self-signed certificate ──────────────────────────────────────
16
17 let mut name = X509NameOwned::new()?;
18 name.add_entry_by_txt(c"CN", b"example.com")?;
19 name.add_entry_by_txt(c"O", b"Example Org")?;
20 name.add_entry_by_txt(c"C", b"US")?;
21
22 let cert = X509Builder::new()?
23 .set_version(2)? // X.509 v3
24 .set_serial_number(42)?
25 .set_not_before_offset(0)? // valid from now
26 .set_not_after_offset(365 * 86400)? // valid for 1 year
27 .set_subject_name(&name)?
28 .set_issuer_name(&name)? // self-signed
29 .set_public_key(&pub_key)?
30 .sign(&priv_key, None)? // Ed25519 (no explicit digest needed)
31 .build();
32
33 // ── Inspect fields ────────────────────────────────────────────────────────
34
35 if let Some(subject) = cert.subject_name().to_string() {
36 println!("Subject: {subject}");
37 }
38 if let Some(issuer) = cert.issuer_name().to_string() {
39 println!("Issuer: {issuer}");
40 }
41 if let Some(serial) = cert.serial_number() {
42 println!("Serial: {serial}");
43 }
44 if let Some(nb) = cert.not_before_str() {
45 println!("NotBefore: {nb}");
46 }
47 if let Some(na) = cert.not_after_str() {
48 println!("NotAfter: {na}");
49 }
50 println!("Valid now: {}", cert.is_valid_now());
51 println!("Self-signed: {}", cert.is_self_signed());
52
53 // ── DER round-trip ────────────────────────────────────────────────────────
54
55 let der = cert.to_der()?;
56 let reloaded = native_ossl::x509::X509::from_der(&der)?;
57 assert_eq!(cert.to_der()?, reloaded.to_der()?);
58 println!("DER round-trip: OK ({} bytes)", der.len());
59
60 // ── PEM output ────────────────────────────────────────────────────────────
61
62 let pem = cert.to_pem()?;
63 println!("\nPEM certificate:\n{}", std::str::from_utf8(&pem)?);
64
65 // ── Signature verification ────────────────────────────────────────────────
66
67 cert.verify(&pub_key)?;
68 println!("Signature verification: OK");
69
70 Ok(())
71}14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 // ── Key pair and self-signed certificate ───────────────────────────────────
16
17 let mut kgen = KeygenCtx::new(c"ED25519")?;
18 let priv_key = kgen.generate()?;
19 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
20
21 let mut name = X509NameOwned::new()?;
22 name.add_entry_by_txt(c"CN", b"localhost")?;
23
24 let cert = X509Builder::new()?
25 .set_version(2)?
26 .set_serial_number(1)?
27 .set_not_before_offset(0)?
28 .set_not_after_offset(86400)?
29 .set_subject_name(&name)?
30 .set_issuer_name(&name)?
31 .set_public_key(&pub_key)?
32 .sign(&priv_key, None)?
33 .build();
34
35 // ── Server context ─────────────────────────────────────────────────────────
36
37 let server_ctx = SslCtx::new_server()?;
38 server_ctx.set_min_proto_version(TlsVersion::Tls13)?;
39 server_ctx.use_certificate(&cert)?;
40 server_ctx.use_private_key(&priv_key)?;
41 server_ctx.check_private_key()?;
42
43 // ── Client context ─────────────────────────────────────────────────────────
44
45 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 // Skip certificate verification for this self-signed example.
48 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 // ── SSL objects ────────────────────────────────────────────────────────────
51
52 let mut client = client_ctx.new_ssl()?;
53 let mut server = server_ctx.new_ssl()?;
54
55 client.set_connect_state();
56 client.set_hostname(c"localhost")?;
57 server.set_accept_state();
58
59 // ── In-process BIO pair ────────────────────────────────────────────────────
60 // Data written to client_bio is readable from server_bio and vice-versa.
61
62 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 // ── Drive the handshake ────────────────────────────────────────────────────
67 // Alternate between client and server until both report success.
68
69 let mut client_done = false;
70 let mut server_done = false;
71
72 for step in 0..20 {
73 if !client_done {
74 match client.connect() {
75 Ok(()) => {
76 client_done = true;
77 println!("Client handshake done at step {step}");
78 }
79 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
80 Err(e) => return Err(format!("client error: {e}").into()),
81 }
82 }
83 if !server_done {
84 match server.accept() {
85 Ok(()) => {
86 server_done = true;
87 println!("Server handshake done at step {step}");
88 }
89 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
90 Err(e) => return Err(format!("server error: {e}").into()),
91 }
92 }
93 if client_done && server_done {
94 break;
95 }
96 }
97 assert!(client_done && server_done, "handshake did not complete");
98
99 // ── Inspect the peer certificate on the client ─────────────────────────────
100
101 if let Some(peer_cert) = client.peer_certificate() {
102 if let Some(subject) = peer_cert.subject_name().to_string() {
103 println!("Server cert subject: {subject}");
104 }
105 }
106
107 // ── Application data exchange ──────────────────────────────────────────────
108
109 let request = b"GET / HTTP/1.0\r\n\r\n";
110 let response = b"HTTP/1.0 200 OK\r\n\r\nHello, TLS!";
111
112 let written = client.write(request)?;
113 assert_eq!(written, request.len());
114
115 let mut rbuf = [0u8; 64];
116 let n = server.read(&mut rbuf)?;
117 assert_eq!(&rbuf[..n], request);
118 println!("Server received: {:?}", std::str::from_utf8(&rbuf[..n])?);
119
120 let written = server.write(response)?;
121 assert_eq!(written, response.len());
122
123 let n = client.read(&mut rbuf)?;
124 assert_eq!(&rbuf[..n], response);
125 println!("Client received: {:?}", std::str::from_utf8(&rbuf[..n])?);
126
127 println!("In-process TLS 1.3 round-trip: OK");
128
129 Ok(())
130}