| 1 | # ---?--- |
| 2 | # |
| 3 | # $Id$ |
| 4 | # |
| 5 | # Key-management interface |
| 6 | # |
| 7 | # (c) 2001 Straylight/Edgeware |
| 8 | # |
| 9 | |
| 10 | #----- Licensing notice ----------------------------------------------------- |
| 11 | # |
| 12 | # This file is part of the Perl interface to Catacomb. |
| 13 | # |
| 14 | # Catacomb/Perl is free software; you can redistribute it and/or modify |
| 15 | # it under the terms of the GNU General Public License as published by |
| 16 | # the Free Software Foundation; either version 2 of the License, or |
| 17 | # (at your option) any later version. |
| 18 | # |
| 19 | # Catacomb/Perl is distributed in the hope that it will be useful, |
| 20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 22 | # GNU General Public License for more details. |
| 23 | # |
| 24 | # You should have received a copy of the GNU General Public License |
| 25 | # along with Catacomb/Perl; if not, write to the Free Software Foundation, |
| 26 | # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 27 | |
| 28 | MODULE = Catacomb PACKAGE = Catacomb::PubKey |
| 29 | |
| 30 | void |
| 31 | gen_dh(me, ql, pl, steps = 0, r = &rand_global, events = &PL_sv_undef) |
| 32 | SV *me |
| 33 | unsigned ql |
| 34 | unsigned pl |
| 35 | unsigned steps |
| 36 | grand *r |
| 37 | MP_Prime_Gen_NullProc *events |
| 38 | PREINIT: |
| 39 | dh_param dp; |
| 40 | pgen_proc *evproc; |
| 41 | void *evctx; |
| 42 | PPCODE: |
| 43 | pgproc_get(events, &evproc, &evctx); |
| 44 | if (dh_gen(&dp, ql, pl, steps, r, evproc, evctx)) |
| 45 | XSRETURN_EMPTY; |
| 46 | XPUSHs(RET_MP(dp.p)); |
| 47 | XPUSHs(RET_MP(dp.g)); |
| 48 | XPUSHs(RET_MP(dp.q)); |
| 49 | |
| 50 | void |
| 51 | gen_limlee(me, ql, pl, flags = 0, steps = 0, r = &rand_global, oevents = &PL_sv_undef, ievents = &PL_sv_undef) |
| 52 | SV *me |
| 53 | unsigned ql |
| 54 | unsigned pl |
| 55 | unsigned flags |
| 56 | unsigned steps |
| 57 | grand *r |
| 58 | MP_Prime_Gen_NullProc *oevents |
| 59 | MP_Prime_Gen_NullProc *ievents |
| 60 | PREINIT: |
| 61 | dh_param dp; |
| 62 | pgen_proc *oev, *iev; |
| 63 | void *oec, *iec; |
| 64 | size_t nf; |
| 65 | mp **f; |
| 66 | size_t i; |
| 67 | PPCODE: |
| 68 | pgproc_get(oevents, &oev, &oec); |
| 69 | pgproc_get(ievents, &iev, &iec); |
| 70 | if (dh_limlee(&dp, ql, pl, flags, steps, r, |
| 71 | oev, oec, iev, iec, &nf, &f)) |
| 72 | XSRETURN_EMPTY; |
| 73 | XPUSHs(RET_MP(dp.p)); |
| 74 | XPUSHs(RET_MP(dp.g)); |
| 75 | XPUSHs(RET_MP(dp.q)); |
| 76 | for (i = 0; i < nf; i++) |
| 77 | XPUSHs(RET_MP(f[i])); |
| 78 | xfree(f); |
| 79 | |
| 80 | void |
| 81 | gen_dsa(me, ql, pl, steps = 0, k = &PL_sv_undef, events = &PL_sv_undef) |
| 82 | SV *me |
| 83 | unsigned ql |
| 84 | unsigned pl |
| 85 | unsigned steps |
| 86 | SV *k |
| 87 | MP_Prime_Gen_NullProc *events |
| 88 | PREINIT: |
| 89 | char *kp; |
| 90 | STRLEN ksz; |
| 91 | dsa_seed ds; |
| 92 | dsa_param dp; |
| 93 | pgen_proc *evproc; |
| 94 | void *evctx; |
| 95 | char buf[20]; |
| 96 | PPCODE: |
| 97 | if (SvOK(k)) |
| 98 | kp = SvPV(k, ksz); |
| 99 | else { |
| 100 | kp = buf; |
| 101 | ksz = 20; |
| 102 | rand_get(RAND_GLOBAL, kp, ksz); |
| 103 | } |
| 104 | pgproc_get(events, &evproc, &evctx); |
| 105 | if (dsa_gen(&dp, ql, pl, steps, kp, ksz, &ds, evproc, evctx)) |
| 106 | XSRETURN_EMPTY; |
| 107 | XPUSHs(RET_MP(dp.p)); |
| 108 | XPUSHs(RET_MP(dp.g)); |
| 109 | XPUSHs(RET_MP(dp.q)); |
| 110 | XPUSHs(sv_2mortal(newSVpvn((char *)ds.p, ds.sz))); |
| 111 | XPUSHs(sv_2mortal(newSViv(ds.count))); |
| 112 | xfree(ds.p); |
| 113 | |
| 114 | MODULE = Catacomb PACKAGE = Catacomb::DSA |
| 115 | |
| 116 | ghash * |
| 117 | beginhash(c) |
| 118 | SV *c |
| 119 | PREINIT: |
| 120 | gdsa g; |
| 121 | CODE: |
| 122 | gdsa_pubfromsv(&g, c); |
| 123 | RETVAL = gdsa_beginhash(&g); |
| 124 | OUTPUT: |
| 125 | RETVAL |
| 126 | |
| 127 | SV * |
| 128 | endhash(c, h) |
| 129 | SV *c |
| 130 | ghash *h |
| 131 | PREINIT: |
| 132 | gdsa g; |
| 133 | CODE: |
| 134 | gdsa_pubfromsv(&g, c); |
| 135 | gdsa_endhash(&g, h); |
| 136 | XSRETURN_YES; |
| 137 | |
| 138 | MODULE = Catacomb PACKAGE = Catacomb::DSA::Private |
| 139 | |
| 140 | void |
| 141 | sign(c, m, k = 0) |
| 142 | SV *c |
| 143 | SV *m |
| 144 | mp *k |
| 145 | PREINIT: |
| 146 | gdsa g; |
| 147 | gdsa_sig s = GDSA_SIG_INIT; |
| 148 | char *p; |
| 149 | STRLEN len; |
| 150 | PPCODE: |
| 151 | gdsa_privfromsv(&g, c); |
| 152 | p = SvPV(m, len); |
| 153 | if (len != g.h->hashsz) |
| 154 | croak("bad message length"); |
| 155 | gdsa_sign(&g, &s, p, k); |
| 156 | XPUSHs(MAKE_MP(s.r)); |
| 157 | XPUSHs(MAKE_MP(s.s)); |
| 158 | |
| 159 | MODULE = Catacomb PACKAGE = Catacomb::DSA::Public |
| 160 | |
| 161 | bool |
| 162 | verify(c, m, r, s) |
| 163 | SV *c |
| 164 | mp *r |
| 165 | mp *s |
| 166 | SV *m |
| 167 | PREINIT: |
| 168 | gdsa g; |
| 169 | gdsa_sig ss = GDSA_SIG_INIT; |
| 170 | char *p; |
| 171 | STRLEN len; |
| 172 | CODE: |
| 173 | gdsa_pubfromsv(&g, c); |
| 174 | p = SvPV(m, len); |
| 175 | if (len != g.h->hashsz) |
| 176 | croak("bad message length"); |
| 177 | ss.r = r; |
| 178 | ss.s = s; |
| 179 | RETVAL = !gdsa_verify(&g, &ss, p); |
| 180 | OUTPUT: |
| 181 | RETVAL |
| 182 | |
| 183 | MODULE = Catacomb PACKAGE = Catacomb::KCDSA |
| 184 | |
| 185 | ghash * |
| 186 | beginhash(c) |
| 187 | SV *c |
| 188 | PREINIT: |
| 189 | gkcdsa g; |
| 190 | CODE: |
| 191 | gdsa_pubfromsv(&g, c); |
| 192 | RETVAL = gkcdsa_beginhash(&g); |
| 193 | OUTPUT: |
| 194 | RETVAL |
| 195 | |
| 196 | SV * |
| 197 | endhash(c, h) |
| 198 | SV *c |
| 199 | ghash *h |
| 200 | PREINIT: |
| 201 | gkcdsa g; |
| 202 | CODE: |
| 203 | gdsa_pubfromsv(&g, c); |
| 204 | gkcdsa_endhash(&g, h); |
| 205 | XSRETURN_YES; |
| 206 | |
| 207 | MODULE = Catacomb PACKAGE = Catacomb::KCDSA::Private |
| 208 | |
| 209 | void |
| 210 | sign(c, m, k = 0) |
| 211 | SV *c |
| 212 | SV *m |
| 213 | mp *k |
| 214 | PREINIT: |
| 215 | gkcdsa g; |
| 216 | gkcdsa_sig s = GKCDSA_SIG_INIT; |
| 217 | char *p; |
| 218 | STRLEN len; |
| 219 | PPCODE: |
| 220 | gdsa_privfromsv(&g, c); |
| 221 | p = SvPV(m, len); |
| 222 | if (len != g.h->hashsz) |
| 223 | croak("bad message length"); |
| 224 | gkcdsa_sign(&g, &s, p, k); |
| 225 | XPUSHs(sv_2mortal(newSVpvn((char *)s.r, g.h->hashsz))); |
| 226 | XPUSHs(RET_MP(s.s)); |
| 227 | xfree(s.r); |
| 228 | |
| 229 | MODULE = Catacomb PACKAGE = Catacomb::KCDSA::Public |
| 230 | |
| 231 | bool |
| 232 | verify(c, m, r, s) |
| 233 | SV *c |
| 234 | SV *r |
| 235 | mp *s |
| 236 | SV *m |
| 237 | PREINIT: |
| 238 | gkcdsa g; |
| 239 | gkcdsa_sig ss = GKCDSA_SIG_INIT; |
| 240 | char *p; |
| 241 | STRLEN len; |
| 242 | CODE: |
| 243 | gdsa_pubfromsv(&g, c); |
| 244 | p = SvPV(m, len); |
| 245 | if (len != g.h->hashsz) |
| 246 | croak("bad message length"); |
| 247 | ss.r = (void *)SvPV(r, len); |
| 248 | if (len != g.h->hashsz) |
| 249 | croak("bad signature (r) length"); |
| 250 | ss.s = s; |
| 251 | RETVAL = !gkcdsa_verify(&g, &ss, p); |
| 252 | OUTPUT: |
| 253 | RETVAL |
| 254 | |
| 255 | MODULE = Catacomb PACKAGE = Catacomb::RSA::Public PREFIX = rsa_ |
| 256 | |
| 257 | RSA_Public * |
| 258 | new(me, sv) |
| 259 | SV *me |
| 260 | SV *sv |
| 261 | PREINIT: |
| 262 | cursor c; |
| 263 | rsa_pub *rp; |
| 264 | CODE: |
| 265 | rp = CREATE(rsa_pub); |
| 266 | c_init(&c, sv); |
| 267 | rp->n = C_MP(&c, "n"); |
| 268 | rp->e = C_MP(&c, "e"); |
| 269 | RETVAL = CREATE(rsa_pubctx); |
| 270 | rsa_pubcreate(RETVAL, rp); |
| 271 | OUTPUT: |
| 272 | RETVAL |
| 273 | |
| 274 | mp * |
| 275 | n(rp) |
| 276 | RSA_Public *rp |
| 277 | CODE: |
| 278 | RETVAL = MP_COPY(rp->rp->n); |
| 279 | OUTPUT: |
| 280 | RETVAL |
| 281 | |
| 282 | HV * |
| 283 | extract(rp) |
| 284 | RSA_Public *rp |
| 285 | CODE: |
| 286 | RETVAL = newHV(); |
| 287 | hvput(RETVAL, "n", MAKE_MP(rp->rp->n)); |
| 288 | hvput(RETVAL, "e", MAKE_MP(rp->rp->e)); |
| 289 | OUTPUT: |
| 290 | RETVAL |
| 291 | |
| 292 | SV * |
| 293 | DESTROY(rp) |
| 294 | RSA_Public *rp |
| 295 | PREINIT: |
| 296 | rsa_pub *rrp; |
| 297 | CODE: |
| 298 | rrp = rp->rp; |
| 299 | rsa_pubdestroy(rp); |
| 300 | DESTROY(rp); |
| 301 | rsa_pubfree(rrp); |
| 302 | DESTROY(rrp); |
| 303 | XSRETURN_YES; |
| 304 | |
| 305 | mp * |
| 306 | op(rp, p) |
| 307 | RSA_Public *rp |
| 308 | mp *p |
| 309 | CODE: |
| 310 | RETVAL = rsa_pubop(rp, MP_NEW, p); |
| 311 | OUTPUT: |
| 312 | RETVAL |
| 313 | |
| 314 | MODULE = Catacomb PACKAGE = Catacomb::RSA::Private PREFIX = rsa_ |
| 315 | |
| 316 | RSA_Private * |
| 317 | new(me, sv) |
| 318 | SV *me |
| 319 | SV *sv |
| 320 | PREINIT: |
| 321 | cursor c; |
| 322 | rsa_priv *rp; |
| 323 | CODE: |
| 324 | c_init(&c, sv); |
| 325 | rp = CREATE(rsa_priv); |
| 326 | rp->n = C_MP(&c, "n"); |
| 327 | rp->e = C_MP(&c, "e"); |
| 328 | rp->d = C_MP(&c, "d"); |
| 329 | rp->p = C_MP(&c, "p"); |
| 330 | rp->q = C_MP(&c, "q"); |
| 331 | rp->dp = C_MP(&c, "dp"); |
| 332 | rp->dq = C_MP(&c, "dq"); |
| 333 | rp->q_inv = C_MP(&c, "qi"); |
| 334 | if (rsa_recover(rp)) |
| 335 | croak("insuffcient values in Catacomb::RSA::Private::new"); |
| 336 | RETVAL = CREATE(rsa_privctx); |
| 337 | rsa_privcreate(RETVAL, rp, &rand_global); |
| 338 | OUTPUT: |
| 339 | RETVAL |
| 340 | |
| 341 | RSA_Private * |
| 342 | generate(me, nbits, r = &rand_global, n = 0, events = &PL_sv_undef) |
| 343 | SV *me |
| 344 | unsigned nbits |
| 345 | grand *r |
| 346 | unsigned n |
| 347 | MP_Prime_Gen_NullProc *events |
| 348 | PREINIT: |
| 349 | pgen_proc *ev; |
| 350 | void *ec; |
| 351 | rsa_priv *rp; |
| 352 | CODE: |
| 353 | rp = CREATE(rsa_priv); |
| 354 | pgproc_get(events, &ev, &ec); |
| 355 | if (rsa_gen(rp, nbits, r, n, ev, ec)) { |
| 356 | DESTROY(rp); |
| 357 | XSRETURN_UNDEF; |
| 358 | } |
| 359 | RETVAL = CREATE(rsa_privctx); |
| 360 | rsa_privcreate(RETVAL, rp, &rand_global); |
| 361 | OUTPUT: |
| 362 | RETVAL |
| 363 | |
| 364 | HV * |
| 365 | extract(rp) |
| 366 | RSA_Private *rp |
| 367 | CODE: |
| 368 | RETVAL = newHV(); |
| 369 | hvput(RETVAL, "n", MAKE_MP(rp->rp->n)); |
| 370 | hvput(RETVAL, "e", MAKE_MP(rp->rp->e)); |
| 371 | hvput(RETVAL, "d", MAKE_MP(rp->rp->d)); |
| 372 | hvput(RETVAL, "p", MAKE_MP(rp->rp->p)); |
| 373 | hvput(RETVAL, "q", MAKE_MP(rp->rp->q)); |
| 374 | hvput(RETVAL, "dp", MAKE_MP(rp->rp->dp)); |
| 375 | hvput(RETVAL, "dq", MAKE_MP(rp->rp->dq)); |
| 376 | hvput(RETVAL, "qi", MAKE_MP(rp->rp->q_inv)); |
| 377 | OUTPUT: |
| 378 | RETVAL |
| 379 | |
| 380 | mp * |
| 381 | n(rp) |
| 382 | RSA_Private *rp |
| 383 | CODE: |
| 384 | RETVAL = MP_COPY(rp->rp->n); |
| 385 | OUTPUT: |
| 386 | RETVAL |
| 387 | |
| 388 | SV * |
| 389 | DESTROY(rp) |
| 390 | RSA_Private *rp |
| 391 | PREINIT: |
| 392 | rsa_priv *rrp; |
| 393 | CODE: |
| 394 | rp->r = &rand_global; |
| 395 | rrp = rp->rp; |
| 396 | rsa_privdestroy(rp); |
| 397 | DESTROY(rp); |
| 398 | rsa_privfree(rrp); |
| 399 | DESTROY(rrp); |
| 400 | XSRETURN_YES; |
| 401 | |
| 402 | mp * |
| 403 | op(rp, p, r = &PL_sv_undef) |
| 404 | RSA_Private *rp |
| 405 | mp *p |
| 406 | SV *r |
| 407 | CODE: |
| 408 | rp->r = SvOK(r) ? ptrfromsv(r, "Catacomb::Rand", "r") : 0; |
| 409 | RETVAL = rsa_privop(rp, MP_NEW, p); |
| 410 | OUTPUT: |
| 411 | RETVAL |
| 412 | |
| 413 | MODULE = Catacomb PACKAGE = Catacomb::RSA::PKCS1Crypt |
| 414 | |
| 415 | mp * |
| 416 | pad(c, m, sz, nbits) |
| 417 | SV *c |
| 418 | SV *m |
| 419 | size_t sz |
| 420 | unsigned long nbits |
| 421 | PREINIT: |
| 422 | pkcs1 pc; |
| 423 | void *b; |
| 424 | void *mm; |
| 425 | STRLEN msz; |
| 426 | CODE: |
| 427 | pkcs1_fromsv(&pc, c); |
| 428 | mm = SvPV(m, msz); |
| 429 | b = xmalloc(sz); |
| 430 | RETVAL = pkcs1_cryptencode(MP_NEW, mm, msz, b, sz, nbits, &pc); |
| 431 | xfree(b); |
| 432 | OUTPUT: |
| 433 | RETVAL |
| 434 | |
| 435 | SV * |
| 436 | unpad(c, m, sz, nbits) |
| 437 | SV *c |
| 438 | mp *m |
| 439 | size_t sz |
| 440 | unsigned long nbits |
| 441 | PREINIT: |
| 442 | pkcs1 pc; |
| 443 | void *b; |
| 444 | int rc; |
| 445 | CODE: |
| 446 | pkcs1_fromsv(&pc, c); |
| 447 | b = xmalloc(sz); |
| 448 | rc = pkcs1_cryptdecode(m, b, sz, nbits, &pc); |
| 449 | if (rc < 0) |
| 450 | RETVAL = &PL_sv_undef; |
| 451 | else |
| 452 | RETVAL = newSVpvn(b, rc); |
| 453 | xfree(b); |
| 454 | OUTPUT: |
| 455 | RETVAL |
| 456 | |
| 457 | MODULE = Catacomb PACKAGE = Catacomb::RSA::PKCS1Sign |
| 458 | |
| 459 | mp * |
| 460 | pad(c, m, sz, nbits) |
| 461 | SV *c |
| 462 | SV *m |
| 463 | size_t sz |
| 464 | unsigned long nbits |
| 465 | PREINIT: |
| 466 | pkcs1 pc; |
| 467 | void *b; |
| 468 | void *mm; |
| 469 | STRLEN msz; |
| 470 | CODE: |
| 471 | pkcs1_fromsv(&pc, c); |
| 472 | mm = SvPV(m, msz); |
| 473 | b = xmalloc(sz); |
| 474 | RETVAL = pkcs1_sigencode(MP_NEW, mm, msz, b, sz, nbits, &pc); |
| 475 | xfree(b); |
| 476 | OUTPUT: |
| 477 | RETVAL |
| 478 | |
| 479 | SV * |
| 480 | unpad(c, s, m, sz, nbits) |
| 481 | SV *c |
| 482 | mp *s |
| 483 | SV *m |
| 484 | size_t sz |
| 485 | unsigned long nbits |
| 486 | PREINIT: |
| 487 | pkcs1 pc; |
| 488 | void *b; |
| 489 | void *mm; |
| 490 | STRLEN msz; |
| 491 | int rc; |
| 492 | CODE: |
| 493 | pkcs1_fromsv(&pc, c); |
| 494 | mm = SvPV(m, msz); |
| 495 | b = xmalloc(sz); |
| 496 | rc = pkcs1_sigdecode(s, mm, msz, b, sz, nbits, &pc); |
| 497 | if (rc < 0) XSRETURN_UNDEF; |
| 498 | RETVAL = newSVpvn(b, rc); |
| 499 | xfree(b); |
| 500 | OUTPUT: |
| 501 | RETVAL |
| 502 | |
| 503 | MODULE = Catacomb PACKAGE = Catacomb::RSA::OAEP |
| 504 | |
| 505 | mp * |
| 506 | pad(c, m, sz, nbits) |
| 507 | SV *c |
| 508 | SV *m |
| 509 | size_t sz |
| 510 | unsigned long nbits |
| 511 | PREINIT: |
| 512 | oaep pc; |
| 513 | void *b; |
| 514 | void *mm; |
| 515 | STRLEN msz; |
| 516 | CODE: |
| 517 | oaep_fromsv(&pc, c); |
| 518 | mm = SvPV(m, msz); |
| 519 | b = xmalloc(sz); |
| 520 | RETVAL = oaep_encode(MP_NEW, mm, msz, b, sz, nbits, &pc); |
| 521 | xfree(b); |
| 522 | OUTPUT: |
| 523 | RETVAL |
| 524 | |
| 525 | SV * |
| 526 | unpad(c, m, sz, nbits) |
| 527 | SV *c |
| 528 | mp *m |
| 529 | size_t sz |
| 530 | unsigned long nbits |
| 531 | PREINIT: |
| 532 | oaep pc; |
| 533 | void *b; |
| 534 | int rc; |
| 535 | CODE: |
| 536 | oaep_fromsv(&pc, c); |
| 537 | b = xmalloc(sz); |
| 538 | rc = oaep_decode(m, b, sz, nbits, &pc); |
| 539 | if (rc < 0) |
| 540 | RETVAL = &PL_sv_undef; |
| 541 | else |
| 542 | RETVAL = newSVpvn(b, rc); |
| 543 | xfree(b); |
| 544 | OUTPUT: |
| 545 | RETVAL |
| 546 | |
| 547 | MODULE = Catacomb PACKAGE = Catacomb::RSA::PSS |
| 548 | |
| 549 | mp * |
| 550 | pad(c, m, sz, nbits) |
| 551 | SV *c |
| 552 | SV *m |
| 553 | size_t sz |
| 554 | unsigned long nbits |
| 555 | PREINIT: |
| 556 | pss pc; |
| 557 | void *b; |
| 558 | void *mm; |
| 559 | STRLEN msz; |
| 560 | CODE: |
| 561 | pss_fromsv(&pc, c); |
| 562 | mm = SvPV(m, msz); |
| 563 | b = xmalloc(sz); |
| 564 | RETVAL = pss_encode(MP_NEW, mm, msz, b, sz, nbits, &pc); |
| 565 | xfree(b); |
| 566 | OUTPUT: |
| 567 | RETVAL |
| 568 | |
| 569 | SV * |
| 570 | unpad(c, s, m, sz, nbits) |
| 571 | SV *c |
| 572 | mp *s |
| 573 | SV *m |
| 574 | size_t sz |
| 575 | unsigned long nbits |
| 576 | PREINIT: |
| 577 | pss pc; |
| 578 | void *b; |
| 579 | void *mm; |
| 580 | STRLEN msz; |
| 581 | int rc; |
| 582 | CODE: |
| 583 | pss_fromsv(&pc, c); |
| 584 | mm = SvPV(m, msz); |
| 585 | b = xmalloc(sz); |
| 586 | rc = pss_decode(s, mm, msz, b, sz, nbits, &pc); |
| 587 | if (rc < 0) XSRETURN_UNDEF; |
| 588 | RETVAL = newSVpvn(b, rc); |
| 589 | xfree(b); |
| 590 | OUTPUT: |
| 591 | RETVAL |
| 592 | |
| 593 | #----- That's all, folks ---------------------------------------------------- |