1 /* Copyright (c) 2024, Google Inc. 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 */ 15 16 //! Helpers to ensure that some temporary objects are always freed. 17 18 use crate::initialized_struct; 19 20 /// A scoped `EC_KEY`. 21 pub struct EvpPkey(*mut bssl_sys::EVP_PKEY); 22 23 impl EvpPkey { new() -> Self24 pub fn new() -> Self { 25 let ptr = unsafe { bssl_sys::EVP_PKEY_new() }; 26 // `ptr` is only NULL if we're out of memory, which this crate 27 // doesn't handle. 28 assert!(!ptr.is_null()); 29 EvpPkey(ptr) 30 } 31 from_ptr(ptr: *mut bssl_sys::EVP_PKEY) -> Self32 pub fn from_ptr(ptr: *mut bssl_sys::EVP_PKEY) -> Self { 33 EvpPkey(ptr) 34 } 35 as_ffi_ptr(&mut self) -> *mut bssl_sys::EVP_PKEY36 pub fn as_ffi_ptr(&mut self) -> *mut bssl_sys::EVP_PKEY { 37 self.0 38 } 39 } 40 41 impl Drop for EvpPkey { drop(&mut self)42 fn drop(&mut self) { 43 unsafe { bssl_sys::EVP_PKEY_free(self.0) } 44 } 45 } 46 47 /// A scoped `EC_KEY`. 48 pub struct EcKey(*mut bssl_sys::EC_KEY); 49 50 impl EcKey { new() -> Self51 pub fn new() -> Self { 52 let ptr = unsafe { bssl_sys::EC_KEY_new() }; 53 // `ptr` is only NULL if we're out of memory, which this crate 54 // doesn't handle. 55 assert!(!ptr.is_null()); 56 EcKey(ptr) 57 } 58 as_ffi_ptr(&mut self) -> *mut bssl_sys::EC_KEY59 pub fn as_ffi_ptr(&mut self) -> *mut bssl_sys::EC_KEY { 60 self.0 61 } 62 } 63 64 impl Drop for EcKey { drop(&mut self)65 fn drop(&mut self) { 66 unsafe { bssl_sys::EC_KEY_free(self.0) } 67 } 68 } 69 70 /// A scoped `EVP_HPKE_CTX`. 71 pub struct EvpHpkeCtx(*mut bssl_sys::EVP_HPKE_CTX); 72 // bssl_sys::EVP_HPKE_CTX is heap-allocated and safe to transfer 73 // between threads. 74 unsafe impl Send for EvpHpkeCtx {} 75 76 impl EvpHpkeCtx { new() -> Self77 pub fn new() -> Self { 78 let ptr = unsafe { bssl_sys::EVP_HPKE_CTX_new() }; 79 // `ptr` is only NULL if we're out of memory, which this crate 80 // doesn't handle. 81 assert!(!ptr.is_null()); 82 EvpHpkeCtx(ptr) 83 } 84 as_ffi_ptr(&self) -> *const bssl_sys::EVP_HPKE_CTX85 pub fn as_ffi_ptr(&self) -> *const bssl_sys::EVP_HPKE_CTX { 86 self.0 87 } 88 as_mut_ffi_ptr(&mut self) -> *mut bssl_sys::EVP_HPKE_CTX89 pub fn as_mut_ffi_ptr(&mut self) -> *mut bssl_sys::EVP_HPKE_CTX { 90 self.0 91 } 92 } 93 94 impl Drop for EvpHpkeCtx { drop(&mut self)95 fn drop(&mut self) { 96 unsafe { bssl_sys::EVP_HPKE_CTX_free(self.0) } 97 } 98 } 99 100 /// A scoped `EVP_HPKE_KEY`. 101 pub struct EvpHpkeKey(bssl_sys::EVP_HPKE_KEY); 102 103 impl EvpHpkeKey { new() -> Self104 pub fn new() -> Self { 105 EvpHpkeKey(unsafe { initialized_struct(|ptr| bssl_sys::EVP_HPKE_KEY_zero(ptr)) }) 106 } 107 as_ffi_ptr(&self) -> *const bssl_sys::EVP_HPKE_KEY108 pub fn as_ffi_ptr(&self) -> *const bssl_sys::EVP_HPKE_KEY { 109 &self.0 110 } 111 as_mut_ffi_ptr(&mut self) -> *mut bssl_sys::EVP_HPKE_KEY112 pub fn as_mut_ffi_ptr(&mut self) -> *mut bssl_sys::EVP_HPKE_KEY { 113 &mut self.0 114 } 115 } 116 117 impl Drop for EvpHpkeKey { drop(&mut self)118 fn drop(&mut self) { 119 // unsafe: the only way to create a `EvpHpkeKey` is via `new` and that 120 // ensures that this structure is initialized. 121 unsafe { bssl_sys::EVP_HPKE_KEY_cleanup(&mut self.0) } 122 } 123 } 124 125 /// A scoped `BIGNUM`. 126 pub struct Bignum(bssl_sys::BIGNUM); 127 128 impl Bignum { from_u64(value: u64) -> Self129 pub fn from_u64(value: u64) -> Self { 130 let mut ret = Bignum(unsafe { initialized_struct(|ptr| bssl_sys::BN_init(ptr)) }); 131 assert_eq!(1, unsafe { bssl_sys::BN_set_u64(&mut ret.0, value) }); 132 ret 133 } 134 as_ffi_ptr(&self) -> *const bssl_sys::BIGNUM135 pub unsafe fn as_ffi_ptr(&self) -> *const bssl_sys::BIGNUM { 136 &self.0 137 } 138 } 139 140 impl Drop for Bignum { drop(&mut self)141 fn drop(&mut self) { 142 unsafe { bssl_sys::BN_free(&mut self.0) } 143 } 144 } 145