1use crate::error::*;
6use crate::pk11::types::{Certificate, PublicKey};
7use crate::util::{assert_nss_initialized, sec_item_as_slice, ScopedPtr};
8use nss_sys::{CERT_ExtractPublicKey, CERT_GetDefaultCertDB, CERT_NewTempCertificate};
9
10pub fn extract_ec_public_key(der: &[u8]) -> Result<Vec<u8>> {
11 assert_nss_initialized();
12
13 let certdb = unsafe { CERT_GetDefaultCertDB() };
14 let mut data = nss_sys::SECItem {
15 len: u32::try_from(der.len())?,
16 data: der.as_ptr() as *mut u8,
17 type_: nss_sys::SECItemType::siBuffer as u32,
18 };
19
20 let cert = unsafe {
21 Certificate::from_ptr(CERT_NewTempCertificate(
22 certdb,
23 &mut data,
24 std::ptr::null_mut(),
25 nss_sys::PR_FALSE,
26 nss_sys::PR_TRUE,
27 ))?
28 };
29
30 let pub_key = unsafe { PublicKey::from_ptr(CERT_ExtractPublicKey(cert.as_mut_ptr()))? };
31 let pub_key_raw = unsafe { &*pub_key.as_ptr() };
32
33 if pub_key_raw.keyType != nss_sys::KeyType::ecKey as u32 {
34 return Err(
35 ErrorKind::InputError("public key is not of type EC (Elliptic Curve).".into()).into(),
36 );
37 }
38
39 let mut pub_key_data = unsafe { pub_key_raw.u.ec.publicValue };
40 let pub_key_data_raw = unsafe { sec_item_as_slice(&mut pub_key_data)? };
41
42 Ok(pub_key_data_raw.to_vec())
43}