]> git.proxmox.com Git - cargo.git/blob - vendor/openssl-0.9.15/src/rsa.rs
New upstream version 0.22.0
[cargo.git] / vendor / openssl-0.9.15 / src / rsa.rs
1 use ffi;
2 use std::fmt;
3 use std::ptr;
4 use std::mem;
5 use libc::{c_int, c_void, c_char};
6 use foreign_types::ForeignTypeRef;
7
8 use {cvt, cvt_p, cvt_n};
9 use bn::{BigNum, BigNumRef};
10 use bio::MemBioSlice;
11 use error::ErrorStack;
12 use util::{CallbackState, invoke_passwd_cb_old};
13
14 /// Type of encryption padding to use.
15 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
16 pub struct Padding(c_int);
17
18 impl Padding {
19 pub fn from_raw(value: c_int) -> Padding {
20 Padding(value)
21 }
22
23 pub fn as_raw(&self) -> c_int {
24 self.0
25 }
26 }
27
28 pub const NO_PADDING: Padding = Padding(ffi::RSA_NO_PADDING);
29 pub const PKCS1_PADDING: Padding = Padding(ffi::RSA_PKCS1_PADDING);
30 pub const PKCS1_OAEP_PADDING: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING);
31
32 foreign_type! {
33 type CType = ffi::RSA;
34 fn drop = ffi::RSA_free;
35
36 pub struct Rsa;
37 pub struct RsaRef;
38 }
39
40 impl RsaRef {
41 // FIXME these need to specify output format
42 private_key_to_pem!(ffi::PEM_write_bio_RSAPrivateKey);
43 public_key_to_pem!(ffi::PEM_write_bio_RSA_PUBKEY);
44
45 private_key_to_der!(ffi::i2d_RSAPrivateKey);
46 public_key_to_der!(ffi::i2d_RSA_PUBKEY);
47
48 to_der_inner!(
49 /// Serializes the public key to DER-encoded PKCS#1.
50 public_key_to_der_pkcs1,
51 ffi::i2d_RSAPublicKey
52 );
53
54 // FIXME should return u32
55 pub fn size(&self) -> usize {
56 unsafe {
57 assert!(self.n().is_some());
58
59 ffi::RSA_size(self.as_ptr()) as usize
60 }
61 }
62
63 /// Decrypts data using the private key, returning the number of decrypted bytes.
64 ///
65 /// # Panics
66 ///
67 /// Panics if `self` has no private components, or if `to` is smaller
68 /// than `self.size()`.
69 pub fn private_decrypt(
70 &self,
71 from: &[u8],
72 to: &mut [u8],
73 padding: Padding,
74 ) -> Result<usize, ErrorStack> {
75 assert!(self.d().is_some(), "private components missing");
76 assert!(from.len() <= i32::max_value() as usize);
77 assert!(to.len() >= self.size());
78
79 unsafe {
80 let len = try!(cvt_n(ffi::RSA_private_decrypt(
81 from.len() as c_int,
82 from.as_ptr(),
83 to.as_mut_ptr(),
84 self.as_ptr(),
85 padding.0,
86 )));
87 Ok(len as usize)
88 }
89 }
90
91 /// Encrypts data using the private key, returning the number of encrypted bytes.
92 ///
93 /// # Panics
94 ///
95 /// Panics if `self` has no private components, or if `to` is smaller
96 /// than `self.size()`.
97 pub fn private_encrypt(
98 &self,
99 from: &[u8],
100 to: &mut [u8],
101 padding: Padding,
102 ) -> Result<usize, ErrorStack> {
103 assert!(self.d().is_some(), "private components missing");
104 assert!(from.len() <= i32::max_value() as usize);
105 assert!(to.len() >= self.size());
106
107 unsafe {
108 let len = try!(cvt_n(ffi::RSA_private_encrypt(
109 from.len() as c_int,
110 from.as_ptr(),
111 to.as_mut_ptr(),
112 self.as_ptr(),
113 padding.0,
114 )));
115 Ok(len as usize)
116 }
117 }
118
119 /// Decrypts data using the public key, returning the number of decrypted bytes.
120 ///
121 /// # Panics
122 ///
123 /// Panics if `to` is smaller than `self.size()`.
124 pub fn public_decrypt(
125 &self,
126 from: &[u8],
127 to: &mut [u8],
128 padding: Padding,
129 ) -> Result<usize, ErrorStack> {
130 assert!(from.len() <= i32::max_value() as usize);
131 assert!(to.len() >= self.size());
132
133 unsafe {
134 let len = try!(cvt_n(ffi::RSA_public_decrypt(
135 from.len() as c_int,
136 from.as_ptr(),
137 to.as_mut_ptr(),
138 self.as_ptr(),
139 padding.0,
140 )));
141 Ok(len as usize)
142 }
143 }
144
145 /// Encrypts data using the public key, returning the number of encrypted bytes.
146 ///
147 /// # Panics
148 ///
149 /// Panics if `to` is smaller than `self.size()`.
150 pub fn public_encrypt(
151 &self,
152 from: &[u8],
153 to: &mut [u8],
154 padding: Padding,
155 ) -> Result<usize, ErrorStack> {
156 assert!(from.len() <= i32::max_value() as usize);
157 assert!(to.len() >= self.size());
158
159 unsafe {
160 let len = try!(cvt_n(ffi::RSA_public_encrypt(
161 from.len() as c_int,
162 from.as_ptr(),
163 to.as_mut_ptr(),
164 self.as_ptr(),
165 padding.0,
166 )));
167 Ok(len as usize)
168 }
169 }
170
171 pub fn n(&self) -> Option<&BigNumRef> {
172 unsafe {
173 let n = compat::key(self.as_ptr())[0];
174 if n.is_null() {
175 None
176 } else {
177 Some(BigNumRef::from_ptr(n as *mut _))
178 }
179 }
180 }
181
182 pub fn d(&self) -> Option<&BigNumRef> {
183 unsafe {
184 let d = compat::key(self.as_ptr())[2];
185 if d.is_null() {
186 None
187 } else {
188 Some(BigNumRef::from_ptr(d as *mut _))
189 }
190 }
191 }
192
193 pub fn e(&self) -> Option<&BigNumRef> {
194 unsafe {
195 let e = compat::key(self.as_ptr())[1];
196 if e.is_null() {
197 None
198 } else {
199 Some(BigNumRef::from_ptr(e as *mut _))
200 }
201 }
202 }
203
204 pub fn p(&self) -> Option<&BigNumRef> {
205 unsafe {
206 let p = compat::factors(self.as_ptr())[0];
207 if p.is_null() {
208 None
209 } else {
210 Some(BigNumRef::from_ptr(p as *mut _))
211 }
212 }
213 }
214
215 pub fn q(&self) -> Option<&BigNumRef> {
216 unsafe {
217 let q = compat::factors(self.as_ptr())[1];
218 if q.is_null() {
219 None
220 } else {
221 Some(BigNumRef::from_ptr(q as *mut _))
222 }
223 }
224 }
225 }
226
227 impl Rsa {
228 /// only useful for associating the key material directly with the key, it's safer to use
229 /// the supplied load and save methods for DER formatted keys.
230 pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa, ErrorStack> {
231 unsafe {
232 let rsa = Rsa(try!(cvt_p(ffi::RSA_new())));
233 try!(cvt(compat::set_key(
234 rsa.0,
235 n.as_ptr(),
236 e.as_ptr(),
237 ptr::null_mut(),
238 )));
239 mem::forget((n, e));
240 Ok(rsa)
241 }
242 }
243
244 pub fn from_private_components(
245 n: BigNum,
246 e: BigNum,
247 d: BigNum,
248 p: BigNum,
249 q: BigNum,
250 dp: BigNum,
251 dq: BigNum,
252 qi: BigNum,
253 ) -> Result<Rsa, ErrorStack> {
254 unsafe {
255 let rsa = Rsa(try!(cvt_p(ffi::RSA_new())));
256 try!(cvt(
257 compat::set_key(rsa.0, n.as_ptr(), e.as_ptr(), d.as_ptr()),
258 ));
259 mem::forget((n, e, d));
260 try!(cvt(compat::set_factors(rsa.0, p.as_ptr(), q.as_ptr())));
261 mem::forget((p, q));
262 try!(cvt(compat::set_crt_params(
263 rsa.0,
264 dp.as_ptr(),
265 dq.as_ptr(),
266 qi.as_ptr(),
267 )));
268 mem::forget((dp, dq, qi));
269 Ok(rsa)
270 }
271 }
272
273 /// Generates a public/private key pair with the specified size.
274 ///
275 /// The public exponent will be 65537.
276 pub fn generate(bits: u32) -> Result<Rsa, ErrorStack> {
277 ffi::init();
278 unsafe {
279 let rsa = Rsa(try!(cvt_p(ffi::RSA_new())));
280 let e = try!(BigNum::from_u32(ffi::RSA_F4 as u32));
281 try!(cvt(ffi::RSA_generate_key_ex(
282 rsa.0,
283 bits as c_int,
284 e.as_ptr(),
285 ptr::null_mut(),
286 )));
287 Ok(rsa)
288 }
289 }
290
291 // FIXME these need to identify input formats
292 private_key_from_pem!(Rsa, ffi::PEM_read_bio_RSAPrivateKey);
293 private_key_from_der!(Rsa, ffi::d2i_RSAPrivateKey);
294 public_key_from_pem!(Rsa, ffi::PEM_read_bio_RSA_PUBKEY);
295 public_key_from_der!(Rsa, ffi::d2i_RSA_PUBKEY);
296
297 from_der_inner!(
298 /// Deserializes a public key from DER-encoded PKCS#1 data.
299 public_key_from_der_pkcs1,
300 Rsa,
301 ffi::d2i_RSAPublicKey
302 );
303
304 #[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
305 pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Rsa, ErrorStack>
306 where
307 F: FnOnce(&mut [c_char]) -> usize,
308 {
309 ffi::init();
310 let mut cb = CallbackState::new(pass_cb);
311 let mem_bio = try!(MemBioSlice::new(buf));
312
313 unsafe {
314 let cb_ptr = &mut cb as *mut _ as *mut c_void;
315 let rsa = try!(cvt_p(ffi::PEM_read_bio_RSAPrivateKey(
316 mem_bio.as_ptr(),
317 ptr::null_mut(),
318 Some(invoke_passwd_cb_old::<F>),
319 cb_ptr,
320 )));
321 Ok(Rsa(rsa))
322 }
323 }
324 }
325
326 impl fmt::Debug for Rsa {
327 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
328 write!(f, "Rsa")
329 }
330 }
331
332 #[cfg(ossl110)]
333 mod compat {
334 use std::ptr;
335
336 use ffi::{self, BIGNUM, RSA};
337 use libc::c_int;
338
339 pub unsafe fn key(r: *const RSA) -> [*const BIGNUM; 3] {
340 let (mut n, mut e, mut d) = (ptr::null(), ptr::null(), ptr::null());
341 ffi::RSA_get0_key(r, &mut n, &mut e, &mut d);
342 [n, e, d]
343 }
344
345 pub unsafe fn factors(r: *const RSA) -> [*const BIGNUM; 2] {
346 let (mut p, mut q) = (ptr::null(), ptr::null());
347 ffi::RSA_get0_factors(r, &mut p, &mut q);
348 [p, q]
349 }
350
351 pub unsafe fn set_key(r: *mut RSA, n: *mut BIGNUM, e: *mut BIGNUM, d: *mut BIGNUM) -> c_int {
352 ffi::RSA_set0_key(r, n, e, d)
353 }
354
355 pub unsafe fn set_factors(r: *mut RSA, p: *mut BIGNUM, q: *mut BIGNUM) -> c_int {
356 ffi::RSA_set0_factors(r, p, q)
357 }
358
359 pub unsafe fn set_crt_params(
360 r: *mut RSA,
361 dmp1: *mut BIGNUM,
362 dmq1: *mut BIGNUM,
363 iqmp: *mut BIGNUM,
364 ) -> c_int {
365 ffi::RSA_set0_crt_params(r, dmp1, dmq1, iqmp)
366 }
367 }
368
369 #[cfg(ossl10x)]
370 mod compat {
371 use libc::c_int;
372 use ffi::{BIGNUM, RSA};
373
374 pub unsafe fn key(r: *const RSA) -> [*const BIGNUM; 3] {
375 [(*r).n, (*r).e, (*r).d]
376 }
377
378 pub unsafe fn factors(r: *const RSA) -> [*const BIGNUM; 2] {
379 [(*r).p, (*r).q]
380 }
381
382 pub unsafe fn set_key(r: *mut RSA, n: *mut BIGNUM, e: *mut BIGNUM, d: *mut BIGNUM) -> c_int {
383 (*r).n = n;
384 (*r).e = e;
385 (*r).d = d;
386 1 // TODO: is this right? should it be 0? what's success?
387 }
388
389 pub unsafe fn set_factors(r: *mut RSA, p: *mut BIGNUM, q: *mut BIGNUM) -> c_int {
390 (*r).p = p;
391 (*r).q = q;
392 1 // TODO: is this right? should it be 0? what's success?
393 }
394
395 pub unsafe fn set_crt_params(
396 r: *mut RSA,
397 dmp1: *mut BIGNUM,
398 dmq1: *mut BIGNUM,
399 iqmp: *mut BIGNUM,
400 ) -> c_int {
401 (*r).dmp1 = dmp1;
402 (*r).dmq1 = dmq1;
403 (*r).iqmp = iqmp;
404 1 // TODO: is this right? should it be 0? what's success?
405 }
406 }
407
408 #[cfg(test)]
409 mod test {
410 use symm::Cipher;
411
412 use super::*;
413
414 #[test]
415 fn test_from_password() {
416 let key = include_bytes!("../test/rsa-encrypted.pem");
417 Rsa::private_key_from_pem_passphrase(key, b"mypass").unwrap();
418 }
419
420 #[test]
421 fn test_from_password_callback() {
422 let mut password_queried = false;
423 let key = include_bytes!("../test/rsa-encrypted.pem");
424 Rsa::private_key_from_pem_callback(key, |password| {
425 password_queried = true;
426 password[..6].copy_from_slice(b"mypass");
427 Ok(6)
428 }).unwrap();
429
430 assert!(password_queried);
431 }
432
433 #[test]
434 fn test_to_password() {
435 let key = Rsa::generate(2048).unwrap();
436 let pem = key.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
437 .unwrap();
438 Rsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
439 assert!(Rsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
440 }
441
442 #[test]
443 fn test_public_encrypt_private_decrypt_with_padding() {
444 let key = include_bytes!("../test/rsa.pem.pub");
445 let public_key = Rsa::public_key_from_pem(key).unwrap();
446
447 let mut result = vec![0; public_key.size()];
448 let original_data = b"This is test";
449 let len = public_key
450 .public_encrypt(original_data, &mut result, PKCS1_PADDING)
451 .unwrap();
452 assert_eq!(len, 256);
453
454 let pkey = include_bytes!("../test/rsa.pem");
455 let private_key = Rsa::private_key_from_pem(pkey).unwrap();
456 let mut dec_result = vec![0; private_key.size()];
457 let len = private_key
458 .private_decrypt(&result, &mut dec_result, PKCS1_PADDING)
459 .unwrap();
460
461 assert_eq!(&dec_result[..len], original_data);
462 }
463
464 #[test]
465 fn test_private_encrypt() {
466 let k0 = super::Rsa::generate(512).unwrap();
467 let k0pkey = k0.public_key_to_pem().unwrap();
468 let k1 = super::Rsa::public_key_from_pem(&k0pkey).unwrap();
469
470 let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
471
472 let mut emesg = vec![0; k0.size()];
473 k0.private_encrypt(&msg, &mut emesg, PKCS1_PADDING).unwrap();
474 let mut dmesg = vec![0; k1.size()];
475 let len = k1.public_decrypt(&emesg, &mut dmesg, PKCS1_PADDING)
476 .unwrap();
477 assert_eq!(msg, &dmesg[..len]);
478 }
479
480 #[test]
481 fn test_public_encrypt() {
482 let k0 = super::Rsa::generate(512).unwrap();
483 let k0pkey = k0.private_key_to_pem().unwrap();
484 let k1 = super::Rsa::private_key_from_pem(&k0pkey).unwrap();
485
486 let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
487
488 let mut emesg = vec![0; k0.size()];
489 k0.public_encrypt(&msg, &mut emesg, PKCS1_PADDING).unwrap();
490 let mut dmesg = vec![0; k1.size()];
491 let len = k1.private_decrypt(&emesg, &mut dmesg, PKCS1_PADDING)
492 .unwrap();
493 assert_eq!(msg, &dmesg[..len]);
494 }
495 }