Skip to content

Commit

Permalink
fix soundness issue with preallocated_gen_new
Browse files Browse the repository at this point in the history
Stop this from being a generic function over all contexts, to only a
function generic over contexts where we can bound the lifetime
precisely.

Fixes #543
  • Loading branch information
apoelstra committed Nov 30, 2022
1 parent 5256139 commit c452ebc
Showing 1 changed file with 48 additions and 3 deletions.
51 changes: 48 additions & 3 deletions src/context.rs
Expand Up @@ -318,9 +318,9 @@ unsafe impl<'buf> Context for AllPreallocated<'buf> {
}
}

impl<'buf, C: Context + 'buf> Secp256k1<C> {
impl<'buf> PreallocatedContext<'buf> for Secp256k1<SignOnlyPreallocated<'buf>> {
/// Lets you create a context with a preallocated buffer in a generic manner (sign/verify/all).
pub fn preallocated_gen_new(buf: &'buf mut [AlignedType]) -> Result<Secp256k1<C>, Error> {
fn preallocated_gen_new(buf: &'buf mut [AlignedType]) -> Result<Self, Error> {
#[cfg(target_arch = "wasm32")]
ffi::types::sanity_checks_for_wasm();

Expand All @@ -331,13 +331,58 @@ impl<'buf, C: Context + 'buf> Secp256k1<C> {
ctx: unsafe {
NonNull::new_unchecked(ffi::secp256k1_context_preallocated_create(
buf.as_mut_c_ptr() as *mut c_void,
C::FLAGS,
AllPreallocated::FLAGS,
))
},
phantom: PhantomData,
})
}
}
impl<'buf> PreallocatedContext<'buf> for Secp256k1<VerifyOnlyPreallocated<'buf>> {
/// Lets you create a context with a preallocated buffer in a generic manner (sign/verify/all).
fn preallocated_gen_new(buf: &'buf mut [AlignedType]) -> Result<Self, Error> {
#[cfg(target_arch = "wasm32")]
ffi::types::sanity_checks_for_wasm();

if buf.len() < Self::preallocate_size_gen() {
return Err(Error::NotEnoughMemory);
}
Ok(Secp256k1 {
ctx: unsafe {
NonNull::new_unchecked(ffi::secp256k1_context_preallocated_create(
buf.as_mut_c_ptr() as *mut c_void,
VerifyOnlyPreallocated::FLAGS,
))
},
phantom: PhantomData,
})
}
}
impl<'buf> PreallocatedContext<'buf> for Secp256k1<AllPreallocated<'buf>> {
/// Lets you create a context with a preallocated buffer in a generic manner (sign/verify/all).
fn preallocated_gen_new(buf: &'buf mut [AlignedType]) -> Result<Self, Error> {
#[cfg(target_arch = "wasm32")]
ffi::types::sanity_checks_for_wasm();

if buf.len() < Self::preallocate_size_gen() {
return Err(Error::NotEnoughMemory);
}
Ok(Secp256k1 {
ctx: unsafe {
NonNull::new_unchecked(ffi::secp256k1_context_preallocated_create(
buf.as_mut_c_ptr() as *mut c_void,
SignOnlyPreallocated::FLAGS,
))
},
phantom: PhantomData,
})
}
}

trait PreallocatedContext<'buf>: Sized {
/// Lets you create a context with a preallocated buffer in a generic manner (sign/verify/all).
fn preallocated_gen_new(buf: &'buf mut [AlignedType]) -> Result<Self, Error>;
}

impl<'buf> Secp256k1<AllPreallocated<'buf>> {
/// Creates a new Secp256k1 context with all capabilities.
Expand Down

0 comments on commit c452ebc

Please sign in to comment.