Codebase list libcryptx-perl / 29b310e
RSA DSA DH improvements Karel Miko 6 years ago
13 changed file(s) with 391 addition(s) and 228 deletion(s). Raw diff Collapse all Expand all
1616 RETVAL
1717
1818 void
19 _generate_key(Crypt::PK::DH self, int groupsize=256)
19 _generate_key_size(Crypt::PK::DH self, int groupsize=256)
2020 PPCODE:
2121 {
2222 int rv;
2828 }
2929
3030 void
31 _generate_key_ex(Crypt::PK::DH self, char *g, char *p)
31 _generate_key_gp(Crypt::PK::DH self, char *g, char *p)
3232 PPCODE:
3333 {
3434 int rv;
4040 if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(p) failed: %s", error_to_string(rv));
4141 rv = radix_to_bin(g, 16, gbin, &glen);
4242 if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(g) failed: %s", error_to_string(rv));
43
43
4444 rv = dh_set_pg(pbin, plen, gbin, glen, &self->key);
4545 if (rv != CRYPT_OK) croak("FATAL: dh_set_pg failed: %s", error_to_string(rv));
4646 rv = dh_generate_key(&self->pstate, self->pindex, &self->key);
5151 }
5252
5353 void
54 _generate_key_dhparam(Crypt::PK::DH self, SV * dhparam)
55 PPCODE:
56 {
57 int rv;
58 unsigned char *data=NULL;
59 STRLEN data_len=0;
60 data = (unsigned char *)SvPVbyte(dhparam, data_len);
61 /* load d p q */
62 rv = dh_set_pg_dhparam(data, data_len, &self->key);
63 if (rv != CRYPT_OK) croak("FATAL: dh_set_pg_dhparam failed: %s", error_to_string(rv));
64 /* gen the key */
65 rv = dh_generate_key(&self->pstate, self->pindex, &self->key);
66 if (rv != CRYPT_OK) croak("FATAL: dh_generate_key failed: %s", error_to_string(rv));
67 XPUSHs(ST(0)); /* return self */
68 }
69
70 void
5471 _import(Crypt::PK::DH self, SV * key_data)
5572 PPCODE:
5673 {
7289 int rv;
7390 unsigned char *data=NULL;
7491 STRLEN data_len=0;
92 unsigned char pbin[1024], gbin[512];
93 unsigned long plen=sizeof(pbin), glen=sizeof(gbin);
7594
7695 data = (unsigned char *)SvPVbyte(raw_key, data_len);
7796 if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
78
79 unsigned char pbin[1024], gbin[512];
80 unsigned long plen=sizeof(pbin), glen=sizeof(gbin);
8197
8298 if (p && strlen(p) > 0 && g && strlen(g) > 0) {
8399 rv = radix_to_bin(p, 16, pbin, &plen);
84100 if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(p) failed: %s", error_to_string(rv));
85101 rv = radix_to_bin(g, 16, gbin, &glen);
86102 if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(g) failed: %s", error_to_string(rv));
87
103
88104 rv = dh_set_pg(pbin, plen, gbin, glen, &self->key);
89105 if (rv != CRYPT_OK) croak("FATAL: dh_set_pg failed: %s", error_to_string(rv));
90106
91107 if (type == 0) {
92108 /* public */
93 rv = dh_set_key(data, (unsigned long)data_len, NULL, 0, &self->key);
109 rv = dh_set_key(data, (unsigned long)data_len, PK_PUBLIC, &self->key);
94110 if (rv != CRYPT_OK) croak("FATAL: dh_set_key failed: %s", error_to_string(rv));
95111 }
96112 else if (type == 1) {
97113 /* private */
98 rv = dh_set_key(NULL, 0, data, (unsigned long)data_len, &self->key);
114 rv = dh_set_key(data, (unsigned long)data_len, PK_PRIVATE, &self->key);
99115 if (rv != CRYPT_OK) croak("FATAL: dh_set_key failed: %s", error_to_string(rv));
100116 }
101117 else {
257273 RETVAL
258274
259275 SV *
260 _encrypt(Crypt::PK::DH self, SV * data, char * hash_name)
261 CODE:
262 {
263 /* XXXXXXXXXXXXXXXXXXXXX
264 int rv, hash_id;
265 unsigned char *data_ptr=NULL;
266 STRLEN data_len=0;
267 unsigned long buffer_len = 1024;
268 unsigned char buffer[1024];
269
270 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
271
272 hash_id = find_hash(hash_name);
273 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name);
274 rv = dh_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
275 &self->pstate, self->pindex,
276 hash_id, &self->key);
277 if (rv != CRYPT_OK) croak("FATAL: dh_encrypt_key failed: %s", error_to_string(rv));
278 RETVAL = newSVpvn((char*)buffer, buffer_len);
279 */
280 }
281 OUTPUT:
282 RETVAL
283
284 SV *
285 _decrypt(Crypt::PK::DH self, SV * data)
286 CODE:
287 {
288 /* XXXXXXXXXXXXXXXXXXXXX
289 int rv;
290 unsigned char *data_ptr=NULL;
291 STRLEN data_len=0;
292 unsigned long buffer_len = 1024;
293 unsigned char buffer[1024];
294
295 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
296
297 rv = dh_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key);
298 if (rv != CRYPT_OK) croak("FATAL: dh_decrypt_key failed: %s", error_to_string(rv));
299 RETVAL = newSVpvn((char*)buffer, buffer_len);
300 */
301 }
302 OUTPUT:
303 RETVAL
304
305 SV *
306 _sign(Crypt::PK::DH self, SV * data)
307 CODE:
308 {
309 /* XXXXXXXXXXXXXXXXXXXXX
310 int rv;
311 unsigned char *data_ptr=NULL;
312 STRLEN data_len=0;
313 unsigned long buffer_len = 1024;
314 unsigned char buffer[1024];
315
316 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
317
318 rv = dh_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
319 &self->pstate, self->pindex,
320 &self->key);
321 if (rv != CRYPT_OK) croak("FATAL: dh_sign_hash failed: %s", error_to_string(rv));
322 RETVAL = newSVpvn((char*)buffer, buffer_len);
323 */
324 }
325 OUTPUT:
326 RETVAL
327
328 int
329 _verify(Crypt::PK::DH self, SV * sig, SV * data)
330 CODE:
331 {
332 /* XXXXXXXXXXXXXXXXXXXXX
333 int rv, stat;
334 unsigned char *data_ptr=NULL;
335 STRLEN data_len=0;
336 unsigned char *sig_ptr=NULL;
337 STRLEN sig_len=0;
338
339 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
340 sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
341
342 RETVAL = 1;
343 rv = dh_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
344 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
345 */
346 }
347 OUTPUT:
348 RETVAL
349
350 SV *
351276 shared_secret(Crypt::PK::DH self, Crypt::PK::DH pubkey)
352277 CODE:
353278 {
367292 CODE:
368293 {
369294 int rv;
370 unsigned long len, buffer_len = 1024;
371 unsigned char buffer[1024];
372 void *key;
295 unsigned char out[1024];
296 unsigned long out_len = 1024;
373297
374298 RETVAL = newSVpvn(NULL, 0); /* undef */
375299 if (strnEQ(type, "private", 7)) {
376 key = self->key.x;
300 rv = dh_export_key(out, &out_len, PK_PRIVATE, &self->key);
301 if (rv != CRYPT_OK) croak("FATAL: dh_export_key(PK_PRIVATE) failed: %s", error_to_string(rv));
302 RETVAL = newSVpvn((char*)out, out_len);
377303 }
378304 else if (strnEQ(type, "public", 6)) {
379 key = self->key.y;
305 rv = dh_export_key(out, &out_len, PK_PUBLIC, &self->key);
306 if (rv != CRYPT_OK) croak("FATAL: dh_export_key(PK_PUBLIC) failed: %s", error_to_string(rv));
307 RETVAL = newSVpvn((char*)out, out_len);
380308 }
381309 else {
382310 croak("FATAL: export_key_raw: invalid type '%s'", type);
383311 }
384
385 len = (unsigned long)mp_unsigned_bin_size(key);
386 if (buffer_len < len) {
387 croak("FATAL: %s", error_to_string(CRYPT_BUFFER_OVERFLOW));
388 }
389 rv = mp_to_unsigned_bin(key, buffer);
390 if (rv != CRYPT_OK) croak("FATAL: %s", error_to_string(rv));
391 RETVAL = newSVpvn((char*)buffer, len);
392 }
393 OUTPUT:
394 RETVAL
395
396 int
397 _is_pubkey_valid(Crypt::PK::DH self);
398 CODE:
399 {
400 int rv, i, bits_set = 0;
401 mp_int one, two, p1, *y;
402 mp_digit digit;
403
404 if ((rv = mp_init_multi(&one, &two, &p1, NULL)) != MP_OKAY) {
405 croak("FATAL: %s", error_to_string(rv));
406 }
407
408 y = self->key.y;
409 mp_set(&one, 1);
410 mp_set(&two, 2);
411
412 /* p1 = p-1 */
413 if ((rv = mp_sub(self->key.prime, &one, &p1)) != MP_OKAY) {
414 croak("FATAL: %s", error_to_string(rv));
415 }
416 /* valid public key cannot be negative */
417 if (y->sign == MP_NEG) {
418 RETVAL = 0;
419 }
420 /* valid public key != 1 */
421 else if (mp_cmp(y, &one) == MP_EQ) {
422 RETVAL = 0;
423 }
424 /* public key cannot be > p-1 */
425 else if (mp_cmp(y, &p1) == MP_GT) {
426 RETVAL = 0;
427 }
428 /* if base == 2, public must have more than one bit set */
429 else if (mp_cmp(self->key.base, &two) == MP_EQ) {
430 for (i = 0; i < y->used; i++) {
431 digit = y->dp[i];
432 while (digit > ((mp_digit) 0)) {
433 if (digit & ((mp_digit) 1))
434 bits_set++;
435 digit >>= ((mp_digit) 1);
436 }
437 }
438 if (bits_set > 1)
439 RETVAL = 1;
440 else RETVAL = 0;
441 }
442 else RETVAL = 1;
443312 }
444313 OUTPUT:
445314 RETVAL
449318 CODE:
450319 if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
451320 Safefree(self);
452
1616 RETVAL
1717
1818 void
19 generate_key(Crypt::PK::DSA self, int group_size=30, int modulus_size=256)
19 _generate_key_size(Crypt::PK::DSA self, int group_size=30, int modulus_size=256)
2020 PPCODE:
2121 {
2222 int rv;
2323 /* gen the key */
2424 rv = dsa_make_key(&self->pstate, self->pindex, group_size, modulus_size, &self->key);
2525 if (rv != CRYPT_OK) croak("FATAL: dsa_make_key failed: %s", error_to_string(rv));
26 XPUSHs(ST(0)); /* return self */
27 }
28
29 void
30 _generate_key_dsaparam(Crypt::PK::DSA self, SV * dsaparam)
31 PPCODE:
32 {
33 int rv;
34 unsigned char *data=NULL;
35 STRLEN data_len=0;
36 data = (unsigned char *)SvPVbyte(dsaparam, data_len);
37 /* load d p q */
38 rv = dsa_set_pqg_dsaparam(data, data_len, &self->key);
39 if (rv != CRYPT_OK) croak("FATAL: dsa_set_pqg_dsaparam failed: %s", error_to_string(rv));
40 /* gen the key */
41 rv = dsa_generate_key(&self->pstate, self->pindex, &self->key);
42 if (rv != CRYPT_OK) croak("FATAL: dsa_generate_key failed: %s", error_to_string(rv));
43 XPUSHs(ST(0)); /* return self */
44 }
45
46 void
47 _generate_key_pqg(Crypt::PK::DSA self, SV * psv, SV * qsv, SV * gsv)
48 PPCODE:
49 {
50 int rv;
51 unsigned char *p=NULL, *q=NULL, *g=NULL;
52 STRLEN plen=0, qlen=0, glen=0;
53 p = (unsigned char *)SvPVbyte(psv, plen);
54 q = (unsigned char *)SvPVbyte(qsv, qlen);
55 g = (unsigned char *)SvPVbyte(gsv, glen);
56 /* set p q g */
57 rv = dsa_set_pqg(p, plen, q, qlen, g, glen, &self->key);
58 if (rv != CRYPT_OK) croak("FATAL: dsa_set_pqg failed: %s", error_to_string(rv));
59 /* gen the key */
60 rv = dsa_generate_key(&self->pstate, self->pindex, &self->key);
61 if (rv != CRYPT_OK) croak("FATAL: dsa_generate_key failed: %s", error_to_string(rv));
2662 XPUSHs(ST(0)); /* return self */
2763 }
2864
67103 /* private */
68104 rv = radix_to_bin(x, 16, xbin, &xlen);
69105 if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(x) failed: %s", error_to_string(rv));
70 rv = dsa_set_key(ybin, ylen, xbin, xlen, &self->key);
106 rv = dsa_set_key(xbin, xlen, PK_PRIVATE, &self->key);
71107 if (rv != CRYPT_OK) croak("FATAL: dsa_set_key failed: %s", error_to_string(rv));
72108 }
73109 else {
74110 /* public */
75 rv = dsa_set_key(ybin, ylen, NULL, 0, &self->key);
111 rv = dsa_set_key(ybin, ylen, PK_PUBLIC, &self->key);
76112 if (rv != CRYPT_OK) croak("FATAL: dsa_set_key failed: %s", error_to_string(rv));
77113 }
78114 }
4545 }
4646
4747 void
48 _import_pkcs8(Crypt::PK::ECC self, SV * key_data)
48 _import_pkcs8(Crypt::PK::ECC self, SV * key_data, SV * passwd)
49 PPCODE:
50 {
51 int rv;
52 unsigned char *data=NULL, *pwd=NULL;
53 STRLEN data_len=0, pwd_len=0;
54
55 data = (unsigned char *)SvPVbyte(key_data, data_len);
56 if (SvOK(passwd)) {
57 pwd = (unsigned char *)SvPVbyte(passwd, pwd_len);
58 }
59 _ecc_free_key(&self->key, &self->dp);
60 rv = ecc_import_pkcs8(data, (unsigned long)data_len, pwd, pwd_len, &self->key, &self->dp);
61 if (rv != CRYPT_OK) croak("FATAL: ecc_import_pkcs8 failed: %s", error_to_string(rv));
62 XPUSHs(ST(0)); /* return self */
63 }
64
65 void
66 import_key_raw(Crypt::PK::ECC self, SV * key_data, SV * curve)
4967 PPCODE:
5068 {
5169 int rv;
5472
5573 data = (unsigned char *)SvPVbyte(key_data, data_len);
5674 _ecc_free_key(&self->key, &self->dp);
57 rv = ecc_import_pkcs8(data, (unsigned long)data_len, NULL, 0, &self->key, &self->dp);
58 if (rv != CRYPT_OK) croak("FATAL: ecc_import_pkcs8 failed: %s", error_to_string(rv));
59 XPUSHs(ST(0)); /* return self */
60 }
61
62 void
63 import_key_raw(Crypt::PK::ECC self, SV * key_data, SV * curve)
64 PPCODE:
65 {
66 int rv;
67 unsigned char *data=NULL;
68 STRLEN data_len=0;
69
70 data = (unsigned char *)SvPVbyte(key_data, data_len);
71 _ecc_free_key(&self->key, &self->dp);
72
75
7376 _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */
74
77
7578 rv = ecc_import_raw(data, (unsigned long)data_len, &self->key, &self->dp);
7679 if (rv != CRYPT_OK) croak("FATAL: ecc_import_raw failed: %s", error_to_string(rv));
7780 XPUSHs(ST(0)); /* return self */
4343 }
4444
4545 void
46 _import_pkcs8(Crypt::PK::RSA self, SV * key_data)
46 _import_pkcs8(Crypt::PK::RSA self, SV * key_data, SV * passwd)
47 PPCODE:
48 {
49 int rv;
50 unsigned char *data=NULL, *pwd=NULL;
51 STRLEN data_len=0, pwd_len=0;
52
53 data = (unsigned char *)SvPVbyte(key_data, data_len);
54 if (SvOK(passwd)) {
55 pwd = (unsigned char *)SvPVbyte(passwd, pwd_len);
56 }
57 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
58 rv = rsa_import_pkcs8(data, (unsigned long)data_len, pwd, pwd_len, &self->key);
59 if (rv != CRYPT_OK) croak("FATAL: rsa_import_pkcs8 failed: %s", error_to_string(rv));
60 XPUSHs(ST(0)); /* return self */
61 }
62
63 void
64 _import_x509(Crypt::PK::RSA self, SV * key_data)
4765 PPCODE:
4866 {
4967 int rv;
5270
5371 data = (unsigned char *)SvPVbyte(key_data, data_len);
5472 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
55 rv = rsa_import_pkcs8(data, (unsigned long)data_len, NULL, 0, &self->key);
56 if (rv != CRYPT_OK) croak("FATAL: rsa_import_pkcs8 failed: %s", error_to_string(rv));
73 rv = rsa_import_x509(data, (unsigned long)data_len, &self->key);
74 if (rv != CRYPT_OK) croak("FATAL: rsa_import_x509 failed: %s", error_to_string(rv));
5775 XPUSHs(ST(0)); /* return self */
5876 }
5977
247265 {
248266 int rv;
249267 unsigned char out[4096];
250 unsigned long int out_len = 4096;
268 unsigned long out_len = 4096;
251269
252270 RETVAL = newSVpvn(NULL, 0); /* undef */
253271 if (strnEQ(type, "private", 7)) {
456474 CODE:
457475 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
458476 Safefree(self);
459
1111 use Carp;
1212 use CryptX;
1313 use Crypt::Digest 'digest_data';
14 use Crypt::Misc qw(read_rawfile);
14 use Crypt::Misc qw(read_rawfile pem_to_der);
15 use Scalar::Util 'looks_like_number';
1516
1617 my %DH_PARAMS = (
1718 ike768 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'.
214215 croak "FATAL: invalid key type '$type'";
215216 }
216217 my $rv = $self->_import_raw($raw_bytes, $type, $g, $p);
217 croak "FATAL: invalid public key" unless $self->_is_pubkey_valid;
218218 return $rv;
219219 }
220220
221221 sub generate_key {
222 my ($key,$param) = @_;
222 my ($self, $param) = @_;
223223
224224 if (!ref $param) {
225 if (my $dhparam = $DH_PARAMS{$param}) {
226 $param = $dhparam;
227 } else {
228 croak "FATAL: invalid key length" unless ($param >= 96 || $param <= 512);
229 return $key->_generate_key($param);
230 }
231 }
232 my $g = $param->{g} or croak "FATAL: 'g' param not specified";
233 my $p = $param->{p} or croak "FATAL: 'p' param not specified";
234 $g =~ s/^0x//;
235 $p =~ s/^0x//;
236 return $key->_generate_key_ex($g, $p);
225 # group name
226 return $self->_generate_key_gp($DH_PARAMS{$param}{g}, $DH_PARAMS{$param}{p}) if $DH_PARAMS{$param};
227 # size
228 return $self->_generate_key_size($param) if looks_like_number($param);
229 }
230 elsif (ref $param eq 'SCALAR') {
231 my $data = $$param;
232 $data = pem_to_der($data) if $data =~ /-----BEGIN DH PARAMETERS-----\s*(.+)\s*-----END DH PARAMETERS-----/s;
233 return $self->_generate_key_dhparam($data);
234 }
235 elsif (ref $param eq 'HASH') {
236 my $g = $param->{g} or croak "FATAL: 'g' param not specified";
237 my $p = $param->{p} or croak "FATAL: 'p' param not specified";
238 $g =~ s/^0x//;
239 $p =~ s/^0x//;
240 return $self->_generate_key_gp($g, $p);
241 }
242 croak "FATAL: DH generate_key - invalid args";
237243 }
238244
239245 ### FUNCTIONS
334340
335341 The following variants are available since CryptX-0.032
336342
337 $pk->generate_key($name)
338 ### $name corresponds to values defined in RFC7296 and RFC3526
339 # ike768 => 768-bit MODP (Group 1)
340 # ike1024 => 1024-bit MODP (Group 2)
341 # ike1536 => 1536-bit MODP (Group 5)
342 # ike2048 => 2048-bit MODP (Group 14)
343 # ike3072 => 3072-bit MODP (Group 15)
344 # ike4096 => 4096-bit MODP (Group 16)
345 # ike6144 => 6144-bit MODP (Group 17)
346 # ike8192 => 8192-bit MODP (Group 18)
343 $pk->generate_key($groupname)
344 ### $groupname corresponds to values defined in RFC7296 and RFC3526
345 # 'ike768' => 768-bit MODP (Group 1)
346 # 'ike1024' => 1024-bit MODP (Group 2)
347 # 'ike1536' => 1536-bit MODP (Group 5)
348 # 'ike2048' => 2048-bit MODP (Group 14)
349 # 'ike3072' => 3072-bit MODP (Group 15)
350 # 'ike4096' => 4096-bit MODP (Group 16)
351 # 'ike6144' => 6144-bit MODP (Group 17)
352 # 'ike8192' => 8192-bit MODP (Group 18)
347353
348354 $pk->generate_key($param_hash)
349 ## $param_hash is { g => $g, p => $p }
350 ## where $g is the generator (base) in a hex string and $p is the prime in a hex string
355 # $param_hash is { g => $g, p => $p }
356 # where $g is the generator (base) in a hex string and $p is the prime in a hex string
357
358 $pk->generate_key(\$dh_param)
359 # $dh_param is the content of DER or PEM file with DH params
360 # e.g. openssl dhparam 2048
351361
352362 =head2 import_key
353363
1919 my $self = _new();
2020 $self->import_key($f, $p) if $f;
2121 return $self;
22 }
23
24 sub generate_key {
25 my $self = shift;
26 return $self->_generate_key_size(@_) if @_ == 2;
27 if (@_ == 1 && ref $_[0] eq 'HASH') {
28 my $param = shift;
29 my $p = $param->{p} or croak "FATAL: 'p' param not specified";
30 my $q = $param->{q} or croak "FATAL: 'q' param not specified";
31 my $g = $param->{g} or croak "FATAL: 'g' param not specified";
32 $p =~ s/^0x//;
33 $q =~ s/^0x//;
34 $g =~ s/^0x//;
35 return $self->_generate_key_pqg($p, $q, $g);
36 }
37 elsif (@_ == 1 && ref $_[0] eq 'SCALAR') {
38 my $data = ${$_[0]};
39 $data = pem_to_der($data) if $data =~ /-----BEGIN DSA PARAMETERS-----\s*(.+)\s*-----END DSA PARAMETERS-----/s;
40 return $self->_generate_key_dsaparam($data);
41 }
42 croak "FATAL: DSA generate_key - invalid args";
2243 }
2344
2445 sub export_key_pem {
251272 # L = 2048, N = 256 => generate_key(32, 256)
252273 # L = 3072, N = 256 => generate_key(32, 384)
253274
275 $pk->generate_key($param_hash)
276 # $param_hash is { d => $d, p => $p, q => $q }
277 # where $d, $p, $q are hex strings
278
279 $pk->generate_key(\$dsa_param)
280 # $dsa_param is the content of DER or PEM file with DSA params
281 # e.g. openssl dsaparam 2048
282
254283 =head2 import_key
255284
256285 Loads private or public key in DER or PEM format.
529529 }
530530 elsif ($data =~ /-----BEGIN PRIVATE KEY-----(.*?)-----END/sg) {
531531 $data = pem_to_der($data, $password);
532 return $self->_import_pkcs8($data);
532 return $self->_import_pkcs8($data, $password);
533533 }
534534 elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) {
535535 # XXX-TODO: pkcs#8 encrypted private key
561561 return $self->import_key_raw($pubkey, "$2") if $pubkey && $typ =~ /^ecdsa-(.+?)-(.*)$/;
562562 }
563563 else {
564 my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data) };
564 my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data, $password) };
565565 return $rv if $rv;
566566 }
567567 croak "FATAL: invalid or unsupported EC key format";
124124 elsif ($data =~ /-----BEGIN PRIVATE KEY-----(.*?)-----END/sg) {
125125 # PKCS#8 PrivateKeyInfo (PEM header: BEGIN PRIVATE KEY)
126126 $data = pem_to_der($data, $password);
127 return $self->_import_pkcs8($data) if $data;
127 return $self->_import_pkcs8($data, $password) if $data;
128128 }
129129 elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) {
130130 # XXX-TODO: PKCS#8 EncryptedPrivateKeyInfo (PEM header: BEGIN ENCRYPTED PRIVATE KEY)
141141 return $self->_import_hex($h->{n}, $h->{e}, $h->{d}, $h->{p}, $h->{q}, $h->{dp}, $h->{dq}, $h->{qi}) if $h->{n} && $h->{e};
142142 }
143143 }
144 elsif ($data =~ /-----BEGIN CERTIFICATE-----(.*?)-----END CERTIFICATE-----/sg) {
145 $data = pem_to_der($data);
146 return $self->_import_x509($data);
147 }
144148 elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) {
145149 $data = pem_to_der($data);
146150 my ($typ, $N, $e) = Crypt::PK::_ssh_parse($data);
153157 }
154158 else {
155159 # DER format
156 my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data) };
160 my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data, $password) } || eval { $self->_import_x509($data) };
157161 return $rv if $rv;
158162 }
159163
478482 1HPwZX2d
479483 -----END ENCRYPTED PRIVATE KEY-----
480484
485 =item * RSA public key from X509 certificate
486
487 -----BEGIN CERTIFICATE-----
488 MIIC8zCCAdugAwIBAgIJAPi+LvMU3uGWMA0GCSqGSIb3DQEBCwUAMBAxDjAMBgNV
489 BAMMBXBva3VzMB4XDTE3MDcxNDE0MTAyMFoXDTIwMDQwOTE0MTAyMFowEDEOMAwG
490 A1UEAwwFcG9rdXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCQima
491 SUIMIdz5uVevzcScbcj06xs1OLaFKUoPJ8v+xP6Ut61BQhAvc8GYuw2uRx223hZC
492 r3HYLfSdWIfmOIAtlL8cPYPVoSivJtpSGE6fBG1tlBjVgXWRmJGR/oxx6Y5QDwcB
493 Q4GZKga8TtHQoY5idZuatYOFZGfMIcIUC0Uoda+YSypnw7A90F/JvlpcTUh3Fnem
494 VinqEA6XOegU9dCZk/29sXqauBjbdGihh8DvpklOhY16eQoiR3909AywQ0KUmI+R
495 Sa9E8oIsmUDetFuXEvana+sD3y42tU+cd2nhBPRETbSXPcum0B3uF4yKgweuJy5D
496 cvtVQIFVkkh4+AWNAgMBAAGjUDBOMB0GA1UdDgQWBBSS6V5PVGyN92NoB0AVLcOb
497 pzR3SzAfBgNVHSMEGDAWgBSS6V5PVGyN92NoB0AVLcObpzR3SzAMBgNVHRMEBTAD
498 AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBIszrBjoJ39axsS6Btbvwvo8vAmgiSWsav
499 7AmjXOAwknHPaCcDmrdOys5POD0DNRwNeRsnxFiZ/UL8Vmj2JGDLgAw+/v32MwfX
500 Ig7m+oIbO8KqDzlYvS5kd3suJ5C21hHy1/JUtfofZLovZH7ZRzhTAoRvCYaodW90
501 2o8ZqmyCdcXPzjFmoJ2xYzs/Sf8/E1cHfb+4HjOpeRnKxDvG0gwWzcsXpUrw2pNO
502 Oztj6Rd0THNrf/anIeYVtAHX4aqZA8Kbv2TyJd+9g78usFw1cn+8vfmilm6Pn0DQ
503 a+I5GyGd7BJI8wYuWqIStzvrJHbQQaNrSk7hgjWYiYlcsPh6w2QP
504 -----END CERTIFICATE-----
505
481506 =item * SSH public RSA keys
482507
483508 ssh-rsa AAAAB3NzaC1yc2EAAAADAQA...6mdYs5iJNGu/ltUdc=
0 -----BEGIN CERTIFICATE-----
1 MIIC8zCCAdugAwIBAgIJAPi+LvMU3uGWMA0GCSqGSIb3DQEBCwUAMBAxDjAMBgNV
2 BAMMBXBva3VzMB4XDTE3MDcxNDE0MTAyMFoXDTIwMDQwOTE0MTAyMFowEDEOMAwG
3 A1UEAwwFcG9rdXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCQima
4 SUIMIdz5uVevzcScbcj06xs1OLaFKUoPJ8v+xP6Ut61BQhAvc8GYuw2uRx223hZC
5 r3HYLfSdWIfmOIAtlL8cPYPVoSivJtpSGE6fBG1tlBjVgXWRmJGR/oxx6Y5QDwcB
6 Q4GZKga8TtHQoY5idZuatYOFZGfMIcIUC0Uoda+YSypnw7A90F/JvlpcTUh3Fnem
7 VinqEA6XOegU9dCZk/29sXqauBjbdGihh8DvpklOhY16eQoiR3909AywQ0KUmI+R
8 Sa9E8oIsmUDetFuXEvana+sD3y42tU+cd2nhBPRETbSXPcum0B3uF4yKgweuJy5D
9 cvtVQIFVkkh4+AWNAgMBAAGjUDBOMB0GA1UdDgQWBBSS6V5PVGyN92NoB0AVLcOb
10 pzR3SzAfBgNVHSMEGDAWgBSS6V5PVGyN92NoB0AVLcObpzR3SzAMBgNVHRMEBTAD
11 AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBIszrBjoJ39axsS6Btbvwvo8vAmgiSWsav
12 7AmjXOAwknHPaCcDmrdOys5POD0DNRwNeRsnxFiZ/UL8Vmj2JGDLgAw+/v32MwfX
13 Ig7m+oIbO8KqDzlYvS5kd3suJ5C21hHy1/JUtfofZLovZH7ZRzhTAoRvCYaodW90
14 2o8ZqmyCdcXPzjFmoJ2xYzs/Sf8/E1cHfb+4HjOpeRnKxDvG0gwWzcsXpUrw2pNO
15 Oztj6Rd0THNrf/anIeYVtAHX4aqZA8Kbv2TyJd+9g78usFw1cn+8vfmilm6Pn0DQ
16 a+I5GyGd7BJI8wYuWqIStzvrJHbQQaNrSk7hgjWYiYlcsPh6w2QP
17 -----END CERTIFICATE-----
00 use strict;
11 use warnings;
2 use Test::More tests => 44;
3
2 use Test::More tests => 60;
3
4 use Crypt::Misc 'decode_b64';
45 use Crypt::PK::DH qw(dh_shared_secret);
56
67 {
104105
105106 {
106107 my $k = Crypt::PK::DH->new;
108 my $p = <<"MARKER";
109 -----BEGIN DH PARAMETERS-----
110 MIIBCAKCAQEA7DIdWuBlIVFTnN9t9SP5tjajNgmQtBuhRlBQJIaHxblApAP9XZgS
111 iuAdkZugjvYb83bFzrjdo+TyKCUKZwVp8pv8LHEG90K54BsZwlbyjHHVlWFcQPIh
112 XYMg7YKEVcOPg0ZRty55g2u6IMMlMl16WWubHvtAeI0qVU7VUA6vuy7qAOauaZWo
113 0klH0zGkc8s1NGectcNbk8GmlUop+7JLUh3K0ikHVPYx2OJHjBhTz2vPgTdlcbHb
114 +dQIMdLFBOySNKv141QsDBo1ugu0Cxx02We6FFp1k5k4le+yGhFtLotE4OlZtcZW
115 xyjO1D0DrX8p6PeI4OmMAeGgGmDNBGreywIBAg==
116 -----END DH PARAMETERS-----
117 MARKER
118 $k->generate_key(\$p);
119 ok($k, 'generate_key PEM');
120 ok($k->is_private, 'is_private');
121 ok($k->export_key('private'), 'export_key_pem pri');
122 ok($k->export_key('public'), 'export_key_pem pub');
123 }
124
125 {
126 my $k = Crypt::PK::DH->new;
127 my $p = decode_b64(<<"MARKER");
128 MIIBCAKCAQEA7DIdWuBlIVFTnN9t9SP5tjajNgmQtBuhRlBQJIaHxblApAP9XZgS
129 iuAdkZugjvYb83bFzrjdo+TyKCUKZwVp8pv8LHEG90K54BsZwlbyjHHVlWFcQPIh
130 XYMg7YKEVcOPg0ZRty55g2u6IMMlMl16WWubHvtAeI0qVU7VUA6vuy7qAOauaZWo
131 0klH0zGkc8s1NGectcNbk8GmlUop+7JLUh3K0ikHVPYx2OJHjBhTz2vPgTdlcbHb
132 +dQIMdLFBOySNKv141QsDBo1ugu0Cxx02We6FFp1k5k4le+yGhFtLotE4OlZtcZW
133 xyjO1D0DrX8p6PeI4OmMAeGgGmDNBGreywIBAg==
134 MARKER
135 $k->generate_key(\$p);
136 ok($k, 'generate_key DER');
137 ok($k->is_private, 'is_private');
138 ok($k->export_key('private'), 'export_key_pem pri');
139 ok($k->export_key('public'), 'export_key_pem pub');
140 }
141
142 {
143 my $k = Crypt::PK::DH->new;
144 $k->generate_key({
145 g=>"0x2",
146 p=>"0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1".
147 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD".
148 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245".
149 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED".
150 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D".
151 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F".
152 "83655D23DCA3AD961C62F356208552BB9ED529077096966D".
153 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B".
154 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9".
155 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510".
156 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64".
157 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7".
158 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B".
159 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C".
160 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31".
161 "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
162 });
163 ok($k, 'generate_key HASH');
164 ok($k->is_private, 'is_private');
165 ok($k->export_key('private'), 'export_key_pem pri');
166 ok($k->export_key('public'), 'export_key_pem pub');
167 }
168
169 {
170 my $k = Crypt::PK::DH->new;
171 $k->generate_key('ike2048');
172 ok($k, 'generate_key groupname');
173 ok($k->is_private, 'is_private');
174 ok($k->export_key('private'), 'export_key_pem pri');
175 ok($k->export_key('public'), 'export_key_pem pub');
176 }
177
178 {
179 my $k = Crypt::PK::DH->new;
107180 $k->generate_key(256);
108 ok($k, 'generate_key');
181 ok($k, 'generate_key groupsize');
109182 ok($k->is_private, 'is_private');
110183 ok($k->export_key('private'), 'export_key_pem pri');
111184 ok($k->export_key('public'), 'export_key_pem pub');
00 use strict;
11 use warnings;
2 use Test::More tests => 44;
2 use Test::More tests => 62;
33
44 use Crypt::PK::DSA qw(dsa_encrypt dsa_decrypt dsa_sign_message dsa_verify_message dsa_sign_hash dsa_verify_hash);
5 use Crypt::Misc 'decode_b64';
56
67 {
78 my $k;
8990
9091 {
9192 my $k = Crypt::PK::DSA->new;
93 $k->generate_key(\<<"MARKER");
94 -----BEGIN DSA PARAMETERS-----
95 MIICLAKCAQEA3dZSaDnP5LgH44CDYc2wfGLtq4rbBgtOVvLkvh4j29CTiOUDRC1H
96 ivkTdtGrI3DdrAFeKieFYDJ1RJFbru+8/RYE7YfaR5Y3OUI4Vdf26guMViLLVjSL
97 W43Td50ZZziLmmYzn3cliokShe9f5/mtuLJ0uJRq7QxgHj7bgmvJvORvi4QXSCOn
98 nmCOgEfhoU1Vj/PePjtjeZWbLyGFXHC7vpvqePrsFtbUlBzIr2mr7JuHB3rAl7A4
99 1VL6lexqONRa4rQuVxiX0vp3iit9Cx02EwrZODdlifssd9Kceu2UsvifjmCBPyv8
100 6nmmEOtxh/xduuOBtVWXeZHSwIDUQvSJFwIhAK/ZDSl9iNuZ/TRwqQ3JRU3MjXCU
101 /US6/LU1qqjQATk7AoIBACoqauphNZmUZYOilArBfYCMtUwS0FNG6wfUMWDMd46z
102 /hv7equa9b75sT1uHyiUVuPD2hRhR3xNYkKSX9Kx8NGKj/bGDyaEW+Ud852N6BTo
103 9vzZ4GjKVBGe44Wa8eynVgVE5/r0z6OfHkV7uOxlGEdYgIooUbIsY7w0DmaR2FVZ
104 AMjGMg+L6CpulfvdETYi9LQafY4jRkgGWTc9h/2RYGhQUti1PheY1AlDYpubO8am
105 ZBG6vMBaANLx6Pv+lle4ltVvDVhwTK5APyfN1vVdEvVmU1/6zHZEnuiDAT8XI1rH
106 S1+SGX11RIn6uPVL1c0RjgW8/JZ6EeM8NvLdBiYYBuI=
107 -----END DSA PARAMETERS-----
108 MARKER
109 ok($k, 'generate_key PEM');
110 ok($k->is_private, 'is_private');
111 ok($k->export_key_pem('private'), 'export_key_pem pri');
112 ok($k->export_key_pem('public'), 'export_key_pem pub');
113 ok($k->export_key_der('private'), 'export_key_der pri');
114 ok($k->export_key_der('public'), 'export_key_der pub');
115 }
116
117 {
118 my $k = Crypt::PK::DSA->new;
119 $k->generate_key(\decode_b64(<<"MARKER"));
120 MIICLAKCAQEA3dZSaDnP5LgH44CDYc2wfGLtq4rbBgtOVvLkvh4j29CTiOUDRC1H
121 ivkTdtGrI3DdrAFeKieFYDJ1RJFbru+8/RYE7YfaR5Y3OUI4Vdf26guMViLLVjSL
122 W43Td50ZZziLmmYzn3cliokShe9f5/mtuLJ0uJRq7QxgHj7bgmvJvORvi4QXSCOn
123 nmCOgEfhoU1Vj/PePjtjeZWbLyGFXHC7vpvqePrsFtbUlBzIr2mr7JuHB3rAl7A4
124 1VL6lexqONRa4rQuVxiX0vp3iit9Cx02EwrZODdlifssd9Kceu2UsvifjmCBPyv8
125 6nmmEOtxh/xduuOBtVWXeZHSwIDUQvSJFwIhAK/ZDSl9iNuZ/TRwqQ3JRU3MjXCU
126 /US6/LU1qqjQATk7AoIBACoqauphNZmUZYOilArBfYCMtUwS0FNG6wfUMWDMd46z
127 /hv7equa9b75sT1uHyiUVuPD2hRhR3xNYkKSX9Kx8NGKj/bGDyaEW+Ud852N6BTo
128 9vzZ4GjKVBGe44Wa8eynVgVE5/r0z6OfHkV7uOxlGEdYgIooUbIsY7w0DmaR2FVZ
129 AMjGMg+L6CpulfvdETYi9LQafY4jRkgGWTc9h/2RYGhQUti1PheY1AlDYpubO8am
130 ZBG6vMBaANLx6Pv+lle4ltVvDVhwTK5APyfN1vVdEvVmU1/6zHZEnuiDAT8XI1rH
131 S1+SGX11RIn6uPVL1c0RjgW8/JZ6EeM8NvLdBiYYBuI=
132 MARKER
133 ok($k, 'generate_key DER');
134 ok($k->is_private, 'is_private');
135 ok($k->export_key_pem('private'), 'export_key_pem pri');
136 ok($k->export_key_pem('public'), 'export_key_pem pub');
137 ok($k->export_key_der('private'), 'export_key_der pri');
138 ok($k->export_key_der('public'), 'export_key_der pub');
139 }
140
141 {
142 my $k = Crypt::PK::DSA->new;
143 $k->generate_key({
144 p => "0xA717676E57280B32123B22E3F5BABC9460FEEBD53CE9ECBA2060AAD0A7128A2EA25D049D0784B08E7B3C63A53F2764".
145 "2EA5B62B44F80BDF74828F9227FACDEAC50D8698AE12722F58F52087564466FA92A38ED6158B5437A4382D7E460D".
146 "41F3FA9B7BD0808E2DDD93529F6CAD397B9287313CFE2A0F913079E86EA0FE55D2620750A57419158EDAC4BB7C97".
147 "2B7C20756C503FBBBC84EE39D0C72298CA3F9B28CD14C640D459F160ADD615F4A24300F5832DE2A874776B94D158".
148 "F77BBD13D417F5A56BE043CD358D9B983B003DF4AE20EB43A358F391CBD75668AAE9A7633815FEE4DBFF0303D097".
149 "AA2BBA9BD7ADD5B75B40ED3F756516AAB46B66872187544B8D",
150 q => "0x81EA35142EDAC0B7A9CCBB4A0D29D16803792A1FC4FD4310682CD6C0FEFD3DC7",
151 g => "0x62160328C0B7F11AD92684E27A28BF5F79D936F968C6301E339D2F18FF86106736030F4287E588AD7A79F37E7340D1
152 E3CA1D89D320F2C2BA5FDC263990456C77FBE683D620A0BB0D49DB793E48C68710750163EF822129D32CC9254218DD
153 74F2E07ACE3B51115837A6336E1CC567862651E911D5FF36D775FE600436BC21FC92076544D813C2437502FD5AC728
154 C1BCBFEA216DFC4B544D39F6D3BC301D7409EDA84A4CFDC7E3D1BB4C37A9E9D27A25ED55630119DBBC4D79E052F1A2
155 CBF5F121531DE33C1FAF2D97930E45A08DE816477711685B4D673041A4D75C8D613091274B2E8766037E4EA973A65F
156 912D74319649E698A019ADEEC66567E9D05A135E8A",
157 });
158 ok($k, 'generate_key HASH');
159 ok($k->is_private, 'is_private');
160 ok($k->export_key_pem('private'), 'export_key_pem pri');
161 ok($k->export_key_pem('public'), 'export_key_pem pub');
162 ok($k->export_key_der('private'), 'export_key_der pri');
163 ok($k->export_key_der('public'), 'export_key_der pub');
164 }
165
166 {
167 my $k = Crypt::PK::DSA->new;
92168 $k->generate_key(20, 128);
93 ok($k, 'generate_key');
169 ok($k, 'generate_key size');
94170 ok($k->is_private, 'is_private');
95171 ok($k->export_key_pem('private'), 'export_key_pem pri');
96172 ok($k->export_key_pem('public'), 'export_key_pem pub');
00 use strict;
11 use warnings;
2 use Test::More tests => 45;
2 use Test::More tests => 49;
33
44 use Crypt::PK::RSA qw(rsa_encrypt rsa_decrypt rsa_sign_message rsa_verify_message rsa_sign_hash rsa_verify_hash);
55
5555 $k = Crypt::PK::RSA->new('t/data/openssl_rsa2.pem');
5656 ok($k, 'load openssl_rsa2.pem');
5757 ok($k->is_private, 'is_private openssl_rsa2.pem');
58
59 # X509
60 $k = Crypt::PK::RSA->new('t/data/openssl_rsa-x509.pem');
61 ok($k, 'openssl_rsa-x509.pem');
62 ok(!$k->is_private, 'not private openssl_rsa-x509.pem');
63 $k = Crypt::PK::RSA->new('t/data/openssl_rsa-x509.der');
64 ok($k, 'openssl_rsa-x509.der');
65 ok(!$k->is_private, 'not private openssl_rsa-x509.der');
5866 }
5967
6068 {