1extern crate num;
2extern crate simple_asn1;
3extern crate rand;
4
5use num::bigint::{BigInt};
6use simple_asn1::{from_der, ASN1Block};
7use rand::Rng;
8
9fn find_bitstrings(asns: Vec<ASN1Block>, mut result: &mut Vec<Vec<u8>>) {
10 for asn in asns.iter() {
11 match asn {
12 ASN1Block::BitString(_, _, bytes) => result.push(bytes.to_vec()),
13 ASN1Block::Sequence(_, blocks) => find_bitstrings(blocks.to_vec(), &mut result),
14 _ => (),
15 }
16 }
17}
18
19pub fn encrypt(der_pubkey: &[u8], message: &[u8]) -> Result<Vec<u8>, String> {
20 let asns: Vec<ASN1Block> = from_der(&der_pubkey).map_err(|err| err.to_string())?;
22 let mut result: Vec<Vec<u8>> = vec![];
23 find_bitstrings(asns, &mut result);
24 if result.len() == 0 {
25 return Err("ASN.1 BitString not found in DER encoding of public key".to_string());
26 }
27
28 let inner_asn: Vec<ASN1Block> = from_der(&result[0]).map_err(|err| err.to_string())?;
29 let (n, e) =
30 match &inner_asn[0] {
31 ASN1Block::Sequence(_, blocks) => {
32 if blocks.len() != 2 {
33 return Err("ASN.1 sequence bad length, expected exactly two blocks in inner Sequence".to_string());
34 }
35
36 let n = match &blocks[0] {
37 ASN1Block::Integer(_, n) => n,
38 _ => return Err("ASN.1 Integer modulus not found".to_string()),
39 };
40
41 let e = match &blocks[1] {
42 ASN1Block::Integer(_, e) => e,
43 _ => return Err("ASN.1 Integer exponent not found".to_string()),
44 };
45 (n, e)
46
47 },
48 _ => return Err("ASN.1 Sequence not found".to_string()),
49 };
50
51 let k = (n.bits() / 8) as usize; if message.len() > k - 11 {
62 return Err("PKCS#1 error: message too long".to_string());
63 }
64
65 let mut padding = vec![1; k - message.len() - 3];
73 let mut i = 0;
74 while i < padding.len() {
75 padding[i] = rand::thread_rng().gen_range(1..255);
76 i += 1;
77 }
78
79 let mut encoded_m = vec![0x00, 0x02];
85 encoded_m.append(&mut padding.to_vec());
86 encoded_m.append(&mut vec![0x00]);
87 encoded_m.extend_from_slice(&message);
88
89 let m = BigInt::from_bytes_be(num::bigint::Sign::Plus, &encoded_m);
98
99 if m.sign() != num::bigint::Sign::Plus || m > n - 1 {
110 return Err("RSA error: message representative out of range".to_string());
111 }
112
113 let ciphertext_bigint = m.modpow(e, n);
115
116 let (_sign, ciphertext) = ciphertext_bigint.to_bytes_be();
123
124 return Ok(ciphertext);
125}
126
127
128#[cfg(test)]
129mod tests {
130 use crate::encrypt;
131 #[test]
132 fn it_works() {
133 assert_eq!(2 + 2, 4);
134 assert_eq!(encrypt(&[], &[]), Err("Encountered an empty buffer decoding ASN1 block.".to_string()));
135 let pk = [48, 129, 159, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, 141, 0, 48, 129, 137, 2, 129, 129, 0, 149, 92, 126, 71, 214, 186, 100, 139, 40, 104, 65, 254, 200, 105, 71, 66, 241, 84, 172, 206, 206, 217, 49, 214, 16, 50, 6, 234, 97, 21, 170, 139, 234, 88, 220, 105, 27, 115, 56, 103, 53, 234, 84, 255, 129, 147, 41, 146, 68, 39, 120, 208, 141, 142, 39, 242, 182, 97, 4, 204, 236, 190, 104, 101, 234, 46, 71, 248, 55, 88, 213, 56, 145, 154, 142, 184, 144, 55, 105, 241, 179, 205, 174, 107, 40, 77, 46, 201, 197, 51, 20, 246, 95, 207, 227, 5, 210, 42, 107, 135, 219, 126, 207, 216, 181, 2, 130, 57, 203, 239, 232, 68, 220, 131, 211, 86, 168, 125, 193, 91, 148, 153, 109, 76, 109, 50, 2, 139, 2, 3, 1, 0, 1];
148
149 assert_eq!(encrypt(&pk, &[0; 128]), Err("PKCS#1 error: message too long".to_string()));
151 assert_eq!(encrypt(&pk, &[0; 128-1]), Err("PKCS#1 error: message too long".to_string()));
152 assert_eq!(encrypt(&pk, &[0; 128-2]), Err("PKCS#1 error: message too long".to_string()));
153 assert_eq!(encrypt(&pk, &[0; 128-10]), Err("PKCS#1 error: message too long".to_string()));
154
155 assert_eq!(encrypt(&pk, &[]).is_ok(), true);
158 assert_eq!(encrypt(&pk, &[1, 2, 3, 4]).is_ok(), true);
159 assert_eq!(encrypt(&pk, &[0; 128-11]).is_ok(), true);
160 }
161}
162
163