|
17 | 17 | //! [Elliptic Curve Cryptography]: https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography
|
18 | 18 | use foreign_types::{ForeignType, ForeignTypeRef};
|
19 | 19 | use libc::c_int;
|
| 20 | +use std::ffi::CString; |
20 | 21 | use std::fmt;
|
21 | 22 | use std::ptr;
|
22 | 23 |
|
23 | 24 | use crate::bn::{BigNum, BigNumContextRef, BigNumRef};
|
24 | 25 | use crate::error::ErrorStack;
|
25 | 26 | use crate::nid::Nid;
|
26 | 27 | use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
|
| 28 | +use crate::string::OpensslString; |
27 | 29 | use crate::util::ForeignTypeRefExt;
|
28 | 30 | use crate::{cvt, cvt_n, cvt_p, init};
|
29 | 31 | use openssl_macros::corresponds;
|
@@ -463,6 +465,26 @@ impl EcPointRef {
|
463 | 465 | }
|
464 | 466 | }
|
465 | 467 |
|
| 468 | + /// Serializes the point to a hexadecimal string representation. |
| 469 | + #[corresponds(EC_POINT_point2hex)] |
| 470 | + #[cfg(not(boringssl))] |
| 471 | + pub fn to_hex_str( |
| 472 | + &self, |
| 473 | + group: &EcGroupRef, |
| 474 | + form: PointConversionForm, |
| 475 | + ctx: &mut BigNumContextRef, |
| 476 | + ) -> Result<OpensslString, ErrorStack> { |
| 477 | + unsafe { |
| 478 | + let buf = cvt_p(ffi::EC_POINT_point2hex( |
| 479 | + group.as_ptr(), |
| 480 | + self.as_ptr(), |
| 481 | + form.0, |
| 482 | + ctx.as_ptr(), |
| 483 | + ))?; |
| 484 | + Ok(OpensslString::from_ptr(buf)) |
| 485 | + } |
| 486 | + } |
| 487 | + |
466 | 488 | /// Creates a new point on the specified curve with the same value.
|
467 | 489 | #[corresponds(EC_POINT_dup)]
|
468 | 490 | pub fn to_owned(&self, group: &EcGroupRef) -> Result<EcPoint, ErrorStack> {
|
@@ -631,6 +653,27 @@ impl EcPoint {
|
631 | 653 | }
|
632 | 654 | Ok(point)
|
633 | 655 | }
|
| 656 | + |
| 657 | + /// Creates point from a hexadecimal string representation |
| 658 | + #[corresponds(EC_POINT_hex2point)] |
| 659 | + #[cfg(not(boringssl))] |
| 660 | + pub fn from_hex_str( |
| 661 | + group: &EcGroupRef, |
| 662 | + s: &str, |
| 663 | + ctx: &mut BigNumContextRef, |
| 664 | + ) -> Result<EcPoint, ErrorStack> { |
| 665 | + let point = EcPoint::new(group)?; |
| 666 | + unsafe { |
| 667 | + let c_str = CString::new(s.as_bytes()).unwrap(); |
| 668 | + cvt_p(ffi::EC_POINT_hex2point( |
| 669 | + group.as_ptr(), |
| 670 | + c_str.as_ptr() as *const _, |
| 671 | + point.as_ptr(), |
| 672 | + ctx.as_ptr(), |
| 673 | + ))?; |
| 674 | + } |
| 675 | + Ok(point) |
| 676 | + } |
634 | 677 | }
|
635 | 678 |
|
636 | 679 | generic_foreign_type_and_impl_send_sync! {
|
@@ -1121,6 +1164,20 @@ mod test {
|
1121 | 1164 | assert!(point.eq(&group, &point2, &mut ctx).unwrap());
|
1122 | 1165 | }
|
1123 | 1166 |
|
| 1167 | + #[test] |
| 1168 | + #[cfg(not(boringssl))] |
| 1169 | + fn point_hex_str() { |
| 1170 | + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); |
| 1171 | + let key = EcKey::generate(&group).unwrap(); |
| 1172 | + let point = key.public_key(); |
| 1173 | + let mut ctx = BigNumContext::new().unwrap(); |
| 1174 | + let hex = point |
| 1175 | + .to_hex_str(&group, PointConversionForm::COMPRESSED, &mut ctx) |
| 1176 | + .unwrap(); |
| 1177 | + let point2 = EcPoint::from_hex_str(&group, &hex, &mut ctx).unwrap(); |
| 1178 | + assert!(point.eq(&group, &point2, &mut ctx).unwrap()); |
| 1179 | + } |
| 1180 | + |
1124 | 1181 | #[test]
|
1125 | 1182 | fn point_owned() {
|
1126 | 1183 | let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
|
0 commit comments