diff options
| author | Steven Fackler <[email protected]> | 2015-01-06 00:24:37 -0500 |
|---|---|---|
| committer | Steven Fackler <[email protected]> | 2015-01-06 00:24:37 -0500 |
| commit | 2b6b1ef8b38f66e5801a1c3bebe19fbb563e110a (patch) | |
| tree | 8ef58f33985624009557e28e191624670dde9f61 | |
| parent | Release v0.2.12 (diff) | |
| parent | Merge remote-tracking branch 'upstream/master' (diff) | |
| download | rust-openssl-2b6b1ef8b38f66e5801a1c3bebe19fbb563e110a.tar.xz rust-openssl-2b6b1ef8b38f66e5801a1c3bebe19fbb563e110a.zip | |
Merge pull request #137 from cjcole/master
Added BN_[add,div,mul,sub,mod]_word and conversions to and from dec and hex strings.
| -rw-r--r-- | openssl-sys/src/lib.rs | 12 | ||||
| -rw-r--r-- | src/bn/mod.rs | 86 |
2 files changed, 96 insertions, 2 deletions
diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 923863f3..fb1ecb78 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -269,6 +269,11 @@ extern "C" { pub fn BN_mod_sub(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; pub fn BN_mul(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; pub fn BN_nnmod(rem: *mut BIGNUM, a: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_add_word(r: *mut BIGNUM, w: c_ulong) -> c_int; + pub fn BN_sub_word(r: *mut BIGNUM, w: c_ulong) -> c_int; + pub fn BN_mul_word(r: *mut BIGNUM, w: c_ulong) -> c_int; + pub fn BN_div_word(r: *mut BIGNUM, w: c_ulong) -> c_ulong; + pub fn BN_mod_word(r: *const BIGNUM, w: c_ulong) -> c_ulong; pub fn BN_sqr(r: *mut BIGNUM, a: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; pub fn BN_sub(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM) -> c_int; @@ -301,9 +306,14 @@ extern "C" { pub fn BN_bin2bn(s: *const u8, size: c_int, ret: *mut BIGNUM) -> *mut BIGNUM; pub fn BN_bn2bin(a: *mut BIGNUM, to: *mut u8) -> c_int; - /* Conversion from/to string representation */ + /* Conversion from/to decimal string representation */ + pub fn BN_dec2bn(a: *const *mut BIGNUM, s: *const i8) -> c_int; pub fn BN_bn2dec(a: *mut BIGNUM) -> *const c_char; + /* Conversion from/to hexidecimal string representation */ + pub fn BN_hex2bn(a: *const *mut BIGNUM, s: *const i8) -> c_int; + pub fn BN_bn2hex(a: *mut BIGNUM) -> *const c_char; + pub fn CRYPTO_num_locks() -> c_int; pub fn CRYPTO_set_locking_callback(func: extern "C" fn(mode: c_int, n: c_int, diff --git a/src/bn/mod.rs b/src/bn/mod.rs index ead3093b..d1a31c0e 100644 --- a/src/bn/mod.rs +++ b/src/bn/mod.rs @@ -1,5 +1,5 @@ use libc::{c_int, c_ulong, c_void}; -use std::c_str::CString; +use std::c_str::{CString, ToCStr}; use std::cmp::Ordering; use std::{fmt, ptr}; @@ -86,6 +86,22 @@ impl BigNum { }) } + pub fn from_dec_str(s: &str) -> Result<BigNum, SslError> { + BigNum::new().and_then(|v| unsafe { + let c_str = s.to_c_str(); + try_ssl!(ffi::BN_dec2bn(v.raw_ptr(), c_str.as_ptr())); + Ok(v) + }) + } + + pub fn from_hex_str(s: &str) -> Result<BigNum, SslError> { + BigNum::new().and_then(|v| unsafe { + let c_str = s.to_c_str(); + try_ssl!(ffi::BN_hex2bn(v.raw_ptr(), c_str.as_ptr())); + Ok(v) + }) + } + pub fn new_from_slice(n: &[u8]) -> Result<BigNum, SslError> { BigNum::new().and_then(|v| unsafe { try_ssl_null!(ffi::BN_bin2bn(n.as_ptr(), n.len() as c_int, v.raw())); @@ -147,6 +163,58 @@ impl BigNum { } } + pub fn add_word(&mut self, w: c_ulong) -> Result<(), SslError> { + unsafe { + if ffi::BN_add_word(self.raw(), w) == 1 { + Ok(()) + } else { + Err(SslError::get()) + } + } + } + + pub fn sub_word(&mut self, w: c_ulong) -> Result<(), SslError> { + unsafe { + if ffi::BN_sub_word(self.raw(), w) == 1 { + Ok(()) + } else { + Err(SslError::get()) + } + } + } + + pub fn mul_word(&mut self, w: c_ulong) -> Result<(), SslError> { + unsafe { + if ffi::BN_mul_word(self.raw(), w) == 1 { + Ok(()) + } else { + Err(SslError::get()) + } + } + } + + pub fn div_word(&mut self, w: c_ulong) -> Result<c_ulong, SslError> { + unsafe { + let result = ffi::BN_div_word(self.raw(), w); + if result != -1 as c_ulong { + Ok(result) + } else { + Err(SslError::get()) + } + } + } + + pub fn mod_word(&self, w: c_ulong) -> Result<c_ulong, SslError> { + unsafe { + let result = ffi::BN_mod_word(self.raw(), w); + if result != -1 as c_ulong { + Ok(result) + } else { + Err(SslError::get()) + } + } + } + pub fn checked_gcd(&self, a: &BigNum) -> Result<BigNum, SslError> { unsafe { with_bn_in_ctx!(r, ctx, { ffi::BN_gcd(r.raw(), self.raw(), a.raw(), ctx) == 1 }) @@ -334,6 +402,11 @@ impl BigNum { n } + unsafe fn raw_ptr(&self) -> *const *mut ffi::BIGNUM { + let BigNum(ref n) = *self; + n + } + pub fn to_vec(&self) -> Vec<u8> { let size = self.num_bytes() as uint; let mut v = Vec::with_capacity(size); @@ -354,6 +427,17 @@ impl BigNum { str } } + + pub fn to_hex_str(&self) -> String { + unsafe { + let buf = ffi::BN_bn2hex(self.raw()); + assert!(!buf.is_null()); + let c_str = CString::new(buf, false); + let str = c_str.as_str().unwrap().to_string(); + ffi::CRYPTO_free(buf as *mut c_void); + str + } + } } impl fmt::Show for BigNum { |