Extracting x.509 keys stored in public keys
Hey all,
I am currently working on fetching PGP keys from an LDAP server that also stores PGP keys that may also be used as S/MIME certificates, thanks to a corporate PGP server using Symantec Desktop Encryption.
https://mailarchive.ietf.org/arch/msg/openpgp/CjNgNtokjGE6u5TDG80F-iI6jRQ/
With the Rust PGP crate I can use this code to fetch the x.509 and validate it with OpenSSL and turn it from DER into a PEM:
use pgp::packet;
use pgp::Deserializable;
use pgp::SignedPublicKey;
pub fn extract_smime(publickey: &str) -> Result<Vec<Vec<u8>>, ()> {
let (pk, _headers) = SignedPublicKey::from_string(publickey).expect("Failed to parse key");
let mut smime_keys: Vec<Vec<u8>> = Vec::new();
// This code is used to pull the x509 certificate out of the PGP public key, which is defined
// in this document: https://mailarchive.ietf.org/arch/msg/openpgp/CjNgNtokjGE6u5TDG80F-iI6jRQ/
for user in pk.details.users {
for sig in user.signatures {
for subpacket in sig.config.hashed_subpackets {
match subpacket {
packet::Subpacket::Experimental(_typ, data) => match data.as_slice() {
[1, 1, 4, rest @ ..] => {
match openssl::x509::X509::from_der(&rest) {
Ok(x509) => {
let encoded = match x509.to_pem() {
Err(_) => {
dbg!("Can't encode to PEM");
continue;
}
Ok(pem) => pem,
};
smime_keys.push(encoded);
x509
}
Err(_) => {
dbg!("Can't parse x509 from DER");
continue;
}
};
}
_ => {}
},
_ => {}
}
}
}
}
if smime_keys.len() >= 1 {
Ok(smime_keys)
} else {
Err(())
}
}
Unfortunately the same PGP public key using Sequoia OpenPGP does not have an easy way to get access to the Experimental packet types, instead it is shoved into an Unknown
, which seems to have a bunch of extraneous data before getting to the sequence of numbers I recognize: [1, 1, 4]
but I am unsure of how to parse the extra data to validate that I am grabbing only the x.509 packet.
[src/internal/pgp.rs:60] ua.body() = [4, 16, 100, 8, 5, 96, 5, 2, 94, 216, 18, 53, 5, 3, 18, 204, 3, 0, 2, 27, 2, 196, 143, 100, 1, 1, 4, ...]
I was looking at the packet format in the PGP RFC, however I am not recognizing a pattern here to help me implement the extraction. Any help on this front would be greatly appreciated, even a pointer to where I can figure it out myself!
Funnily enough Rust PGP can't verify the public key, whereas Sequoia OpenPGP can so that I can make sure it hasn't been corrupted in transit or storage, so for now I am using two PGP libraries in a single project.
Here's a copy of the PGP Public Key:
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: PGP Universal 10.5.0 (Build 1520)
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
HSUEDDAKBggrBgEFBQcDBDARBgNVHQ4ECgQIveI4oYZldRYwIQYDVR0RBBowGIEW
QmVydC5SZWdlZXJAU0FQTlMyLmNvbTATBgNVHSMEDDAKgAjp9vF6X+T6vTCB9wYD
VR0fBIHvMIHsMIHpoIHmoIHjhkhodHRwOi8va2V5cy5zYXBuczIuY29tOjgwL2Ny
bC9SZXZva2VkQ2VydGlmaWNhdGVzXzB4RTlGNkYxN0E1RkU0RkFCRC5jcmyGgZZs
ZGFwOi8va2V5cy5zYXBuczIuY29tOjM4OS9wZ3BLZXlJRD0weEU5RjZGMTdBNUZF
NEZBQkQsY249UmV2b2tlZCUyMENlcnRpZmljYXRlcyxvPUNSTD9jZXJ0aWZpY2F0
ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Y2xhc3M9Y1JMRGlzdHJpYnV0aW9u
UG9pbnQwDQYJKoZIhvcNAQELBQADggEBABdVNGFg2A0kmFwOeWkT2REHWr8z8eBQ
HLwaRfupB+f0gMveO1npJ5MY5TdSfllAV/3YtHBjoc5lUAMtfsrOvE7Gshegjhat
uJQiEz6tNZJcYeZPMoed7MXSmI3O+zf5YqJmDVPnLc7NRtRWjRhke/hD1RgZNB7M
8AGg8be3lQZNm2cfbLNwhm0RA4i61BQXLckzyRRlFhsthfv7dT/FGxA3qJHQeI5y
9F1SxE6hRhHcRBotU0CZAk1cbUvQm8t92vz/P++RuXFvVzgp/VtqR/ye1Njrz081
Fw4y8egh4zPQVWY9p2zrzShXEE9jtTyys1DY//nivPYS7O1HkDo5q7AAAAAAAAEB
uQENBF7YEjUBCADpP5h0IOJMxQ2kNe9haMhJu44mrpi/s4WBH3K4lwJ1rwWQ8Iiv
WsUMzZVOkVZhgWjw5rxvrsxEw4Wc+xjHxpFgZ9VJowlW+FMGsTKUZRt5PJjhWY09
IiyyFckJ3QJKHg82YPngVUlHMXMaH4T4597trAovd0kBRoJXVSCfWbjF0ZFnN5+z
pwIKw4Vm2gNxYHGk0ZfS4rnVnp8/hLt7dZS6fzAYVk2JyBxaWaTVy//9GpWeLBF9
FhByN29ur7Rv+JNu8yJaAuO3LujqWwTds5HtkAchj4p7RY4alX8RSpazmyD7hwUn
YRqdrWTqXLNitTIp/RcwOmQq6HEsWJ6ZdTlBABEBAAGJB7QEGAEIBp4FAl7YEjkF
CRLMq8DEqxQAAAAAABcFS3g1MDljZXJ0aWZpY2F0ZUBwZ3AuY29tMIIFRzCCBC+g
AwIBAgIUIz4eZWbDMf9qIwI10CRNukWuFIUwDQYJKoZIhvcNAQELBQAwgZQxEzAR
BgNVBAMTCnNhcG5zMi5jb20xDzANBgNVBAoTBlNBUE5TMjEPMA0GA1UECxMGU0FQ
TlMyMRcwFQYDVQQHEw5OZXd0b3duIFNxdWFyZTELMAkGA1UECBMCUEExCzAJBgNV
BAYTAlVuMSgwJgYJKoZIhvcNAQkBFhltaWNoYWVsLm9uZWlsbEBzYXBuczIuY29t
MB4XDTIwMDYwMzIxMTIyMVoXDTMwMDYwMTIxMTIyMVowgZQxDDAKBgNVBAYTA1VT
QTELMAkGA1UECBMCUEExFzAVBgNVBAcTDk5ld3Rvd24gU3F1YXJlMQ8wDQYDVQQL
EwZTQVBOUzIxDzANBgNVBAoTBlNBUE5TMjElMCMGCSqGSIb3DQEJARYWQmVydC5S
ZWdlZXJAU0FQTlMyLmNvbTEVMBMGA1UEAxMMUmVnZWVyLCBCZXJ0MIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6T+YdCDiTMUNpDXvYWjISbuOJq6Yv7OF
gR9yuJcCda8FkPCIr1rFDM2VTpFWYYFo8Oa8b67MRMOFnPsYx8aRYGfVSaMJVvhT
BrEylGUbeTyY4VmNPSIsshXJCd0CSh4PNmD54FVJRzFzGh+E+Ofe7awKL3dJAUaC
V1Ugn1m4xdGRZzefs6cCCsOFZtoDcWBxpNGX0uK51Z6fP4S7e3WUun8wGFZNicgc
Wlmk1cv//RqVniwRfRYQcjdvbq+0b/iTbvMiWgLjty7o6lsE3bOR7ZAHIY+Ke0WO
GpV/EUqWs5sg+4cFJ2Eana1k6lyzYrUyKf0XMDpkKuhxLFiemXU5QQIDAQABo4IB
jTCCAYkwHQYKKwYBBAGaSQgBAQQPFw0yMDA2MDMyMTEyMjFaMA4GA1UdDwEB/wQE
AwIDODATBgNVHSUEDDAKBggrBgEFBQcDBDARBgNVHQ4ECgQI0CRNukWuFIUwIQYD
VR0RBBowGIEWQmVydC5SZWdlZXJAU0FQTlMyLmNvbTATBgNVHSMEDDAKgAjp9vF6
X+T6vTCB9wYDVR0fBIHvMIHsMIHpoIHmoIHjhkhodHRwOi8va2V5cy5zYXBuczIu
Y29tOjgwL2NybC9SZXZva2VkQ2VydGlmaWNhdGVzXzB4RTlGNkYxN0E1RkU0RkFC
RC5jcmyGgZZsZGFwOi8va2V5cy5zYXBuczIuY29tOjM4OS9wZ3BLZXlJRD0weEU5
RjZGMTdBNUZFNEZBQkQsY249UmV2b2tlZCUyMENlcnRpZmljYXRlcyxvPUNSTD9j
ZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Y2xhc3M9Y1JMRGlz
dHJpYnV0aW9uUG9pbnQwDQYJKoZIhvcNAQELBQADggEBAGwtbOImjmSJpNLTOptx
YDEmOUB+teUypXdEEYfBQJPwjcKqKmG/viru9ZPSHCWD83bei1L/8QcDakGS+hU3
9HG68QKcR0oR0LKcv4em8ySn0gILXVseHBEccW2Teyr51v7ExftgWjnHaz9U/dKk
9iXTzABXODpONIPpyfT9CMAY5lYdFIA2L5uuABmcKOcbNHffmGRwMF8Io9NVPlHh
+cGKHfBvtoRv8BvtunsGrdtdEecU4A+XDoxD/zd7McA1Cx+ZMqH3IMZ+5Xes8gzt
4u8DGrswlnKSL4vaUXZmk/ke6FJWQGlong/K1/P9A4/FrqZrjneTXK2FIyRqgT5k
2uoFGwwAAADAXSAEGQEIAAYFAl7YEjUACgkQ0CRNukWuFIWJaggA2emvw5d6FVAO
6PQeVgWJ1wV2xG2CHpNoXPqvIJbTZDu9LxDwOm/FuoP/U2s5MjmXLGrsgP4I9lbA
K0lZdRSmyLNGzW+g6AoSecEvSXa2oxCNFtFM5FZU9QexZAiNaNtlRs/IZOa5oGrw
bEbNUaP4SATXn67X9if9X72zvXflYeE6p5vUahl3RabzCBzyEmLUT3k/QXLVvjSD
P2yNSrx2anglAukgT6LA6LkqZHgMm8OKvkcDn3cAw6Lr/v9ozp3ucDj7WQ1sPKuu
VimY8QX6AEznl9MYo1sCHBLAd5Vg9qs6oZAaYS1ErnLkZNkwv2IJKxKZIPyymR9/
A6F6vnUHxgAKCRC94jihhmV1FnpcB/kBHB7YBgYTNeX4IoNgBCcqnU6ngRJT4bt/
J/GEgjh4bTTb7GAo1As2USnQiOdLQqLnzG4MO3hMIL4FW/vBri4uE1bh1p7aZjAR
DtzXEEDjC8emL5i6AY4XQjNbIp5lwaaaabtFzMC3n8vsLJ0o1MsPTy6vVDkLhc2e
OByEA0G2XdZXlZB5Hu6JWt4ZcUiknANdC2RfFf1FV/Uq16G6XcJwNbQL4gbY9Zdh
4FYGRt1MwZbm+niu1yCpruYSaDksf8e5bGA5nxyLWvLirfgd8NDavebvXjrBet0L
mRLEvw3EiSffliE0ZpbbByNo/F/oRejGUJNz7WNG96rRcJQVeRpV
=DikI
-----END PGP PUBLIC KEY BLOCK-----
For reference, here is the S/MIME certificate parsed out of that public key:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
32:66:97:0f:b5:29:95:74:32:89:c5:43:bd:e2:38:a1:86:65:75:16
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=sapns2.com, O=SAPNS2, OU=SAPNS2, L=Newtown Square, ST=PA, C=Un/emailAddress=michael.oneill@sapns2.com
Validity
Not Before: Jun 3 21:12:21 2020 GMT
Not After : Jun 1 21:12:21 2030 GMT
Subject: C=USA, ST=PA, L=Newtown Square, OU=SAPNS2, O=SAPNS2/emailAddress=Bert.Regeer@SAPNS2.com, CN=Regeer, Bert
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:cd:52:99:94:e3:fa:dd:fa:6e:ef:8f:52:7a:96:
89:34:16:2a:70:c8:1c:27:01:42:a0:8e:23:4e:69:
d1:e1:99:04:70:b0:b3:96:6c:3f:52:fe:66:a2:89:
63:e4:f1:ee:74:8e:43:aa:26:54:8b:11:b3:77:7c:
d0:a5:3f:86:dc:eb:82:4d:e2:4e:04:89:82:b3:20:
73:2a:dc:dc:a3:30:e5:25:8e:57:d2:40:48:ca:04:
48:b9:47:0a:eb:b2:96:8f:a7:4d:8f:7a:e2:3c:6f:
9b:5d:44:2a:b5:39:f9:a6:57:ee:9b:45:8f:b5:68:
fd:73:fe:8b:74:e1:2f:84:c0:5c:dd:12:ef:41:c3:
7c:10:77:dd:cf:73:5b:fc:5d:a9:9f:72:fc:59:ae:
ab:01:39:1a:9d:02:c3:a1:4a:db:04:a9:53:49:55:
57:bd:c5:8e:6a:a6:ac:32:0d:85:82:40:60:9e:19:
17:c4:db:e3:b3:ff:35:34:20:b7:ac:49:cb:9d:cf:
12:79:5a:ef:97:c7:89:bb:ca:2d:70:b2:2e:f6:a5:
b4:e2:36:5d:13:8e:f0:15:c6:d6:76:76:ef:5c:09:
55:02:da:31:10:66:cb:65:e1:93:7d:84:5b:27:85:
4c:e5:00:79:fb:1b:46:44:ff:b9:2e:8a:a0:51:e6:
64:43
Exponent: 65537 (0x10001)
X509v3 extensions:
1.3.6.1.4.1.3401.8.1.1:
200603211221Z .
X509v3 Key Usage: critical
Digital Signature
X509v3 Extended Key Usage:
E-mail Protection
X509v3 Subject Key Identifier:
BD:E2:38:A1:86:65:75:16
X509v3 Subject Alternative Name:
email:Bert.Regeer@SAPNS2.com
X509v3 Authority Key Identifier:
keyid:E9:F6:F1:7A:5F:E4:FA:BD
X509v3 CRL Distribution Points:
Full Name:
URI:http://keys.sapns2.com:80/crl/RevokedCertificates_0xE9F6F17A5FE4FABD.crl
URI:ldap://keys.sapns2.com:389/pgpKeyID=0xE9F6F17A5FE4FABD,cn=Revoked%20Certificates,o=CRL?certificateRevocationList?base?objectclass=cRLDistributionPoint
Signature Algorithm: sha256WithRSAEncryption
17:55:34:61:60:d8:0d:24:98:5c:0e:79:69:13:d9:11:07:5a:
bf:33:f1:e0:50:1c:bc:1a:45:fb:a9:07:e7:f4:80:cb:de:3b:
59:e9:27:93:18:e5:37:52:7e:59:40:57:fd:d8:b4:70:63:a1:
ce:65:50:03:2d:7e:ca:ce:bc:4e:c6:b2:17:a0:8e:16:ad:b8:
94:22:13:3e:ad:35:92:5c:61:e6:4f:32:87:9d:ec:c5:d2:98:
8d:ce:fb:37:f9:62:a2:66:0d:53:e7:2d:ce:cd:46:d4:56:8d:
18:64:7b:f8:43:d5:18:19:34:1e:cc:f0:01:a0:f1:b7:b7:95:
06:4d:9b:67:1f:6c:b3:70:86:6d:11:03:88:ba:d4:14:17:2d:
c9:33:c9:14:65:16:1b:2d:85:fb:fb:75:3f:c5:1b:10:37:a8:
91:d0:78:8e:72:f4:5d:52:c4:4e:a1:46:11:dc:44:1a:2d:53:
40:99:02:4d:5c:6d:4b:d0:9b:cb:7d:da:fc:ff:3f:ef:91:b9:
71:6f:57:38:29:fd:5b:6a:47:fc:9e:d4:d8:eb:cf:4f:35:17:
0e:32:f1:e8:21:e3:33:d0:55:66:3d:a7:6c:eb:cd:28:57:10:
4f:63:b5:3c:b2:b3:50:d8:ff:f9:e2:bc:f6:12:ec:ed:47:90:
3a:39:ab:b0
-----BEGIN CERTIFICATE-----
MIIFRzCCBC+gAwIBAgIUMmaXD7UplXQyicVDveI4oYZldRYwDQYJKoZIhvcNAQEL
BQAwgZQxEzARBgNVBAMTCnNhcG5zMi5jb20xDzANBgNVBAoTBlNBUE5TMjEPMA0G
A1UECxMGU0FQTlMyMRcwFQYDVQQHEw5OZXd0b3duIFNxdWFyZTELMAkGA1UECBMC
UEExCzAJBgNVBAYTAlVuMSgwJgYJKoZIhvcNAQkBFhltaWNoYWVsLm9uZWlsbEBz
YXBuczIuY29tMB4XDTIwMDYwMzIxMTIyMVoXDTMwMDYwMTIxMTIyMVowgZQxDDAK
BgNVBAYTA1VTQTELMAkGA1UECBMCUEExFzAVBgNVBAcTDk5ld3Rvd24gU3F1YXJl
MQ8wDQYDVQQLEwZTQVBOUzIxDzANBgNVBAoTBlNBUE5TMjElMCMGCSqGSIb3DQEJ
ARYWQmVydC5SZWdlZXJAU0FQTlMyLmNvbTEVMBMGA1UEAxMMUmVnZWVyLCBCZXJ0
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzVKZlOP63fpu749SepaJ
NBYqcMgcJwFCoI4jTmnR4ZkEcLCzlmw/Uv5moolj5PHudI5DqiZUixGzd3zQpT+G
3OuCTeJOBImCsyBzKtzcozDlJY5X0kBIygRIuUcK67KWj6dNj3riPG+bXUQqtTn5
plfum0WPtWj9c/6LdOEvhMBc3RLvQcN8EHfdz3Nb/F2pn3L8Wa6rATkanQLDoUrb
BKlTSVVXvcWOaqasMg2FgkBgnhkXxNvjs/81NCC3rEnLnc8SeVrvl8eJu8otcLIu
9qW04jZdE47wFcbWdnbvXAlVAtoxEGbLZeGTfYRbJ4VM5QB5+xtGRP+5LoqgUeZk
QwIDAQABo4IBjTCCAYkwHQYKKwYBBAGaSQgBAQQPFw0yMDA2MDMyMTEyMjFaMA4G
A1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDBDARBgNVHQ4ECgQIveI4
oYZldRYwIQYDVR0RBBowGIEWQmVydC5SZWdlZXJAU0FQTlMyLmNvbTATBgNVHSME
DDAKgAjp9vF6X+T6vTCB9wYDVR0fBIHvMIHsMIHpoIHmoIHjhkhodHRwOi8va2V5
cy5zYXBuczIuY29tOjgwL2NybC9SZXZva2VkQ2VydGlmaWNhdGVzXzB4RTlGNkYx
N0E1RkU0RkFCRC5jcmyGgZZsZGFwOi8va2V5cy5zYXBuczIuY29tOjM4OS9wZ3BL
ZXlJRD0weEU5RjZGMTdBNUZFNEZBQkQsY249UmV2b2tlZCUyMENlcnRpZmljYXRl
cyxvPUNSTD9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Y2xh
c3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwDQYJKoZIhvcNAQELBQADggEBABdVNGFg
2A0kmFwOeWkT2REHWr8z8eBQHLwaRfupB+f0gMveO1npJ5MY5TdSfllAV/3YtHBj
oc5lUAMtfsrOvE7GshegjhatuJQiEz6tNZJcYeZPMoed7MXSmI3O+zf5YqJmDVPn
Lc7NRtRWjRhke/hD1RgZNB7M8AGg8be3lQZNm2cfbLNwhm0RA4i61BQXLckzyRRl
Fhsthfv7dT/FGxA3qJHQeI5y9F1SxE6hRhHcRBotU0CZAk1cbUvQm8t92vz/P++R
uXFvVzgp/VtqR/ye1Njrz081Fw4y8egh4zPQVWY9p2zrzShXEE9jtTyys1DY//ni
vPYS7O1HkDo5q7A=
-----END CERTIFICATE-----