Add ability to get affine coordinates from EcPoint
The initial usecase here is creating JWK representations as defined within RFC 7517 from an EcKey created via a PEM source.
This commit is contained in:
parent
51471c7c8a
commit
f599df124b
|
|
@ -1714,7 +1714,11 @@ extern "C" {
|
|||
pub fn EC_KEY_generate_key(key: *mut EC_KEY) -> c_int;
|
||||
pub fn EC_KEY_check_key(key: *const EC_KEY) -> c_int;
|
||||
pub fn EC_KEY_free(key: *mut EC_KEY);
|
||||
pub fn EC_KEY_set_public_key_affine_coordinates(key: *mut EC_KEY, x: *mut BIGNUM, y: *mut BIGNUM) -> c_int;
|
||||
pub fn EC_KEY_set_public_key_affine_coordinates(
|
||||
key: *mut EC_KEY,
|
||||
x: *mut BIGNUM,
|
||||
y: *mut BIGNUM,
|
||||
) -> c_int;
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
|
||||
pub fn EC_GF2m_simple_method() -> *const EC_METHOD;
|
||||
|
|
@ -1798,6 +1802,21 @@ extern "C" {
|
|||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
pub fn EC_POINT_free(point: *mut EC_POINT);
|
||||
pub fn EC_POINT_get_affine_coordinates_GFp(
|
||||
group: *const EC_GROUP,
|
||||
p: *const EC_POINT,
|
||||
x: *mut BIGNUM,
|
||||
y: *mut BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
|
||||
pub fn EC_POINT_get_affine_coordinates_GF2m(
|
||||
group: *const EC_GROUP,
|
||||
p: *const EC_POINT,
|
||||
x: *mut BIGNUM,
|
||||
y: *mut BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
pub fn ERR_peek_last_error() -> c_ulong;
|
||||
pub fn ERR_get_error() -> c_ulong;
|
||||
|
|
@ -2643,10 +2662,7 @@ extern "C" {
|
|||
flags: c_uint,
|
||||
) -> c_int;
|
||||
#[cfg(not(libressl))]
|
||||
pub fn SMIME_read_CMS(
|
||||
bio: *mut BIO,
|
||||
bcont: *mut *mut BIO,
|
||||
) -> *mut CMS_ContentInfo;
|
||||
pub fn SMIME_read_CMS(bio: *mut BIO, bcont: *mut *mut BIO) -> *mut CMS_ContentInfo;
|
||||
#[cfg(not(libressl))]
|
||||
pub fn CMS_ContentInfo_free(cms: *mut CMS_ContentInfo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,6 +271,45 @@ impl EcPointRef {
|
|||
Ok(res == 0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Place affine coordinates of a curve over a prime field in the provided x and y BigNum's
|
||||
pub fn get_affine_coordinates_gfp(
|
||||
&self,
|
||||
group: &EcGroupRef,
|
||||
x: &mut BigNumRef,
|
||||
y: &mut BigNumRef,
|
||||
ctx: &mut BigNumContextRef,
|
||||
) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EC_POINT_get_affine_coordinates_GFp(
|
||||
group.as_ptr(),
|
||||
self.as_ptr(),
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Place affine coordinates of a curve over a binary field in the provided x and y BigNum's
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
|
||||
pub fn get_affine_coordinates_gf2m(
|
||||
&self,
|
||||
group: &EcGroupRef,
|
||||
x: &mut BigNumRef,
|
||||
y: &mut BigNumRef,
|
||||
ctx: &mut BigNumContextRef,
|
||||
) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EC_POINT_get_affine_coordinates_GF2m(
|
||||
group.as_ptr(),
|
||||
self.as_ptr(),
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EcPoint {
|
||||
|
|
@ -461,25 +500,23 @@ impl EcKeyBuilderRef {
|
|||
}
|
||||
|
||||
/// Sets the public key based on affine coordinates.
|
||||
pub fn set_public_key_affine_coordinates(&mut self,
|
||||
x: &BigNumRef,
|
||||
y: &BigNumRef)
|
||||
-> Result<&mut EcKeyBuilderRef, ErrorStack> {
|
||||
pub fn set_public_key_affine_coordinates(
|
||||
&mut self,
|
||||
x: &BigNumRef,
|
||||
y: &BigNumRef,
|
||||
) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EC_KEY_set_public_key_affine_coordinates(self.as_ptr(),
|
||||
x.as_ptr(),
|
||||
y.as_ptr())
|
||||
).map(|_| self)
|
||||
cvt(ffi::EC_KEY_set_public_key_affine_coordinates(
|
||||
self.as_ptr(),
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
)).map(|_| self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the private key.
|
||||
pub fn set_private_key(&mut self,
|
||||
key: &BigNumRef)
|
||||
-> Result<&mut EcKeyBuilderRef, ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EC_KEY_set_private_key(self.as_ptr(), key.as_ptr())).map(|_| self)
|
||||
}
|
||||
pub fn set_private_key(&mut self, key: &BigNumRef) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
|
||||
unsafe { cvt(ffi::EC_KEY_set_private_key(self.as_ptr(), key.as_ptr())).map(|_| self) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -566,17 +603,21 @@ mod test {
|
|||
#[test]
|
||||
fn key_from_affine_coordinates() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let x = data_encoding::base64url::decode_nopad("MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4".as_bytes())
|
||||
.unwrap();
|
||||
let y = data_encoding::base64url::decode_nopad("4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM".as_bytes())
|
||||
.unwrap();
|
||||
let x = data_encoding::base64url::decode_nopad(
|
||||
"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4".as_bytes(),
|
||||
).unwrap();
|
||||
let y = data_encoding::base64url::decode_nopad(
|
||||
"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM".as_bytes(),
|
||||
).unwrap();
|
||||
|
||||
let xbn = BigNum::from_slice(&x).unwrap();
|
||||
let ybn = BigNum::from_slice(&y).unwrap();
|
||||
|
||||
let mut builder = EcKeyBuilder::new().unwrap();
|
||||
builder.set_group(&group).unwrap();
|
||||
builder.set_public_key_affine_coordinates(&xbn, &ybn).unwrap();
|
||||
builder
|
||||
.set_public_key_affine_coordinates(&xbn, &ybn)
|
||||
.unwrap();
|
||||
|
||||
let ec_key = builder.build();
|
||||
assert!(ec_key.check_key().is_ok());
|
||||
|
|
@ -586,8 +627,9 @@ mod test {
|
|||
#[test]
|
||||
fn set_private_key() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let d = data_encoding::base64url::decode_nopad("870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE".as_bytes())
|
||||
.unwrap();
|
||||
let d = data_encoding::base64url::decode_nopad(
|
||||
"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE".as_bytes(),
|
||||
).unwrap();
|
||||
|
||||
let dbn = BigNum::from_slice(&d).unwrap();
|
||||
|
||||
|
|
@ -598,4 +640,34 @@ mod test {
|
|||
let ec_key = builder.build();
|
||||
assert!(ec_key.private_key().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_affine_coordinates() {
|
||||
let raw_x = "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4";
|
||||
let raw_y = "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM";
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let x = data_encoding::base64url::decode_nopad(raw_x.as_bytes()).unwrap();
|
||||
let y = data_encoding::base64url::decode_nopad(raw_y.as_bytes()).unwrap();
|
||||
|
||||
let xbn = BigNum::from_slice(&x).unwrap();
|
||||
let ybn = BigNum::from_slice(&y).unwrap();
|
||||
|
||||
let mut builder = EcKeyBuilder::new().unwrap();
|
||||
builder.set_group(&group).unwrap();
|
||||
builder
|
||||
.set_public_key_affine_coordinates(&xbn, &ybn)
|
||||
.unwrap();
|
||||
|
||||
let ec_key = builder.build();
|
||||
|
||||
let mut xbn2 = BigNum::new().unwrap();
|
||||
let mut ybn2 = BigNum::new().unwrap();
|
||||
let mut ctx = BigNumContext::new().unwrap();
|
||||
let ec_key_pk = ec_key.public_key().unwrap();
|
||||
ec_key_pk
|
||||
.get_affine_coordinates_gfp(&group, &mut xbn2, &mut ybn2, &mut ctx)
|
||||
.unwrap();
|
||||
assert_eq!(xbn2, xbn);
|
||||
assert_eq!(ybn2, ybn);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue