2 use foreign_types
::ForeignTypeRef
;
3 use libc
::{c_int, c_char, c_void}
;
10 use error
::ErrorStack
;
11 use util
::{CallbackState, invoke_passwd_cb_old}
;
14 type CType
= ffi
::DSA
;
15 fn drop
= ffi
::DSA_free
;
22 private_key_to_pem
!(ffi
::PEM_write_bio_DSAPrivateKey
);
23 public_key_to_pem
!(ffi
::PEM_write_bio_DSA_PUBKEY
);
25 private_key_to_der
!(ffi
::i2d_DSAPrivateKey
);
26 public_key_to_der
!(ffi
::i2d_DSAPublicKey
);
28 // FIXME should return u32
29 pub fn size(&self) -> Option
<u32> {
30 if self.q().is_some() {
31 unsafe { Some(ffi::DSA_size(self.as_ptr()) as u32) }
37 pub fn p(&self) -> Option
<&BigNumRef
> {
39 let p
= compat
::pqg(self.as_ptr())[0];
43 Some(BigNumRef
::from_ptr(p
as *mut _
))
48 pub fn q(&self) -> Option
<&BigNumRef
> {
50 let q
= compat
::pqg(self.as_ptr())[1];
54 Some(BigNumRef
::from_ptr(q
as *mut _
))
59 pub fn g(&self) -> Option
<&BigNumRef
> {
61 let g
= compat
::pqg(self.as_ptr())[2];
65 Some(BigNumRef
::from_ptr(g
as *mut _
))
70 pub fn has_public_key(&self) -> bool
{
71 unsafe { !compat::keys(self.as_ptr())[0].is_null() }
74 pub fn has_private_key(&self) -> bool
{
75 unsafe { !compat::keys(self.as_ptr())[1].is_null() }
80 /// Generate a DSA key pair.
81 pub fn generate(bits
: u32) -> Result
<Dsa
, ErrorStack
> {
83 let dsa
= Dsa(try
!(cvt_p(ffi
::DSA_new())));
84 try
!(cvt(ffi
::DSA_generate_parameters_ex(
93 try
!(cvt(ffi
::DSA_generate_key(dsa
.0)));
98 private_key_from_pem
!(Dsa
, ffi
::PEM_read_bio_DSAPrivateKey
);
99 private_key_from_der
!(Dsa
, ffi
::d2i_DSAPrivateKey
);
100 public_key_from_pem
!(Dsa
, ffi
::PEM_read_bio_DSA_PUBKEY
);
101 public_key_from_der
!(Dsa
, ffi
::d2i_DSAPublicKey
);
103 #[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
104 pub fn private_key_from_pem_cb
<F
>(buf
: &[u8], pass_cb
: F
) -> Result
<Dsa
, ErrorStack
>
106 F
: FnOnce(&mut [c_char
]) -> usize,
109 let mut cb
= CallbackState
::new(pass_cb
);
110 let mem_bio
= try
!(MemBioSlice
::new(buf
));
113 let cb_ptr
= &mut cb
as *mut _
as *mut c_void
;
114 let dsa
= try
!(cvt_p(ffi
::PEM_read_bio_DSAPrivateKey(
117 Some(invoke_passwd_cb_old
::<F
>),
125 impl fmt
::Debug
for Dsa
{
126 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
134 use ffi
::{self, BIGNUM, DSA}
;
136 pub unsafe fn pqg(d
: *const DSA
) -> [*const BIGNUM
; 3] {
137 let (mut p
, mut q
, mut g
) = (ptr
::null(), ptr
::null(), ptr
::null());
138 ffi
::DSA_get0_pqg(d
, &mut p
, &mut q
, &mut g
);
142 pub unsafe fn keys(d
: *const DSA
) -> [*const BIGNUM
; 2] {
143 let (mut pub_key
, mut priv_key
) = (ptr
::null(), ptr
::null());
144 ffi
::DSA_get0_key(d
, &mut pub_key
, &mut priv_key
);
151 use ffi
::{BIGNUM, DSA}
;
153 pub unsafe fn pqg(d
: *const DSA
) -> [*const BIGNUM
; 3] {
154 [(*d
).p
, (*d
).q
, (*d
).g
]
157 pub unsafe fn keys(d
: *const DSA
) -> [*const BIGNUM
; 2] {
158 [(*d
).pub_key
, (*d
).priv_key
]
169 pub fn test_generate() {
170 Dsa
::generate(1024).unwrap();
174 pub fn test_password() {
175 let key
= include_bytes
!("../test/dsa-encrypted.pem");
176 Dsa
::private_key_from_pem_passphrase(key
, b
"mypass").unwrap();
180 fn test_to_password() {
181 let key
= Dsa
::generate(2048).unwrap();
182 let pem
= key
.private_key_to_pem_passphrase(Cipher
::aes_128_cbc(), b
"foobar")
184 Dsa
::private_key_from_pem_passphrase(&pem
, b
"foobar").unwrap();
185 assert
!(Dsa
::private_key_from_pem_passphrase(&pem
, b
"fizzbuzz").is_err());
189 pub fn test_password_callback() {
190 let mut password_queried
= false;
191 let key
= include_bytes
!("../test/dsa-encrypted.pem");
192 Dsa
::private_key_from_pem_callback(key
, |password
| {
193 password_queried
= true;
194 password
[..6].copy_from_slice(b
"mypass");
198 assert
!(password_queried
);