nss/
cert.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use 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}