]> git.proxmox.com Git - cargo.git/blob - vendor/openssl-0.9.15/src/dsa.rs
New upstream version 0.22.0
[cargo.git] / vendor / openssl-0.9.15 / src / dsa.rs
1 use ffi;
2 use foreign_types::ForeignTypeRef;
3 use libc::{c_int, c_char, c_void};
4 use std::fmt;
5 use std::ptr;
6
7 use {cvt, cvt_p};
8 use bio::MemBioSlice;
9 use bn::BigNumRef;
10 use error::ErrorStack;
11 use util::{CallbackState, invoke_passwd_cb_old};
12
13 foreign_type! {
14 type CType = ffi::DSA;
15 fn drop = ffi::DSA_free;
16
17 pub struct Dsa;
18 pub struct DsaRef;
19 }
20
21 impl DsaRef {
22 private_key_to_pem!(ffi::PEM_write_bio_DSAPrivateKey);
23 public_key_to_pem!(ffi::PEM_write_bio_DSA_PUBKEY);
24
25 private_key_to_der!(ffi::i2d_DSAPrivateKey);
26 public_key_to_der!(ffi::i2d_DSAPublicKey);
27
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) }
32 } else {
33 None
34 }
35 }
36
37 pub fn p(&self) -> Option<&BigNumRef> {
38 unsafe {
39 let p = compat::pqg(self.as_ptr())[0];
40 if p.is_null() {
41 None
42 } else {
43 Some(BigNumRef::from_ptr(p as *mut _))
44 }
45 }
46 }
47
48 pub fn q(&self) -> Option<&BigNumRef> {
49 unsafe {
50 let q = compat::pqg(self.as_ptr())[1];
51 if q.is_null() {
52 None
53 } else {
54 Some(BigNumRef::from_ptr(q as *mut _))
55 }
56 }
57 }
58
59 pub fn g(&self) -> Option<&BigNumRef> {
60 unsafe {
61 let g = compat::pqg(self.as_ptr())[2];
62 if g.is_null() {
63 None
64 } else {
65 Some(BigNumRef::from_ptr(g as *mut _))
66 }
67 }
68 }
69
70 pub fn has_public_key(&self) -> bool {
71 unsafe { !compat::keys(self.as_ptr())[0].is_null() }
72 }
73
74 pub fn has_private_key(&self) -> bool {
75 unsafe { !compat::keys(self.as_ptr())[1].is_null() }
76 }
77 }
78
79 impl Dsa {
80 /// Generate a DSA key pair.
81 pub fn generate(bits: u32) -> Result<Dsa, ErrorStack> {
82 unsafe {
83 let dsa = Dsa(try!(cvt_p(ffi::DSA_new())));
84 try!(cvt(ffi::DSA_generate_parameters_ex(
85 dsa.0,
86 bits as c_int,
87 ptr::null(),
88 0,
89 ptr::null_mut(),
90 ptr::null_mut(),
91 ptr::null_mut(),
92 )));
93 try!(cvt(ffi::DSA_generate_key(dsa.0)));
94 Ok(dsa)
95 }
96 }
97
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);
102
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>
105 where
106 F: FnOnce(&mut [c_char]) -> usize,
107 {
108 ffi::init();
109 let mut cb = CallbackState::new(pass_cb);
110 let mem_bio = try!(MemBioSlice::new(buf));
111
112 unsafe {
113 let cb_ptr = &mut cb as *mut _ as *mut c_void;
114 let dsa = try!(cvt_p(ffi::PEM_read_bio_DSAPrivateKey(
115 mem_bio.as_ptr(),
116 ptr::null_mut(),
117 Some(invoke_passwd_cb_old::<F>),
118 cb_ptr,
119 )));
120 Ok(Dsa(dsa))
121 }
122 }
123 }
124
125 impl fmt::Debug for Dsa {
126 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
127 write!(f, "DSA")
128 }
129 }
130
131 #[cfg(ossl110)]
132 mod compat {
133 use std::ptr;
134 use ffi::{self, BIGNUM, DSA};
135
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);
139 [p, q, g]
140 }
141
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);
145 [pub_key, priv_key]
146 }
147 }
148
149 #[cfg(ossl10x)]
150 mod compat {
151 use ffi::{BIGNUM, DSA};
152
153 pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] {
154 [(*d).p, (*d).q, (*d).g]
155 }
156
157 pub unsafe fn keys(d: *const DSA) -> [*const BIGNUM; 2] {
158 [(*d).pub_key, (*d).priv_key]
159 }
160 }
161
162 #[cfg(test)]
163 mod test {
164 use symm::Cipher;
165
166 use super::*;
167
168 #[test]
169 pub fn test_generate() {
170 Dsa::generate(1024).unwrap();
171 }
172
173 #[test]
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();
177 }
178
179 #[test]
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")
183 .unwrap();
184 Dsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
185 assert!(Dsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
186 }
187
188 #[test]
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");
195 Ok(6)
196 }).unwrap();
197
198 assert!(password_queried);
199 }
200 }