Skip to content

Commit 79585b3

Browse files
authored
x509-cert: adds conversion from std::net::IpAddr (#1035)
1 parent 3d7a110 commit 79585b3

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

x509-cert/src/ext/pkix/name/general.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,49 @@ pub enum GeneralName {
6161
#[asn1(context_specific = "8", tag_mode = "IMPLICIT")]
6262
RegisteredId(ObjectIdentifier),
6363
}
64+
65+
#[cfg(feature = "std")]
66+
impl From<std::net::IpAddr> for GeneralName {
67+
fn from(ip: std::net::IpAddr) -> Self {
68+
// Safety: this is unfailable here, OctetString will issue an error if you go
69+
// over 256MiB, here the buffer is at most 16 bytes (ipv6). The two `expect`s
70+
// below are safe.
71+
let buf = match ip {
72+
std::net::IpAddr::V4(v) => {
73+
let value = v.octets();
74+
OctetString::new(&value[..])
75+
.expect("OctetString is not expected to fail with a 4 bytes long buffer")
76+
}
77+
std::net::IpAddr::V6(v) => {
78+
let value = v.octets();
79+
OctetString::new(&value[..])
80+
.expect("OctetString is not expected to fail with a 16 bytes long buffer")
81+
}
82+
};
83+
84+
GeneralName::IpAddress(buf)
85+
}
86+
}
87+
88+
#[cfg(all(feature = "std", test))]
89+
mod tests {
90+
use super::*;
91+
use der::Encode;
92+
93+
#[test]
94+
fn test_convert() {
95+
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
96+
97+
let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
98+
let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
99+
100+
assert_eq!(
101+
GeneralName::from(localhost_v4).to_der().unwrap(),
102+
&[135, 4, 127, 0, 0, 1][..]
103+
);
104+
assert_eq!(
105+
GeneralName::from(localhost_v6).to_der().unwrap(),
106+
&[135, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1][..]
107+
);
108+
}
109+
}

0 commit comments

Comments
 (0)