The large one adds support for RSA keys and reorganizes
authorBruce Momjian <bruce@momjian.us>
Sat, 13 Aug 2005 02:06:21 +0000 (02:06 +0000)
committerBruce Momjian <bruce@momjian.us>
Sat, 13 Aug 2005 02:06:21 +0000 (02:06 +0000)
the pubkey functions a bit.  The actual RSA-specific code
there is tiny, most of the patch consists of reorg of the
pubkey code, as lots of it was written as elgamal-only.

---------------------------------------------------------------------------

The SHLIB section was copy-pasted from somewhere and contains
several unnecessary libs.  This cleans it up a bit.

 -lcrypt
   we don't use system crypt()

 -lssl, -lssleay32
   no SSL here

 -lz in win32 section
   already added on previous line

 -ldes
   The chance anybody has it is pretty low.
   And the chance pgcrypto works with it is even lower.

Also trim the win32 section.

---------------------------------------------------------------------------

It is already disabled in Makefile, remove code too.

---------------------------------------------------------------------------

I was bit hasty making the random exponent 'k' a prime.  Further researh
shows that Elgamal encryption has no specific needs in respect to k,
any random number is fine.

It is bit different for signing, there it needs to be 'relatively prime'
to p - 1,  that means GCD(k, p-1) == 1, which is also a lot lighter than
full primality.  As we don't do signing, this can be ignored.

This brings major speedup to Elgamal encryption.

---------------------------------------------------------------------------

o  pgp_mpi_free: Accept NULLs
o  pgp_mpi_cksum: result should be 16bit
o  Remove function name from error messages - to be similar to other
   SQL functions, and it does not match anyway the called function
o  remove couple junk lines

---------------------------------------------------------------------------

o  Support for RSA encryption
o  Big reorg to better separate generic and algorithm-specific code.
o  Regression tests for RSA.

---------------------------------------------------------------------------

o  Tom stuck a CVS id into file.  I doubt the usefulness of it,
   but if it needs to be in the file then rather at the end.
   Also tag it as comment for asciidoc.
o  Mention bytea vs. text difference
o  Couple clarifications

---------------------------------------------------------------------------

There is a choice whether to update it with pgp functions or
remove it.  I decided to remove it, updating is pointless.

I've tried to keep the core of pgcrypto relatively independent
from main PostgreSQL, to make it easy to use externally if needed,
and that is good.  Eg. that made development of PGP functions much
nicer.

But I have no plans to release it as generic library, so keeping such
doc
up-to-date is waste of time.  If anyone is interested in using it in
other products, he can probably bother to read the source too.

Commented source is another thing - I'll try to make another pass
over code to see if there is anything non-obvious that would need
more comments.

---------------------------------------------------------------------------

Marko Kreen

23 files changed:
contrib/pgcrypto/Makefile
contrib/pgcrypto/README.pgcrypto
contrib/pgcrypto/expected/pgp-armor.out
contrib/pgcrypto/expected/pgp-encrypt.out
contrib/pgcrypto/expected/pgp-info.out
contrib/pgcrypto/expected/pgp-pubkey-decrypt.out
contrib/pgcrypto/expected/pgp-pubkey-encrypt.out
contrib/pgcrypto/pgp-info.c
contrib/pgcrypto/pgp-mpi-internal.c
contrib/pgcrypto/pgp-mpi-openssl.c
contrib/pgcrypto/pgp-mpi.c
contrib/pgcrypto/pgp-pgsql.c
contrib/pgcrypto/pgp-pubdec.c
contrib/pgcrypto/pgp-pubenc.c
contrib/pgcrypto/pgp-pubkey.c
contrib/pgcrypto/pgp.h
contrib/pgcrypto/px-crypt.c
contrib/pgcrypto/px-crypt.h
contrib/pgcrypto/px.c
contrib/pgcrypto/px.h
contrib/pgcrypto/sql/pgp-info.sql
contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql
contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql

index 1b3c18356de6113270912cf044513e9204a8e321..fd7a694c6837188f341a2bb751d5fcca796e0035 100644 (file)
@@ -56,17 +56,13 @@ endif
 # Add libraries that pgcrypto depends (or might depend) on into the
 # shared library link.  (The order in which you list them here doesn't
 # matter.)
-SHLIB_LINK += $(filter -lcrypt -ldes -lcrypto -lssl -lz, $(LIBS))
+SHLIB_LINK += $(filter -lcrypto -lz, $(LIBS))
 ifeq ($(PORTNAME), win32)
-SHLIB_LINK += $(filter -leay32 -lssleay32 -lz, $(LIBS))
-endif
-
-# to make ws2_32.lib the last library (must occur after definition of PORTNAME)
-ifeq ($(PORTNAME),win32)
+SHLIB_LINK += $(filter -leay32, $(LIBS))
+# those must be at the end
 SHLIB_LINK += -lwsock32 -lws2_32
 endif
 
-
 rijndael.o: rijndael.tbl
 
 rijndael.tbl:
index 419ec875078a00a9c271ec76c85fb21e5558e84b..c99fff3d322442bb7a86ce1b2ed4cb75f8c7fabb 100644 (file)
@@ -1,4 +1,3 @@
-$PostgreSQL$
 
 pgcrypto - cryptographic functions for PostgreSQL
 =================================================
@@ -278,7 +277,7 @@ cracking.  Or may not.
 -------------------
 
 The functions here implement the encryption part of OpenPGP (RFC2440)
-standard.
+standard.   Supported are both symmetric-key and public-key encryption.
 
 
 5.1.  Overview
@@ -334,6 +333,10 @@ Options are described in section 5.7.
 
 Decrypt a symmetric-key encrypted PGP message.
 
+Decrypting bytea data with `pgp_sym_decrypt` is disallowed.
+This is to avoid outputting invalid character data.  Decrypting
+originally textual data with `pgp_sym_decrypt_bytea` is fine.
+
 Options are described in section 5.7.
 
 
@@ -362,6 +365,10 @@ key is password-protected, you must give the password in `psw`.  If
 there is no password, but you want to specify option for function, you
 need to give empty password.
 
+Decrypting bytea data with `pgp_pub_decrypt` is disallowed.
+This is to avoid outputting invalid character data.  Decrypting
+originally textual data with `pgp_pub_decrypt_bytea` is fine.
+
 Options are described in section 5.7.
 
 
@@ -422,7 +429,6 @@ cipher-algo::
   Default: aes128
   Applies: pgp_sym_encrypt, pgp_pub_encrypt
 
-
 compress-algo::
   Which compression algorithm to use.  Needs building with zlib.
 
@@ -492,7 +498,7 @@ s2k-cipher-algo::
   Which cipher to use for encrypting separate session key.
 
   Values: bf, aes, aes128, aes192, aes256
-  Default: same as cipher-algo.
+  Default: use cipher-algo.
   Applies: pgp_sym_encrypt
 
 unicode-mode::
@@ -513,7 +519,10 @@ Generate a new key:
 
     gpg --gen-key
 
-You need to pick "DSA and Elgamal" key type, others are sign-only.
+The preferred key type is "DSA and Elgamal".
+
+For RSA encryption you must create either DSA or RSA sign-only key
+as master and then add RSA encryption subkey with `gpg --edit-key`.
 
 List keys:
 
@@ -531,6 +540,9 @@ You need to use `dearmor()` on them before giving giving them to
 pgp_pub_* functions.  Or if you can handle binary data, you can drop
 "-a" from gpg.
 
+For more details see `man gpg`, http://www.gnupg.org/gph/en/manual.html[
+The GNU Privacy Handbook] and other docs on http://www.gnupg.org[] site.
+
 
 5.10.  Limitations of PGP code
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -538,9 +550,13 @@ pgp_pub_* functions.  Or if you can handle binary data, you can drop
 - No support for signing.  That also means that it is not checked
   whether the encryption subkey belongs to master key.
 
-- No support for RSA keys.  Only Elgamal encryption keys are supported
+- No support for encryption key as master key.  As such practice
+  is generally discouraged, it should not be a problem.
 
-- No support for several encryption subkeys.
+- No support for several subkeys.  This may seem like a problem, as this
+  is common practice.  On the other hand, you should not use your regular
+  GPG/PGP keys with pgcrypto, but create new ones, as the usage scenario
+  is rather different.
 
 
 6.  Raw encryption
@@ -631,6 +647,9 @@ I have used code from following sources:
 9.1.  Useful reading
 ~~~~~~~~~~~~~~~~~~~~~
 
+http://www.gnupg.org/gph/en/manual.html[]::
+       The GNU Privacy Handbook
+
 http://www.openwall.com/crypt/[]::
        Describes the crypt-blowfish algorithm.
 
@@ -673,3 +692,7 @@ http://jlcooke.ca/random/[]::
 
 http://www.cs.ut.ee/~helger/crypto/[]::
        Collection of cryptology pointers.
+
+
+// $PostgreSQL$
+
index ba7d4262377875b2e2b3746db0f58741f4026531..60a89e5c48871837d094226cf68dcc12b4a83a72 100644 (file)
@@ -99,4 +99,4 @@ em9va2E=
 =ZZZZ
 -----END PGP MESSAGE-----
 ');
-ERROR:  dearmor: Corrupt ascii-armor
+ERROR:  Corrupt ascii-armor
index b04bae5720737a3bc5a2f96b1af420d2bea7ae39..ab33a04eec3319de634707acc64692df2a63fcac 100644 (file)
@@ -43,7 +43,7 @@ NOTICE:  pgp_decrypt: unexpected compress_algo: expected 1 got 0
 
 -- bytea as text
 select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz');
-ERROR:  pgp_decrypt error: Not text data
+ERROR:  Not text data
 -- text as bytea
 select pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz');
  pgp_sym_decrypt_bytea 
index 300d41adcd1885ce76a1fe3e00d18ea7dfc9773c..1fe008890fbd1e273415f7a0e74fbaeaa9af3979 100644 (file)
@@ -21,13 +21,19 @@ select pgp_key_id(dearmor(pubkey)) from keytbl where id=3;
 (1 row)
 
 select pgp_key_id(dearmor(pubkey)) from keytbl where id=4; -- should fail
-ERROR:  No usable key found (expecting Elgamal key)
+ERROR:  No encryption key found
 select pgp_key_id(dearmor(pubkey)) from keytbl where id=5;
     pgp_key_id    
 ------------------
  D936CF64BB73F466
 (1 row)
 
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=6;
+    pgp_key_id    
+------------------
+ FD0206C409B74875
+(1 row)
+
 select pgp_key_id(dearmor(seckey)) from keytbl where id=1;
     pgp_key_id    
 ------------------
@@ -47,13 +53,19 @@ select pgp_key_id(dearmor(seckey)) from keytbl where id=3;
 (1 row)
 
 select pgp_key_id(dearmor(seckey)) from keytbl where id=4; -- should fail
-ERROR:  No usable key found (expecting Elgamal key)
+ERROR:  No encryption key found
 select pgp_key_id(dearmor(seckey)) from keytbl where id=5;
     pgp_key_id    
 ------------------
  D936CF64BB73F466
 (1 row)
 
+select pgp_key_id(dearmor(seckey)) from keytbl where id=6;
+    pgp_key_id    
+------------------
+ FD0206C409B74875
+(1 row)
+
 select pgp_key_id(dearmor(data)) as data_key_id
 from encdata order by id;
    data_key_id    
@@ -61,5 +73,6 @@ from encdata order by id;
  D936CF64BB73F466
  2C226E1FFE5CC7D4
  B68504FD128E1FF9
-(3 rows)
+ FD0206C409B74875
+(4 rows)
 
index 28881ad3479a73c052a7136d8b6c5e594f18a739..7d16a43279d97b2e7dded1137d506ebb7e35a651 100644 (file)
@@ -326,6 +326,97 @@ saCh6QCfR1O48O8nYN93SPSfIFZK5rEmdv8=
 =Y6Qv
 -----END PGP PRIVATE KEY BLOCK-----
 ');
+insert into keytbl (id, name, pubkey, seckey)
+values (6, 'rsaenc2048', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQELBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj
+UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW
+czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT
+4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ
+dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4
+NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYptCVSU0EgMjA0OCBFbmMgPHJz
+YTIwNDhlbmNAZXhhbXBsZS5vcmc+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMV
+AgMDFgIBAh4BAheAAAoJEMiZ6pNEGVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8
+JCaxHa31wH3PKqGtq2M+cpb2rXf7gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw
++IkhihEb5bWxQBNj+3zAFs1YX6v2HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzku
+UOhcgfpBgIt3Q+MpT6M2+OIF7lVfSb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQ
+RJ6DWH61F8fFIDJg1z+A/Obx4fqX6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO8
+0g/oVYBbuvOYedffDBeQarhERZ5W2TnIE+nqY61YOLBqosliygdZTXULzNi5AQsE
+QuvaugEIAOuCJZdkzORA6e1lr81Lnr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPX
+z1YIrMTu+1rMIiy10IWbA6zgMTpzPhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfK
+lAXIxJurCHXTbEa+YvPdn76vJ3HsXOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zE
+FZcAoKbFqAAjDLEai64SoOFh0W3CsD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9U
+rHlolqYNhYze/uRLyfnUx9PN4r/GhEzauyDMV0smo91uB3aewPft+eCpmeWnu0PF
+JVK4xyRmhIq2rVCw16a1pBJirvGM+y0ABimJAR8EGAECAAkFAkLr2roCGwwACgkQ
+yJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+1iqYE0B0
+WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwarANhHxkWg
+w/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx2eVM1k+X
+dmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOyla+wJdro
+PYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CChbt6LhKh
+CLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug==
+=pwU2
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+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
+=UKh3
+-----END PGP PRIVATE KEY BLOCK-----
+');
 -- elg1024 / aes128
 insert into encdata (id, data) values (1, '
 -----BEGIN PGP MESSAGE-----
@@ -393,6 +484,22 @@ DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglTVTfYmi1ToZDDipkALBhndQ==
 =L/M/
 -----END PGP MESSAGE-----
 ');
+-- rsaenc2048 / aes128
+insert into encdata (id, data) values (4, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQEMA/0CBsQJt0h1AQf+JyYnCiortj26P11zk28MKOGfWpWyAhuIgwbJXsdQ+e6r
+pEyyqs9GC6gI7SNF6+J8B/gsMwvkAL4FHAQCvA4ZZ6eeXR1Of4YG22JQGmpWVWZg
+DTyfhA2vkczuqfAD2tgUpMT6sdyGkQ/fnQ0lknlfHgC5GRx7aavOoAKtMqiZW5PR
+yae/qR48mjX7Mb+mLvbagv9mHEgQSmHwFpaq2k456BbcZ23bvCmBnCvqV/90Ggfb
+VP6gkSoFVsJ19RHsOhW1dk9ehbl51WB3zUOO5FZWwUTY9DJvKblRK/frF0+CXjE4
+HfcZXHSpSjx4haGGTsMvEJ85qFjZpr0eTGOdY5cFhNJAAVP8MZfji7OhPRAoOOIK
+eRGOCkao12pvPyFTFnPd5vqmyBbdNpK4Q0hS82ljugMJvM0p3vJZVzW402Kz6iBL
+GQ==
+=XHkF
+-----END PGP MESSAGE-----
+');
 -- successful decrypt
 select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
 from keytbl, encdata where keytbl.id=1 and encdata.id=1;
@@ -415,22 +522,29 @@ from keytbl, encdata where keytbl.id=3 and encdata.id=3;
  Secret msg
 (1 row)
 
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=6 and encdata.id=4;
+ pgp_pub_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
 -- wrong key
 select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
 from keytbl, encdata where keytbl.id=2 and encdata.id=1;
-ERROR:  pgp_decrypt error: Data is not encrypted with this key
+ERROR:  Wrong key
 -- sign-only key
 select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
 from keytbl, encdata where keytbl.id=4 and encdata.id=1;
-ERROR:  pgp_decrypt error: No usable key found (expecting Elgamal key)
+ERROR:  No encryption key found
 -- password-protected secret key, no password
 select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
 from keytbl, encdata where keytbl.id=5 and encdata.id=1;
-ERROR:  pgp_decrypt error: Need password for secret key
+ERROR:  Need password for secret key
 -- password-protected secret key, wrong password
 select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'foo')
 from keytbl, encdata where keytbl.id=5 and encdata.id=1;
-ERROR:  pgp_decrypt error: Corrupt data
+ERROR:  Corrupt data
 -- password-protected secret key, right password
 select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'parool')
 from keytbl, encdata where keytbl.id=5 and encdata.id=1;
index a7b1c027eef669e87838918f01979c9277198c57..e222541c24c8b2e463380bd4f37ce30929ecc31e 100644 (file)
@@ -29,18 +29,27 @@ from keytbl where keytbl.id=3;
  Secret msg
 (1 row)
 
+select pgp_pub_decrypt(
+               pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+               dearmor(seckey))
+from keytbl where keytbl.id=6;
+ pgp_pub_decrypt 
+-----------------
+ Secret msg
+(1 row)
+
 -- try with rsa-sign only
 select pgp_pub_decrypt(
                pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
                dearmor(seckey))
 from keytbl where keytbl.id=4;
-ERROR:  pgp_encrypt error: No usable key found (expecting Elgamal key)
+ERROR:  No encryption key found
 -- try with secret key
 select pgp_pub_decrypt(
                pgp_pub_encrypt('Secret msg', dearmor(seckey)),
                dearmor(seckey))
 from keytbl where keytbl.id=1;
-ERROR:  pgp_encrypt error: Refusing to encrypt with secret key
+ERROR:  Refusing to encrypt with secret key
 -- does text-to-bytea works
 select pgp_pub_decrypt_bytea(
                pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
@@ -56,4 +65,4 @@ select pgp_pub_decrypt(
                pgp_pub_encrypt_bytea('Secret msg', dearmor(pubkey)),
                dearmor(seckey))
 from keytbl where keytbl.id=1;
-ERROR:  pgp_decrypt error: Not text data
+ERROR:  Not text data
index 594331133d1e2ba4946775cdbe58246b93283008..192f4aba3142c23907fa00131a26ca3eb19c3373 100644 (file)
 
 static int read_pubkey_keyid(PullFilter *pkt, uint8 *keyid_buf)
 {
-       int res = 0;
-       PGP_PubKey *pk;
-
-       res = pgp_key_alloc(&pk);
-       if (res < 0)
-               return res;
+       int res;
+       PGP_PubKey *pk = NULL;
 
-       res = _pgp_read_public_key(pkt, pk);
+       res = _pgp_read_public_key(pkt, &pk);
        if (res < 0)
                goto err;
+
+       /* skip secret key part, if it exists */
        res = pgp_skip_packet(pkt);
        if (res < 0)
                goto err;
 
-       res = 0;
-       if (pk->algo == PGP_PUB_ELG_ENCRYPT)
+       /* is it encryption key */
+       switch (pk->algo)
        {
-               memcpy(keyid_buf, pk->key_id, 8);
-               res = 1;
+               case PGP_PUB_ELG_ENCRYPT:
+               case PGP_PUB_RSA_ENCRYPT:
+               case PGP_PUB_RSA_ENCRYPT_SIGN:
+                       memcpy(keyid_buf, pk->key_id, 8);
+                       res = 1;
+                       break;
+               default:
+                       res = 0;
        }
+
 err:
        pgp_key_free(pk);
        return res;
@@ -110,6 +115,7 @@ pgp_get_keyid(MBuf *pgp_data, char *dst)
        int got_pub_key=0, got_symenc_key=0, got_pubenc_key=0;
        int got_data=0;
        uint8 keyid_buf[8];
+       int got_main_key=0;
 
 
        res = pullf_create_mbuf_reader(&src, pgp_data);
@@ -128,6 +134,15 @@ pgp_get_keyid(MBuf *pgp_data, char *dst)
                {
                        case PGP_PKT_SECRET_KEY:
                        case PGP_PKT_PUBLIC_KEY:
+                               /* main key is for signing, so ignore it */
+                               if (!got_main_key)
+                               {
+                                       got_main_key = 1;
+                                       res = pgp_skip_packet(pkt);
+                               }
+                               else
+                                       res = PXE_PGP_MULTIPLE_KEYS;
+                               break;
                        case PGP_PKT_SECRET_SUBKEY:
                        case PGP_PKT_PUBLIC_SUBKEY:
                                res = read_pubkey_keyid(pkt, keyid_buf);
@@ -142,6 +157,7 @@ pgp_get_keyid(MBuf *pgp_data, char *dst)
                                break;
                        case PGP_PKT_SYMENCRYPTED_DATA:
                        case PGP_PKT_SYMENCRYPTED_DATA_MDC:
+                               /* don't skip it, just stop */
                                got_data = 1;
                                break;
                        case PGP_PKT_SYMENCRYPTED_SESSKEY:
@@ -179,10 +195,10 @@ pgp_get_keyid(MBuf *pgp_data, char *dst)
                res = PXE_PGP_CORRUPT_DATA;
 
        if (got_pub_key > 1)
-               res = -1;
+               res = PXE_PGP_MULTIPLE_KEYS;
 
        if (got_pubenc_key > 1)
-               res = -1;
+               res = PXE_PGP_MULTIPLE_KEYS;
 
        /*
         * if still ok, look what we got
index 214bcebcae35c80e7877d6978b52af54eea86f18..65e394b4be3d9080452a8fa624bed2ece001b29d 100644 (file)
@@ -48,3 +48,14 @@ pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2,
        return PXE_PGP_NO_BIGNUM;
 }
 
+int pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *m, PGP_MPI **c)
+{
+       return PXE_PGP_NO_BIGNUM;
+}
+
+int pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *c, PGP_MPI **m)
+{
+       return PXE_PGP_NO_BIGNUM;
+}
+
+
index 5078bb523c089730f20d4ed3bad10e8c26105fb9..f52e8cff059aa413d57d530d83ad2c4cf53b3180 100644 (file)
@@ -104,9 +104,9 @@ pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
        int res = PXE_PGP_MATH_FAILED;
        int k_bits;
        BIGNUM *m = mpi_to_bn(_m);
-       BIGNUM *p = mpi_to_bn(pk->elg_p);
-       BIGNUM *g = mpi_to_bn(pk->elg_g);
-       BIGNUM *y = mpi_to_bn(pk->elg_y);
+       BIGNUM *p = mpi_to_bn(pk->pub.elg.p);
+       BIGNUM *g = mpi_to_bn(pk->pub.elg.g);
+       BIGNUM *y = mpi_to_bn(pk->pub.elg.y);
        BIGNUM *k = BN_new();
        BIGNUM *yk = BN_new();
        BIGNUM *c1 = BN_new();
@@ -120,7 +120,7 @@ pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
         * generate k
         */
        k_bits = decide_k_bits(BN_num_bits(p));
-       if (!BN_generate_prime(k, k_bits, 0, NULL, NULL, NULL, NULL))
+       if (!BN_rand(k, k_bits, 0, 0))
                goto err;
 
        /*
@@ -159,8 +159,8 @@ pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2,
        int res = PXE_PGP_MATH_FAILED;
        BIGNUM *c1 = mpi_to_bn(_c1);
        BIGNUM *c2 = mpi_to_bn(_c2);
-       BIGNUM *p = mpi_to_bn(pk->elg_p);
-       BIGNUM *x = mpi_to_bn(pk->elg_x);
+       BIGNUM *p = mpi_to_bn(pk->pub.elg.p);
+       BIGNUM *x = mpi_to_bn(pk->sec.elg.x);
        BIGNUM *c1x = BN_new();
        BIGNUM *div = BN_new();
        BIGNUM *m = BN_new();
@@ -195,3 +195,65 @@ err:
        return res;
 }
 
+int
+pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *_m, PGP_MPI **c_p)
+{
+       int res = PXE_PGP_MATH_FAILED;
+       BIGNUM *m = mpi_to_bn(_m);
+       BIGNUM *e = mpi_to_bn(pk->pub.rsa.e);
+       BIGNUM *n = mpi_to_bn(pk->pub.rsa.n);
+       BIGNUM *c = BN_new();
+       BN_CTX *tmp = BN_CTX_new();
+
+       if (!m || !e || !n || !c || !tmp)
+               goto err;
+
+       /*
+        * c = m ^ e
+        */
+       if (!BN_mod_exp(c, m, e, n, tmp))
+               goto err;
+
+       *c_p = bn_to_mpi(c);
+       if (*c_p)
+               res = 0;
+err:
+       if (tmp) BN_CTX_free(tmp);
+       if (c) BN_clear_free(c);
+       if (n) BN_clear_free(n);
+       if (e) BN_clear_free(e);
+       if (m) BN_clear_free(m);
+       return res;
+}
+
+int
+pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *_c, PGP_MPI **m_p)
+{
+       int res = PXE_PGP_MATH_FAILED;
+       BIGNUM *c = mpi_to_bn(_c);
+       BIGNUM *d = mpi_to_bn(pk->sec.rsa.d);
+       BIGNUM *n = mpi_to_bn(pk->pub.rsa.n);
+       BIGNUM *m = BN_new();
+       BN_CTX *tmp = BN_CTX_new();
+
+       if (!m || !d || !n || !c || !tmp)
+               goto err;
+
+       /*
+        * m = c ^ d
+        */
+       if (!BN_mod_exp(m, c, d, n, tmp))
+               goto err;
+
+       *m_p = bn_to_mpi(m);
+       if (*m_p)
+               res = 0;
+err:
+       if (tmp) BN_CTX_free(tmp);
+       if (m) BN_clear_free(m);
+       if (n) BN_clear_free(n);
+       if (d) BN_clear_free(d);
+       if (c) BN_clear_free(c);
+       return res;
+}
+
index 0a368a6641e64c2182412890f4c99b39d5945353..3617c09e9e58bebee90ec969e18e48e433d0997f 100644 (file)
@@ -66,6 +66,8 @@ int pgp_mpi_create(uint8 *data, int bits, PGP_MPI **mpi)
 
 int pgp_mpi_free(PGP_MPI *mpi)
 {
+       if (mpi == NULL)
+               return 0;
        memset(mpi, 0, sizeof(*mpi) + mpi->bytes);
        px_free(mpi);
        return 0;
@@ -129,6 +131,6 @@ unsigned pgp_mpi_cksum(unsigned cksum, PGP_MPI *n)
        for (i = 0; i < n->bytes; i++)
                cksum += n->data[i];
 
-       return cksum;
+       return cksum & 0xFFFF;
 }
 
index 38dd3e172c7977fa2a956ee8cb02ec554b0cc179..9c7e46aa72872060ff5e35b86c02e134b7ec92e0 100644 (file)
@@ -496,7 +496,7 @@ encrypt_internal(int is_pubenc, int is_text,
                mbuf_free(dst);
                ereport(ERROR,
                                (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
-                                errmsg("pgp_encrypt error: %s", px_strerror(err))));
+                                errmsg("%s", px_strerror(err))));
        }
 
        /* res_len includes VARHDRSZ */
@@ -591,7 +591,7 @@ out:
                        mbuf_free(dst);
                ereport(ERROR,
                                (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
-                                errmsg("pgp_decrypt error: %s", px_strerror(err))));
+                                errmsg("%s", px_strerror(err))));
        }
 
        res_len = mbuf_steal_data(dst, &restmp);
@@ -879,7 +879,7 @@ pg_dearmor(PG_FUNCTION_ARGS)
        if (res_len < 0)
                ereport(ERROR,
                                (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
-                                errmsg("dearmor: %s", px_strerror(res_len))));
+                                errmsg("%s", px_strerror(res_len))));
        if (res_len > guess_len)
                ereport(ERROR,
                                (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
@@ -909,9 +909,7 @@ pgp_key_id_w(PG_FUNCTION_ARGS)
        buf = create_mbuf_from_vardata(data);
        res = palloc(VARHDRSZ + 17);
 
-       px_set_debug_handler(show_debug);
        res_len = pgp_get_keyid(buf, VARDATA(res));
-       px_set_debug_handler(NULL);
        mbuf_free(buf);
        if (res_len < 0)
                ereport(ERROR,
index 8673c030398dc7ae442baeda2d8dd2f5cb2559c9..f5836c351df22ad41be485a202e7e76eedb43753 100644 (file)
@@ -77,7 +77,7 @@ control_cksum(uint8 *msg, int msglen)
        unsigned my_cksum, got_cksum;
 
        if (msglen < 3)
-               return PXE_PGP_CORRUPT_DATA;
+               return PXE_PGP_WRONG_KEY;
 
        my_cksum = 0;
        for (i = 1; i < msglen - 2; i++)
@@ -86,11 +86,60 @@ control_cksum(uint8 *msg, int msglen)
        got_cksum = ((unsigned)(msg[msglen-2]) << 8) + msg[msglen-1];
        if (my_cksum != got_cksum) {
                px_debug("pubenc cksum failed");
-               return PXE_PGP_CORRUPT_DATA;
+               return PXE_PGP_WRONG_KEY;
        }
        return 0;
 }
 
+static int
+decrypt_elgamal(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
+{
+       int res;
+       PGP_MPI *c1 = NULL;
+       PGP_MPI *c2 = NULL;
+
+       if (pk->algo != PGP_PUB_ELG_ENCRYPT)
+               return PXE_PGP_WRONG_KEY;
+
+       /* read elgamal encrypted data */
+       res = pgp_mpi_read(pkt, &c1);
+       if (res < 0)
+               goto out;
+       res = pgp_mpi_read(pkt, &c2);
+       if (res < 0)
+               goto out;
+
+       /* decrypt */
+       res = pgp_elgamal_decrypt(pk, c1, c2, m_p);
+
+out:
+       pgp_mpi_free(c1);
+       pgp_mpi_free(c2);
+       return res;
+}
+
+static int
+decrypt_rsa(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
+{
+       int res;
+       PGP_MPI *c;
+
+       if (pk->algo != PGP_PUB_RSA_ENCRYPT
+                       && pk->algo != PGP_PUB_RSA_ENCRYPT_SIGN)
+               return PXE_PGP_WRONG_KEY;
+
+       /* read rsa encrypted data */
+       res = pgp_mpi_read(pkt, &c);
+       if (res < 0)
+               return res;
+
+       /* decrypt */
+       res = pgp_rsa_decrypt(pk, c, m_p);
+
+       pgp_mpi_free(c);
+       return res;
+}
+
 /* key id is missing - user is expected to try all keys */
 static const uint8
 any_key[] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -102,7 +151,6 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
        int algo;
        int res;
        uint8 key_id[8];
-       PGP_MPI *c1, *c2;
        PGP_PubKey *pk;
        uint8 *msg;
        int msglen;
@@ -113,11 +161,7 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
                px_debug("no pubkey?");
                return PXE_BUG;
        }
-       if (!pk->elg_p || !pk->elg_g || !pk->elg_y || !pk->elg_x) {
-               px_debug("seckey not loaded?");
-               return PXE_BUG;
-       }
-       
+
        GETBYTE(pkt, ver);
        if (ver != 3) {
                px_debug("unknown pubenc_sesskey pkt ver=%d", ver);
@@ -134,33 +178,25 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
         && memcmp(key_id, pk->key_id, 8) != 0)
        {
                px_debug("key_id's does not match");
-               return PXE_PGP_WRONG_KEYID;
+               return PXE_PGP_WRONG_KEY;
        }
 
+       /*
+        * Decrypt
+        */
        GETBYTE(pkt, algo);
-       if (algo != PGP_PUB_ELG_ENCRYPT)
+       switch (algo)
        {
-               px_debug("unknown public-key algo=%d", algo);
-               if (algo == PGP_PUB_RSA_ENCRYPT || algo == PGP_PUB_RSA_ENCRYPT_SIGN)
-                       return PXE_PGP_RSA_UNSUPPORTED;
-               else
-                       return PXE_PGP_UNKNOWN_PUBALGO;
+               case PGP_PUB_ELG_ENCRYPT:
+                       res = decrypt_elgamal(pk, pkt, &m);
+                       break;
+               case PGP_PUB_RSA_ENCRYPT:
+               case PGP_PUB_RSA_ENCRYPT_SIGN:
+                       res = decrypt_rsa(pk, pkt, &m);
+                       break;
+               default:
+                       res = PXE_PGP_UNKNOWN_PUBALGO;
        }
-
-       /*
-        * read elgamal encrypted data
-        */
-       res = pgp_mpi_read(pkt, &c1);
-       if (res < 0)
-               return res;
-       res = pgp_mpi_read(pkt, &c2);
-       if (res < 0)
-               return res;
-
-       /*
-        * decrypt
-        */
-       res = pgp_elgamal_decrypt(pk, c1, c2, &m);
        if (res < 0)
                return res;
 
@@ -170,13 +206,14 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
        msg = check_eme_pkcs1_v15(m->data, m->bytes);
        if (msg == NULL) {
                px_debug("check_eme_pkcs1_v15 failed");
-               return PXE_PGP_CORRUPT_DATA;
+               res = PXE_PGP_WRONG_KEY;
+               goto out;
        }
        msglen = m->bytes - (msg - m->data);
 
        res = control_cksum(msg, msglen);
        if (res < 0)
-               return res;
+               goto out;
 
        /*
         * got sesskey
@@ -185,6 +222,10 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
        ctx->sess_key_len = msglen - 3;
        memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len);
 
+out:
+       pgp_mpi_free(m);
+       if (res < 0)
+               return res;
        return pgp_expect_packet_end(pkt);
 }
 
index 05ecce55c07c09c7d2fcae7425731bf87cba563b..6452583a7be198841945bdf0f19844d7e9db553e 100644 (file)
@@ -84,39 +84,16 @@ pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p)
        return 0;
 }
 
-/*
- * Decide the padded message length in bytes.
- * It should be as large as possible, but not larger
- * than p.
- *
- * To get max size (and assuming p may have weird sizes):
- * ((p->bytes * 8 - 6) > p->bits) ? (p->bytes - 1) : p->bytes
- *
- * Following mirrors gnupg behaviour.
- */
 static int
-decide_msglen(PGP_MPI *p)
-{
-       return p->bytes - 1;
-}
-
-static int
-create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p)
+create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p, int full_bytes)
 {
        uint8 *secmsg;
-       int res, i, full_bytes;
+       int res, i;
        unsigned cksum = 0;
        int klen = ctx->sess_key_len;
        uint8 *padded = NULL;
        PGP_MPI *m = NULL;
-       PGP_PubKey *pk = ctx->pub_key;
 
-       /*
-        * Refuse to operate with keys < 1024
-        */
-       if (pk->elg_p->bits < 1024)
-               return PXE_PGP_SHORT_ELGAMAL_KEY;
-       
        /* calc checksum */
        for (i = 0; i < klen; i++)
                cksum += ctx->sess_key[i];
@@ -133,7 +110,6 @@ create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p)
        /*
         * now create a large integer of it
         */
-       full_bytes = decide_msglen(pk->elg_p);
        res = pad_eme_pkcs1_v15(secmsg, klen + 3, full_bytes, &padded);
        if (res >= 0)
        {
@@ -156,37 +132,72 @@ create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p)
        return res;
 }
 
+static int
+encrypt_and_write_elgamal(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt)
+{
+       int res;
+       PGP_MPI *m = NULL, *c1 = NULL, *c2 = NULL;
+
+       /* create padded msg */
+       res = create_secmsg(ctx, &m, pk->pub.elg.p->bytes - 1);
+       if (res < 0)
+               goto err;
+
+       /* encrypt it */
+       res = pgp_elgamal_encrypt(pk, m, &c1, &c2);
+       if (res < 0)
+               goto err;
+
+       /* write out */
+       res = pgp_mpi_write(pkt, c1);
+       if (res < 0)
+               goto err;
+       res = pgp_mpi_write(pkt, c2);
+
+err:
+       pgp_mpi_free(m);
+       pgp_mpi_free(c1);
+       pgp_mpi_free(c2);
+       return res;
+}
+
+static int
+encrypt_and_write_rsa(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt)
+{
+       int res;
+       PGP_MPI *m = NULL, *c = NULL;
+
+       /* create padded msg */
+       res = create_secmsg(ctx, &m, pk->pub.rsa.n->bytes - 1);
+       if (res < 0)
+               goto err;
+
+       /* encrypt it */
+       res = pgp_rsa_encrypt(pk, m, &c);
+       if (res < 0)
+               goto err;
+
+       /* write out */
+       res = pgp_mpi_write(pkt, c);
+
+err:
+       pgp_mpi_free(m);
+       pgp_mpi_free(c);
+       return res;
+}
+
 int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst)
 {
        int res;
        PGP_PubKey *pk = ctx->pub_key;
-       PGP_MPI *m = NULL, *c1 = NULL, *c2 = NULL;
        uint8 ver = 3;
-       uint8 algo = PGP_PUB_ELG_ENCRYPT;
        PushFilter *pkt = NULL;
+       uint8 algo = pk->algo;
 
        if (pk == NULL) {
                px_debug("no pubkey?\n");
                return PXE_BUG;
        }
-       if (!pk->elg_p || !pk->elg_g || !pk->elg_y) {
-               px_debug("pubkey not loaded?\n");
-               return PXE_BUG;
-       }
-
-       /*
-        * sesskey packet
-        */
-       res = create_secmsg(ctx, &m);
-       if (res < 0)
-               goto err;
-
-       /*
-        * encrypt it
-        */
-       res = pgp_elgamal_encrypt(pk, m, &c1, &c2);
-       if (res < 0)
-               goto err;
 
        /*
         * now write packet
@@ -203,10 +214,17 @@ int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst)
        res = pushf_write(pkt, &algo, 1);
        if (res < 0)
                goto err;
-       res = pgp_mpi_write(pkt, c1);
-       if (res < 0)
-               goto err;
-       res = pgp_mpi_write(pkt, c2);
+
+       switch (algo)
+       {
+               case PGP_PUB_ELG_ENCRYPT:
+                       res = encrypt_and_write_elgamal(ctx, pk, pkt);
+                       break;
+               case PGP_PUB_RSA_ENCRYPT:
+               case PGP_PUB_RSA_ENCRYPT_SIGN:
+                       res = encrypt_and_write_rsa(ctx, pk, pkt);
+                       break;
+       }
        if (res < 0)
                goto err;
 
@@ -217,12 +235,6 @@ int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst)
 err:
        if (pkt)
                pushf_free(pkt);
-       if (m)
-               pgp_mpi_free(m);
-       if (c1)
-               pgp_mpi_free(c1);
-       if (c2)
-               pgp_mpi_free(c2);
 
        return res;
 }
index 1ac690214483ddea640734c41abba93e7252c979..5f69de72242b115036906a4d9bfadedc5a203753 100644 (file)
@@ -34,8 +34,6 @@
 #include "mbuf.h"
 #include "pgp.h"
 
-#define PXE_PGP_BAD_KEY -90
-
 int pgp_key_alloc(PGP_PubKey **pk_p)
 {
        PGP_PubKey *pk;
@@ -47,14 +45,35 @@ int pgp_key_alloc(PGP_PubKey **pk_p)
 
 void pgp_key_free(PGP_PubKey *pk)
 {
-       if (pk->elg_p)
-               pgp_mpi_free(pk->elg_p);
-       if (pk->elg_g)
-               pgp_mpi_free(pk->elg_g);
-       if (pk->elg_y)
-               pgp_mpi_free(pk->elg_y);
-       if (pk->elg_x)
-               pgp_mpi_free(pk->elg_x);
+       if (pk == NULL)
+               return;
+
+       switch (pk->algo)
+       {
+               case PGP_PUB_ELG_ENCRYPT:
+                       pgp_mpi_free(pk->pub.elg.p);
+                       pgp_mpi_free(pk->pub.elg.g);
+                       pgp_mpi_free(pk->pub.elg.y);
+                       pgp_mpi_free(pk->sec.elg.x);
+                       break;
+               case PGP_PUB_RSA_SIGN:
+               case PGP_PUB_RSA_ENCRYPT:
+               case PGP_PUB_RSA_ENCRYPT_SIGN:
+                       pgp_mpi_free(pk->pub.rsa.n);
+                       pgp_mpi_free(pk->pub.rsa.e);
+                       pgp_mpi_free(pk->sec.rsa.d);
+                       pgp_mpi_free(pk->sec.rsa.p);
+                       pgp_mpi_free(pk->sec.rsa.q);
+                       pgp_mpi_free(pk->sec.rsa.u);
+                       break;
+               case PGP_PUB_DSA_SIGN:
+                       pgp_mpi_free(pk->pub.dsa.p);
+                       pgp_mpi_free(pk->pub.dsa.q);
+                       pgp_mpi_free(pk->pub.dsa.g);
+                       pgp_mpi_free(pk->pub.dsa.y);
+                       pgp_mpi_free(pk->sec.dsa.x);
+                       break;
+       }
        memset(pk, 0, sizeof(*pk));
        px_free(pk);
 }
@@ -76,9 +95,21 @@ calc_key_id(PGP_PubKey *pk)
        switch (pk->algo)
        {
                case PGP_PUB_ELG_ENCRYPT:
-                       len += 2 + pk->elg_p->bytes;
-                       len += 2 + pk->elg_g->bytes;
-                       len += 2 + pk->elg_y->bytes;
+                       len += 2 + pk->pub.elg.p->bytes;
+                       len += 2 + pk->pub.elg.g->bytes;
+                       len += 2 + pk->pub.elg.y->bytes;
+                       break;
+               case PGP_PUB_RSA_SIGN:
+               case PGP_PUB_RSA_ENCRYPT:
+               case PGP_PUB_RSA_ENCRYPT_SIGN:
+                       len += 2 + pk->pub.rsa.n->bytes;
+                       len += 2 + pk->pub.rsa.e->bytes;
+                       break;
+               case PGP_PUB_DSA_SIGN:
+                       len += 2 + pk->pub.dsa.p->bytes;
+                       len += 2 + pk->pub.dsa.q->bytes;
+                       len += 2 + pk->pub.dsa.g->bytes;
+                       len += 2 + pk->pub.dsa.y->bytes;
                        break;
        }
 
@@ -94,9 +125,21 @@ calc_key_id(PGP_PubKey *pk)
        switch (pk->algo)
        {
                case PGP_PUB_ELG_ENCRYPT:
-                       pgp_mpi_hash(md, pk->elg_p);
-                       pgp_mpi_hash(md, pk->elg_g);
-                       pgp_mpi_hash(md, pk->elg_y);
+                       pgp_mpi_hash(md, pk->pub.elg.p);
+                       pgp_mpi_hash(md, pk->pub.elg.g);
+                       pgp_mpi_hash(md, pk->pub.elg.y);
+                       break;
+               case PGP_PUB_RSA_SIGN:
+               case PGP_PUB_RSA_ENCRYPT:
+               case PGP_PUB_RSA_ENCRYPT_SIGN:
+                       pgp_mpi_hash(md, pk->pub.rsa.n);
+                       pgp_mpi_hash(md, pk->pub.rsa.e);
+                       break;
+               case PGP_PUB_DSA_SIGN:
+                       pgp_mpi_hash(md, pk->pub.dsa.p);
+                       pgp_mpi_hash(md, pk->pub.dsa.q);
+                       pgp_mpi_hash(md, pk->pub.dsa.g);
+                       pgp_mpi_hash(md, pk->pub.dsa.y);
                        break;
        }
 
@@ -109,47 +152,82 @@ calc_key_id(PGP_PubKey *pk)
        return 0;
 }
 
-int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey *pk)
+int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
 {
        int res;
+       PGP_PubKey *pk;
+
+       res = pgp_key_alloc(&pk);
+       if (res < 0)
+               return res;
 
        /* get version */
        GETBYTE(pkt, pk->ver);
        if (pk->ver != 4) {
-               px_debug("\tunsupported version: %d", pk->ver);
-               return PXE_PGP_NOT_V4_KEYPKT;
+               res = PXE_PGP_NOT_V4_KEYPKT;
+               goto out;
        }
        
        /* read time */
        res = pullf_read_fixed(pkt, 4, pk->time);
        if (res < 0)
-               return res;
+               goto out;
 
        /* pubkey algorithm */
        GETBYTE(pkt, pk->algo);
 
        switch (pk->algo) {
-               case PGP_PUB_RSA_ENCRYPT_SIGN:
-               case PGP_PUB_RSA_ENCRYPT:
-               case PGP_PUB_RSA_SIGN:
                case PGP_PUB_DSA_SIGN:
-                       res = pgp_skip_packet(pkt);
+                       res = pgp_mpi_read(pkt, &pk->pub.dsa.p);
+                       if (res < 0) break;
+                       res = pgp_mpi_read(pkt, &pk->pub.dsa.q);
+                       if (res < 0) break;
+                       res = pgp_mpi_read(pkt, &pk->pub.dsa.g);
+                       if (res < 0) break;
+                       res = pgp_mpi_read(pkt, &pk->pub.dsa.y);
+                       if (res < 0) break;
+
+                       res = calc_key_id(pk);
                        break;
+
+               case PGP_PUB_RSA_SIGN:
+               case PGP_PUB_RSA_ENCRYPT:
+               case PGP_PUB_RSA_ENCRYPT_SIGN:
+                       res = pgp_mpi_read(pkt, &pk->pub.rsa.n);
+                       if (res < 0) break;
+                       res = pgp_mpi_read(pkt, &pk->pub.rsa.e);
+                       if (res < 0) break;
+
+                       res = calc_key_id(pk);
+
+                       if (pk->algo != PGP_PUB_RSA_SIGN)
+                               pk->can_encrypt = 1;
+                       break;
+
                case PGP_PUB_ELG_ENCRYPT:
-                       res = pgp_mpi_read(pkt, &pk->elg_p);
+                       res = pgp_mpi_read(pkt, &pk->pub.elg.p);
                        if (res < 0) break;
-                       res = pgp_mpi_read(pkt, &pk->elg_g);
+                       res = pgp_mpi_read(pkt, &pk->pub.elg.g);
                        if (res < 0) break;
-                       res = pgp_mpi_read(pkt, &pk->elg_y);
+                       res = pgp_mpi_read(pkt, &pk->pub.elg.y);
                        if (res < 0) break;
 
                        res = calc_key_id(pk);
+
+                       pk->can_encrypt = 1;
                        break;
+
                default:
                        px_debug("unknown public algo: %d", pk->algo);
                        res = PXE_PGP_UNKNOWN_PUBALGO;
        }
 
+out:
+       if (res < 0)
+               pgp_key_free(pk);
+       else
+               *pk_p = pk;
+
        return res;
 }
 
@@ -175,7 +253,18 @@ check_key_sha1(PullFilter *src, PGP_PubKey *pk)
        switch (pk->algo)
        {
                case PGP_PUB_ELG_ENCRYPT:
-                       pgp_mpi_hash(md, pk->elg_x);
+                       pgp_mpi_hash(md, pk->sec.elg.x);
+                       break;
+               case PGP_PUB_RSA_SIGN:
+               case PGP_PUB_RSA_ENCRYPT:
+               case PGP_PUB_RSA_ENCRYPT_SIGN:
+                       pgp_mpi_hash(md, pk->sec.rsa.d);
+                       pgp_mpi_hash(md, pk->sec.rsa.p);
+                       pgp_mpi_hash(md, pk->sec.rsa.q);
+                       pgp_mpi_hash(md, pk->sec.rsa.u);
+                       break;
+               case PGP_PUB_DSA_SIGN:
+                       pgp_mpi_hash(md, pk->sec.dsa.x);
                        break;
        }
        px_md_finish(md, my_sha1);
@@ -207,7 +296,18 @@ check_key_cksum(PullFilter *src, PGP_PubKey *pk)
        switch (pk->algo)
        {
                case PGP_PUB_ELG_ENCRYPT:
-                       my_cksum = pgp_mpi_cksum(0, pk->elg_x);
+                       my_cksum = pgp_mpi_cksum(0, pk->sec.elg.x);
+                       break;
+               case PGP_PUB_RSA_SIGN:
+               case PGP_PUB_RSA_ENCRYPT:
+               case PGP_PUB_RSA_ENCRYPT_SIGN:
+                       my_cksum = pgp_mpi_cksum(0, pk->sec.rsa.d);
+                       my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.p);
+                       my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.q);
+                       my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.u);
+                       break;
+               case PGP_PUB_DSA_SIGN:
+                       my_cksum = pgp_mpi_cksum(0, pk->sec.dsa.x);
                        break;
        }
        if (my_cksum != got_cksum)
@@ -218,7 +318,7 @@ check_key_cksum(PullFilter *src, PGP_PubKey *pk)
        return 0;
 }
 
-static int process_secret_key(PullFilter *pkt, PGP_PubKey *pk,
+static int process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
                const uint8 *key, int key_len)
 {
        int res;
@@ -229,16 +329,13 @@ static int process_secret_key(PullFilter *pkt, PGP_PubKey *pk,
        PullFilter *pf_decrypt = NULL, *pf_key;
        PGP_CFB *cfb = NULL;
        PGP_S2K s2k;
+       PGP_PubKey *pk;
 
        /* first read public key part */
-       res = _pgp_read_public_key(pkt, pk);
+       res = _pgp_read_public_key(pkt, &pk);
        if (res < 0)
                return res;
 
-       /* skip key? */
-       if (pk->algo != PGP_PUB_ELG_ENCRYPT)
-               return 0;
-
        /*
         * is secret key encrypted?
         */
@@ -282,15 +379,23 @@ static int process_secret_key(PullFilter *pkt, PGP_PubKey *pk,
 
        /* read secret key */
        switch (pk->algo) {
-               case PGP_PUB_RSA_ENCRYPT_SIGN:
-               case PGP_PUB_RSA_ENCRYPT:
                case PGP_PUB_RSA_SIGN:
-               case PGP_PUB_DSA_SIGN:
-                       px_debug("unsupported public algo: %d", pk->algo);
-                       res = PXE_PGP_UNSUPPORTED_PUBALGO;
+               case PGP_PUB_RSA_ENCRYPT:
+               case PGP_PUB_RSA_ENCRYPT_SIGN:
+                       res = pgp_mpi_read(pkt, &pk->sec.rsa.d);
+                       if (res < 0) break;
+                       res = pgp_mpi_read(pkt, &pk->sec.rsa.p);
+                       if (res < 0) break;
+                       res = pgp_mpi_read(pkt, &pk->sec.rsa.q);
+                       if (res < 0) break;
+                       res = pgp_mpi_read(pkt, &pk->sec.rsa.u);
+                       if (res < 0) break;
                        break;
                case PGP_PUB_ELG_ENCRYPT:
-                       res = pgp_mpi_read(pf_key, &pk->elg_x);
+                       res = pgp_mpi_read(pf_key, &pk->sec.elg.x);
+                       break;
+               case PGP_PUB_DSA_SIGN:
+                       res = pgp_mpi_read(pf_key, &pk->sec.dsa.x);
                        break;
                default:
                        px_debug("unknown public algo: %d", pk->algo);
@@ -312,31 +417,31 @@ static int process_secret_key(PullFilter *pkt, PGP_PubKey *pk,
        if (cfb)
                pgp_cfb_free(cfb);
 
+       if (res < 0)
+               pgp_key_free(pk);
+       else
+               *pk_p = pk;
+
        return res;
 }
 
 static int
 internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
-                                       const uint8 *key, int key_len, int pubtype)
+                                       const uint8 *psw, int psw_len, int pubtype)
 {
        PullFilter *pkt = NULL;
        int res;
        uint8 tag;
        int len;
+       PGP_PubKey *enc_key = NULL;
        PGP_PubKey *pk = NULL;
-       int got_key = 0;
-       int n_subkey = 0;
-
-       res = pgp_key_alloc(&pk);
-       if (res < 0)
-               return res;
+       int got_main_key = 0;
 
        /*
-        * Search for Elgamal key.
+        * Search for encryption key.
         *
         * Error out on anything fancy.
         */
-       res = PXE_PGP_KEYPKT_CORRUPT;
        while (1) {
                res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
                if (res <= 0)
@@ -346,46 +451,31 @@ internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
                        break;
                
                switch (tag) {
+                       case PGP_PKT_PUBLIC_KEY:
                        case PGP_PKT_SECRET_KEY:
-                               if (got_key)
+                               if (got_main_key)
                                {
                                        res = PXE_PGP_MULTIPLE_KEYS;
                                        break;
                                }
-                               got_key = 1;
-                               n_subkey = 0;
-                               /* fallthru */
-                       case PGP_PKT_SECRET_SUBKEY:
-                               if (tag == PGP_PKT_SECRET_SUBKEY)
-                                       n_subkey++;
+                               got_main_key = 1;
+                               res = pgp_skip_packet(pkt);
+                               break;
 
-                               if (n_subkey > 1)
-                                       res = PXE_PGP_MULTIPLE_SUBKEYS;
-                               else if (pubtype == 1)
-                                       res = process_secret_key(pkt, pk, key, key_len);
+                       case PGP_PKT_PUBLIC_SUBKEY:
+                               if (pubtype != 0)
+                                       res = PXE_PGP_EXPECT_SECRET_KEY;
                                else
-                                       res = PXE_PGP_EXPECT_PUBLIC_KEY;
+                                       res = _pgp_read_public_key(pkt, &pk);
                                break;
-                       case PGP_PKT_PUBLIC_KEY:
-                               if (got_key)
-                               {
-                                       res = PXE_PGP_MULTIPLE_KEYS;
-                                       break;
-                               }
-                               got_key = 1;
-                               n_subkey = 0;
-                               /* fallthru */
-                       case PGP_PKT_PUBLIC_SUBKEY:
-                               if (tag == PGP_PKT_PUBLIC_SUBKEY)
-                                       n_subkey++;
 
-                               if (n_subkey > 1)
-                                       res = PXE_PGP_MULTIPLE_SUBKEYS;
-                               else if (pubtype == 0)
-                                       res = _pgp_read_public_key(pkt, pk);
+                       case PGP_PKT_SECRET_SUBKEY:
+                               if (pubtype != 1)
+                                       res = PXE_PGP_EXPECT_PUBLIC_KEY;
                                else
-                                       res = PXE_PGP_EXPECT_SECRET_KEY;
+                                       res = process_secret_key(pkt, &pk, psw, psw_len);
                                break;
+
                        case PGP_PKT_SIGNATURE:
                        case PGP_PKT_MARKER:
                        case PGP_PKT_TRUST:
@@ -401,10 +491,25 @@ internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
                pullf_free(pkt);
                pkt = NULL;
 
-               if (res < 0)
-                       break;
+               if (pk != NULL)
+               {
+                       if (res >= 0 && pk->can_encrypt)
+                       {
+                               if (enc_key == NULL)
+                               {
+                                       enc_key = pk;
+                                       pk = NULL;
+                               }
+                               else
+                                       res = PXE_PGP_MULTIPLE_SUBKEYS;
+                       }
+
+                       if (pk)
+                               pgp_key_free(pk);
+                       pk = NULL;
+               }
 
-               if (pk->algo == PGP_PUB_ELG_ENCRYPT)
+               if (res < 0)
                        break;
        }
 
@@ -412,17 +517,17 @@ internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
                pullf_free(pkt);
 
        if (res < 0)
-               pgp_key_free(pk);
-       else {
-               if (pk->algo == PGP_PUB_ELG_ENCRYPT)
-                       *pk_p = pk;
-               else {
-                       pgp_key_free(pk);
-                       px_debug("non-elg");
-                       res = PXE_PGP_NO_USABLE_KEY;
-               }
+       {
+               if (enc_key)
+                       pgp_key_free(enc_key);
+               return res;
        }
-       return res < 0 ? res : 0;
+
+       if (!enc_key)
+               res = PXE_PGP_NO_USABLE_KEY;
+       else
+               *pk_p = enc_key;
+       return res;
 }
 
 int
index 8c69f91c26d00fee52c86601b501a99a39f05623..81934afbb2dedb20b3407c76d4900afcb1e4cc35 100644 (file)
@@ -173,14 +173,44 @@ struct PGP_PubKey {
        uint8 ver;
        uint8 time[4];
        uint8 algo;
-       /* public */
-       PGP_MPI *elg_p;
-       PGP_MPI *elg_g;
-       PGP_MPI *elg_y;
-       /* secret */
-       PGP_MPI *elg_x;
+
+       /* public part */
+       union {
+               struct {
+                       PGP_MPI *p;
+                       PGP_MPI *g;
+                       PGP_MPI *y;
+               } elg;
+               struct {
+                       PGP_MPI *n;
+                       PGP_MPI *e;
+               } rsa;
+               struct {
+                       PGP_MPI *p;
+                       PGP_MPI *q;
+                       PGP_MPI *g;
+                       PGP_MPI *y;
+               } dsa;
+       } pub;
+
+       /* secret part */
+       union {
+               struct {
+                       PGP_MPI *x;
+               } elg;
+               struct {
+                       PGP_MPI *d;
+                       PGP_MPI *p;
+                       PGP_MPI *q;
+                       PGP_MPI *u;
+               } rsa;
+               struct {
+                       PGP_MPI *x;
+               } dsa;
+       } sec;
 
        uint8 key_id[8];
+       int can_encrypt;
 };
 
 int                    pgp_init(PGP_Context ** ctx);
@@ -240,7 +270,7 @@ int pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src);
 
 int pgp_key_alloc(PGP_PubKey **pk_p);
 void pgp_key_free(PGP_PubKey *pk);
-int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey *pk);
+int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p);
 
 int pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt);
 int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
@@ -266,6 +296,8 @@ int pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *m,
                                                PGP_MPI **c1, PGP_MPI **c2);
 int pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *c1, PGP_MPI *c2,
                                                PGP_MPI **m);
+int pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *m, PGP_MPI **c);
+int pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *c, PGP_MPI **m);
 
 extern struct PullFilterOps pgp_decrypt_filter;
 
index 9b35c6945f0dcb32b34888544d09225dc7033c2d..a13811e537998da7a29754f777757533ddd62d83 100644 (file)
@@ -35,8 +35,6 @@
 #include "px-crypt.h"
 
 
-#ifndef PX_SYSTEM_CRYPT
-
 static char *
 run_crypt_des(const char *psw, const char *salt,
                          char *buf, unsigned len)
@@ -107,24 +105,6 @@ px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
        return c->crypt(psw, salt, buf, len);
 }
 
-#else                                                  /* PX_SYSTEM_CRYPT */
-
-extern char *crypt(const char *psw, const char *salt);
-
-char *
-px_crypt(const char *psw, const char *salt,
-                char *buf, unsigned len)
-{
-       char       *res;
-
-       res = crypt(psw, salt);
-       if (!res || strlen(res) >= len)
-               return NULL;
-       strcpy(buf, res);
-       return buf;
-}
-#endif
-
 /*
  * salt generators
  */
index e53d45137a58967125e9477606ae3835e05b706a..4e3096b744ad1c8d67bd3072eea0264237fa5f09 100644 (file)
@@ -73,8 +73,6 @@ char *_crypt_gensalt_md5_rn(unsigned long count,
 char *_crypt_gensalt_blowfish_rn(unsigned long count,
                         const char *input, int size, char *output, int output_size);
 
-#ifndef PX_SYSTEM_CRYPT
-
 /* disable 'extended DES crypt' */
 /* #define DISABLE_XDES */
 
@@ -88,6 +86,5 @@ char     *px_crypt_des(const char *key, const char *setting);
 /* crypt-md5.c */
 char *px_crypt_md5(const char *pw, const char *salt,
                         char *dst, unsigned dstlen);
-#endif   /* !PX_SYSTEM_CRYPT */
 
 #endif   /* _PX_CRYPT_H */
index fa8ffdcfaf80c57db8a4b7876ca29b66857d3f4f..f3a49c87b62fce204ecc0a67f46290eacc1809eb 100644 (file)
@@ -72,14 +72,14 @@ static const struct error_desc px_err_list[] = {
        {PXE_PGP_SHORT_ELGAMAL_KEY, "Elgamal keys must be at least 1024 bits long"},
        {PXE_PGP_RSA_UNSUPPORTED, "pgcrypto does not support RSA keys"},
        {PXE_PGP_UNKNOWN_PUBALGO, "Unknown public-key encryption algorithm"},
-       {PXE_PGP_WRONG_KEYID, "Data is not encrypted with this key"},
+       {PXE_PGP_WRONG_KEY, "Wrong key"},
        {PXE_PGP_MULTIPLE_KEYS,
                "Several keys given - pgcrypto does not handle keyring"},
        {PXE_PGP_EXPECT_PUBLIC_KEY, "Refusing to encrypt with secret key"},
        {PXE_PGP_EXPECT_SECRET_KEY, "Cannot decrypt with public key"},
        {PXE_PGP_NOT_V4_KEYPKT, "Only V4 key packets are supported"},
        {PXE_PGP_KEYPKT_CORRUPT, "Corrupt key packet"},
-       {PXE_PGP_NO_USABLE_KEY, "No usable key found (expecting Elgamal key)"},
+       {PXE_PGP_NO_USABLE_KEY, "No encryption key found"},
        {PXE_PGP_NEED_SECRET_PSW, "Need password for secret key"},
        {PXE_PGP_BAD_S2K_MODE, "Bad S2K mode"},
        {PXE_PGP_UNSUPPORTED_PUBALGO, "Unsupported public key algorithm"},
index dd4f646417e73f38fb9309852d8f212d0772a04e..52947209c7c41debe12f038831497ae94e3d3558 100644 (file)
@@ -101,7 +101,7 @@ void                px_free(void *p);
 #define PXE_PGP_SHORT_ELGAMAL_KEY      -110
 #define PXE_PGP_RSA_UNSUPPORTED                -111
 #define PXE_PGP_UNKNOWN_PUBALGO                -112
-#define PXE_PGP_WRONG_KEYID                    -113
+#define PXE_PGP_WRONG_KEY                      -113
 #define PXE_PGP_MULTIPLE_KEYS          -114
 #define PXE_PGP_EXPECT_PUBLIC_KEY      -115
 #define PXE_PGP_EXPECT_SECRET_KEY      -116
index d979bb93d97e2862cb45ae35e5f0724484513050..c525ce307e908576263b6a2ab8761629f073a460 100644 (file)
@@ -9,12 +9,14 @@ select pgp_key_id(dearmor(pubkey)) from keytbl where id=2;
 select pgp_key_id(dearmor(pubkey)) from keytbl where id=3;
 select pgp_key_id(dearmor(pubkey)) from keytbl where id=4; -- should fail
 select pgp_key_id(dearmor(pubkey)) from keytbl where id=5;
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=6;
 
 select pgp_key_id(dearmor(seckey)) from keytbl where id=1;
 select pgp_key_id(dearmor(seckey)) from keytbl where id=2;
 select pgp_key_id(dearmor(seckey)) from keytbl where id=3;
 select pgp_key_id(dearmor(seckey)) from keytbl where id=4; -- should fail
 select pgp_key_id(dearmor(seckey)) from keytbl where id=5;
+select pgp_key_id(dearmor(seckey)) from keytbl where id=6;
 
 select pgp_key_id(dearmor(data)) as data_key_id
 from encdata order by id;
index 13fe090c6749d5fe4cbac1638a93bb4265cb8b07..82c6086ce582534fba49373b3f6a79653be9268c 100644 (file)
@@ -334,6 +334,98 @@ saCh6QCfR1O48O8nYN93SPSfIFZK5rEmdv8=
 -----END PGP PRIVATE KEY BLOCK-----
 ');
 
+insert into keytbl (id, name, pubkey, seckey)
+values (6, 'rsaenc2048', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQELBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj
+UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW
+czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT
+4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ
+dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4
+NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYptCVSU0EgMjA0OCBFbmMgPHJz
+YTIwNDhlbmNAZXhhbXBsZS5vcmc+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMV
+AgMDFgIBAh4BAheAAAoJEMiZ6pNEGVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8
+JCaxHa31wH3PKqGtq2M+cpb2rXf7gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw
++IkhihEb5bWxQBNj+3zAFs1YX6v2HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzku
+UOhcgfpBgIt3Q+MpT6M2+OIF7lVfSb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQ
+RJ6DWH61F8fFIDJg1z+A/Obx4fqX6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO8
+0g/oVYBbuvOYedffDBeQarhERZ5W2TnIE+nqY61YOLBqosliygdZTXULzNi5AQsE
+QuvaugEIAOuCJZdkzORA6e1lr81Lnr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPX
+z1YIrMTu+1rMIiy10IWbA6zgMTpzPhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfK
+lAXIxJurCHXTbEa+YvPdn76vJ3HsXOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zE
+FZcAoKbFqAAjDLEai64SoOFh0W3CsD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9U
+rHlolqYNhYze/uRLyfnUx9PN4r/GhEzauyDMV0smo91uB3aewPft+eCpmeWnu0PF
+JVK4xyRmhIq2rVCw16a1pBJirvGM+y0ABimJAR8EGAECAAkFAkLr2roCGwwACgkQ
+yJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+1iqYE0B0
+WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwarANhHxkWg
+w/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx2eVM1k+X
+dmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOyla+wJdro
+PYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CChbt6LhKh
+CLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug==
+=pwU2
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+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
+=UKh3
+-----END PGP PRIVATE KEY BLOCK-----
+');
+
 
 -- elg1024 / aes128
 insert into encdata (id, data) values (1, '
@@ -405,6 +497,23 @@ DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglTVTfYmi1ToZDDipkALBhndQ==
 -----END PGP MESSAGE-----
 ');
 
+-- rsaenc2048 / aes128
+insert into encdata (id, data) values (4, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQEMA/0CBsQJt0h1AQf+JyYnCiortj26P11zk28MKOGfWpWyAhuIgwbJXsdQ+e6r
+pEyyqs9GC6gI7SNF6+J8B/gsMwvkAL4FHAQCvA4ZZ6eeXR1Of4YG22JQGmpWVWZg
+DTyfhA2vkczuqfAD2tgUpMT6sdyGkQ/fnQ0lknlfHgC5GRx7aavOoAKtMqiZW5PR
+yae/qR48mjX7Mb+mLvbagv9mHEgQSmHwFpaq2k456BbcZ23bvCmBnCvqV/90Ggfb
+VP6gkSoFVsJ19RHsOhW1dk9ehbl51WB3zUOO5FZWwUTY9DJvKblRK/frF0+CXjE4
+HfcZXHSpSjx4haGGTsMvEJ85qFjZpr0eTGOdY5cFhNJAAVP8MZfji7OhPRAoOOIK
+eRGOCkao12pvPyFTFnPd5vqmyBbdNpK4Q0hS82ljugMJvM0p3vJZVzW402Kz6iBL
+GQ==
+=XHkF
+-----END PGP MESSAGE-----
+');
+
 -- successful decrypt
 select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
 from keytbl, encdata where keytbl.id=1 and encdata.id=1;
@@ -415,6 +524,9 @@ from keytbl, encdata where keytbl.id=2 and encdata.id=2;
 select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
 from keytbl, encdata where keytbl.id=3 and encdata.id=3;
 
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=6 and encdata.id=4;
+
 -- wrong key
 select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
 from keytbl, encdata where keytbl.id=2 and encdata.id=1;
index 89d05a7a36488d6119643d0809a764ad89a46852..62dd487c10ff70afa52a2bc5072911be058e402b 100644 (file)
@@ -18,6 +18,11 @@ select pgp_pub_decrypt(
                dearmor(seckey))
 from keytbl where keytbl.id=3;
 
+select pgp_pub_decrypt(
+               pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+               dearmor(seckey))
+from keytbl where keytbl.id=6;
+
 -- try with rsa-sign only
 select pgp_pub_decrypt(
                pgp_pub_encrypt('Secret msg', dearmor(pubkey)),