mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-17 19:30:00 +08:00
Add missing pgcrypto files from previous commit.
This commit is contained in:
parent
42e7b0f02f
commit
e94dd6ab91
102
contrib/pgcrypto/expected/pgp-armor.out
Normal file
102
contrib/pgcrypto/expected/pgp-armor.out
Normal file
@ -0,0 +1,102 @@
|
||||
--
|
||||
-- PGP Armor
|
||||
--
|
||||
select armor('');
|
||||
armor
|
||||
---------------------------------------------------------------
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
=twTO
|
||||
-----END PGP MESSAGE-----
|
||||
|
||||
(1 row)
|
||||
|
||||
select armor('test');
|
||||
armor
|
||||
------------------------------------------------------------------------
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
dGVzdA==
|
||||
=+G7Q
|
||||
-----END PGP MESSAGE-----
|
||||
|
||||
(1 row)
|
||||
|
||||
select dearmor(armor(''));
|
||||
dearmor
|
||||
---------
|
||||
|
||||
(1 row)
|
||||
|
||||
select dearmor(armor('zooka'));
|
||||
dearmor
|
||||
---------
|
||||
zooka
|
||||
(1 row)
|
||||
|
||||
select armor('0123456789abcdef0123456789abcdef0123456789abcdef
|
||||
0123456789abcdef0123456789abcdef0123456789abcdef');
|
||||
armor
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmCjAxMjM0NTY3
|
||||
ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZg==
|
||||
=JFw5
|
||||
-----END PGP MESSAGE-----
|
||||
|
||||
(1 row)
|
||||
|
||||
-- lots formatting
|
||||
select dearmor(' a pgp msg:
|
||||
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: Some junk
|
||||
|
||||
em9va2E=
|
||||
|
||||
=D5cR
|
||||
|
||||
-----END PGP MESSAGE-----');
|
||||
dearmor
|
||||
---------
|
||||
zooka
|
||||
(1 row)
|
||||
|
||||
-- lots messages
|
||||
select dearmor('
|
||||
wrong packet:
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
d3Jvbmc=
|
||||
=vCYP
|
||||
-----END PGP MESSAGE-----
|
||||
|
||||
right packet:
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
cmlnaHQ=
|
||||
=nbpj
|
||||
-----END PGP MESSAGE-----
|
||||
|
||||
use only first packet
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
d3Jvbmc=
|
||||
=vCYP
|
||||
-----END PGP MESSAGE-----
|
||||
');
|
||||
dearmor
|
||||
---------
|
||||
right
|
||||
(1 row)
|
||||
|
||||
-- bad crc
|
||||
select dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
em9va2E=
|
||||
=ZZZZ
|
||||
-----END PGP MESSAGE-----
|
||||
');
|
||||
ERROR: dearmor: Corrupt ascii-armor
|
50
contrib/pgcrypto/expected/pgp-compression.out
Normal file
50
contrib/pgcrypto/expected/pgp-compression.out
Normal file
@ -0,0 +1,50 @@
|
||||
--
|
||||
-- PGP compression support
|
||||
--
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
ww0ECQMCsci6AdHnELlh0kQB4jFcVwHMJg0Bulop7m3Mi36s15TAhBo0AnzIrRFrdLVCkKohsS6+
|
||||
DMcmR53SXfLoDJOv/M8uKj3QSq7oWNIp95pxfA==
|
||||
=tbSn
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'key', 'expect-compress-algo=1');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret message', 'key', 'compress-algo=0'),
|
||||
'key', 'expect-compress-algo=0');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret message', 'key', 'compress-algo=1'),
|
||||
'key', 'expect-compress-algo=1');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret message', 'key', 'compress-algo=2'),
|
||||
'key', 'expect-compress-algo=2');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message
|
||||
(1 row)
|
||||
|
||||
-- level=0 should turn compression off
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret message', 'key',
|
||||
'compress-algo=2, compress-level=0'),
|
||||
'key', 'expect-compress-algo=0');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message
|
||||
(1 row)
|
||||
|
366
contrib/pgcrypto/expected/pgp-decrypt.out
Normal file
366
contrib/pgcrypto/expected/pgp-decrypt.out
Normal file
@ -0,0 +1,366 @@
|
||||
--
|
||||
-- pgp_descrypt tests
|
||||
--
|
||||
-- Checking ciphers
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.blowfish.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBAMCfFNwxnvodX9g0jwB4n4s26/g5VmKzVab1bX1SmwY7gvgvlWdF3jKisvS
|
||||
yA6Ce1QTMK3KdL2MPfamsTUSAML8huCJMwYQFfE=
|
||||
=JcP+
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCci97v0Q6Z0Zg0kQBsVf5Oe3iC+FBzUmuMV9KxmAyOMyjCc/5i8f1Eest
|
||||
UTAsG35A1vYs02VARKzGz6xI2UHwFUirP+brPBg3Ee7muOx8pA==
|
||||
=XtrP
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes192.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0ECAMCI7YQpWqp3D1g0kQBCjB7GlX7+SQeXNleXeXQ78ZAPNliquGDq9u378zI
|
||||
5FPTqAhIB2/2fjY8QEIs1ai00qphjX2NitxV/3Wn+6dufB4Q4g==
|
||||
=rCZt
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes256.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0ECQMC4f/5djqCC1Rg0kQBTHEPsD+Sw7biBsM2er3vKyGPAQkuTBGKC5ie7hT/
|
||||
lceMfQdbAg6oTFyJpk/wH18GzRDphCofg0X8uLgkAKMrpcmgog==
|
||||
=fB6S
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
-- Checking MDC modes
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.nomdc.s2k3.z0
|
||||
|
||||
jA0EBwMCnv07rlXqWctgyS2Dm2JfOKCRL4sLSLJUC8RS2cH7cIhKSuLitOtyquB+
|
||||
u9YkgfJfsuRJmgQ9tmo=
|
||||
=60ui
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCEeP3idNjQ1Bg0kQBf4G0wX+2QNzLh2YNwYkQgQkfYhn/hLXjV4nK9nsE
|
||||
8Ex1Dsdt5UPvOz8W8VKQRS6loOfOe+yyXil8W3IYFwUpdDUi+Q==
|
||||
=moGf
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
-- Checking hashes
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.md5.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMClrXXtOXetohg0kQBn0Kl1ymevQZRHkdoYRHgzCwSQEiss7zYff2UNzgO
|
||||
KyRrHf7zEBuZiZ2AG34jNVMOLToj1jJUg5zTSdecUzQVCykWTA==
|
||||
=NyLk
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCApbdlrURoWJg0kQBzHM/E0o7djY82bNuspjxjAcPFrrtp0uvDdMQ4z2m
|
||||
/PM8jhgI5vxFYfNQjLl8y3fHYIomk9YflN9K/Q13iq8A8sjeTw==
|
||||
=FxbQ
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
-- Checking S2K modes
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k0.z0
|
||||
|
||||
jAQEBwAC0kQBKTaLAKE3xzps+QIZowqRNb2eAdzBw2LxEW2YD5PgNlbhJdGg+dvw
|
||||
Ah9GXjGS1TVALzTImJbz1uHUZRfhJlFbc5yGQw==
|
||||
=YvkV
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k1.z0
|
||||
|
||||
jAwEBwEC/QTByBLI3b/SRAHPxKzI6SZBo5lAEOD+EsvKQWO4adL9tDY+++Iqy1xK
|
||||
4IaWXVKEj9R2Lr2xntWWMGZtcKtjD2lFFRXXd9dZp1ZThNDz
|
||||
=dbXm
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCEq4Su3ZqNEJg0kQB4QG5jBTKF0i04xtH+avzmLhstBNRxvV3nsmB3cwl
|
||||
z+9ZaA/XdSx5ZiFnMym8P6r8uY9rLjjNptvvRHlxIReF+p9MNg==
|
||||
=VJKg
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes192.sha1.mdc.s2k0.z0
|
||||
|
||||
jAQECAAC0kQBBDnQWkgsx9YFaqDfWmpsiyAJ6y2xG/sBvap1dySYEMuZ+wJTXQ9E
|
||||
Cr3i2M7TgVZ0M4jp4QL0adG1lpN5iK7aQeOwMw==
|
||||
=cg+i
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes192.sha1.mdc.s2k1.z0
|
||||
|
||||
jAwECAECruOfyNDFiTnSRAEVoGXm4A9UZKkWljdzjEO/iaE7mIraltIpQMkiqCh9
|
||||
7h8uZ2u9uRBOv222fZodGvc6bvq/4R4hAa/6qSHtm8mdmvGt
|
||||
=aHmC
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes192.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0ECAMCjFn6SRi3SONg0kQBqtSHPaD0m7rXfDAhCWU/ypAsI93GuHGRyM99cvMv
|
||||
q6eF6859ZVnli3BFSDSk3a4e/pXhglxmDYCfjAXkozKNYLo6yw==
|
||||
=K0LS
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes256.sha1.mdc.s2k0.z0
|
||||
|
||||
jAQECQAC0kQB4L1eMbani07XF2ZYiXNK9LW3v8w41oUPl7dStmrJPQFwsdxmrDHu
|
||||
rQr3WbdKdY9ufjOE5+mXI+EFkSPrF9rL9NCq6w==
|
||||
=RGts
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes256.sha1.mdc.s2k1.z0
|
||||
|
||||
jAwECQECKHhrou7ZOIXSRAHWIVP+xjVQcjAVBTt+qh9SNzYe248xFTwozkwev3mO
|
||||
+KVJW0qhk0An+Y2KF99/bYFl9cL5D3Tl43fC8fXGl3x3m7pR
|
||||
=SUrU
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes256.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0ECQMCjc8lwZu8Fz1g0kQBkEzjImi21liep5jj+3dAJ2aZFfUkohi8b3n9z+7+
|
||||
4+NRzL7cMW2RLAFnJbiqXDlRHMwleeuLN1up2WIxsxtYYuaBjA==
|
||||
=XZrG
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
-- Checking longer passwords
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCx6dBiuqrYNRg0kQBEo63AvA1SCslxP7ayanLf1H0/hlk2nONVhTwVEWi
|
||||
tTGup1mMz6Cfh1uDRErUuXpx9A0gdMu7zX0o5XjrL7WGDAZdSw==
|
||||
=XKKG
|
||||
-----END PGP MESSAGE-----
|
||||
'), '0123456789abcdefghij');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCBDvYuS990iFg0kQBW31UK5OiCjWf5x6KJ8qNNT2HZWQCjCBZMU0XsOC6
|
||||
CMxFKadf144H/vpoV9GA0f22keQgCl0EsTE4V4lweVOPTKCMJg==
|
||||
=gWDh
|
||||
-----END PGP MESSAGE-----
|
||||
'), '0123456789abcdefghij2jk4h5g2j54khg23h54g2kh54g2khj54g23hj54');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCqXbFafC+ofVg0kQBejyiPqH0QMERVGfmPOjtAxvyG5KDIJPYojTgVSDt
|
||||
FwsDabdQUz5O7bgNSnxfmyw1OifGF+W2bIn/8W+0rDf8u3+O+Q==
|
||||
=OxOF
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'x');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret message.
|
||||
(1 row)
|
||||
|
||||
-- Checking various data
|
||||
select encode(digest(pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCGJ+SpuOysINg0kQBJfSjzsW0x4OVcAyr17O7FBvMTwIGeGcJd99oTQU8
|
||||
Xtx3kDqnhUq9Z1fS3qPbi5iNP2A9NxOBxPWz2JzxhydANlgbxg==
|
||||
=W/ik
|
||||
-----END PGP MESSAGE-----
|
||||
'), '0123456789abcdefghij'), 'sha1'), 'hex');
|
||||
encode
|
||||
------------------------------------------
|
||||
0225e3ede6f2587b076d021a189ff60aad67e066
|
||||
(1 row)
|
||||
|
||||
-- expected: 0225e3ede6f2587b076d021a189ff60aad67e066
|
||||
select encode(digest(pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat2.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCvdpDvidNzMxg0jUBvj8eS2+1t/9/zgemxvhtc0fvdKGGbjH7dleaTJRB
|
||||
SaV9L04ky1qECNDx3XjnoKLC+H7IOQ==
|
||||
=Fxen
|
||||
-----END PGP MESSAGE-----
|
||||
'), '0123456789abcdefghij'), 'sha1'), 'hex');
|
||||
encode
|
||||
------------------------------------------
|
||||
da39a3ee5e6b4b0d3255bfef95601890afd80709
|
||||
(1 row)
|
||||
|
||||
-- expected: da39a3ee5e6b4b0d3255bfef95601890afd80709
|
||||
select encode(digest(pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat3.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCxQvxJZ3G/HRg0lgBeYmTa7/uDAjPyFwSX4CYBgpZWVn/JS8JzILrcWF8
|
||||
gFnkUKIE0PSaYFp+Yi1VlRfUtRQ/X/LYNGa7tWZS+4VQajz2Xtz4vUeAEiYFYPXk
|
||||
73Hb8m1yRhQK
|
||||
=ivrD
|
||||
-----END PGP MESSAGE-----
|
||||
'), '0123456789abcdefghij'), 'sha1'), 'hex');
|
||||
encode
|
||||
------------------------------------------
|
||||
5e5c135efc0dd00633efc6dfd6e731ea408a5b4c
|
||||
(1 row)
|
||||
|
||||
-- expected: 5e5c135efc0dd00633efc6dfd6e731ea408a5b4c
|
||||
-- Checking CRLF
|
||||
select encode(digest(pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: crlf mess
|
||||
|
||||
ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms
|
||||
a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs
|
||||
=mBP9
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'key', 'convert-crlf=0'), 'sha1'), 'hex');
|
||||
encode
|
||||
------------------------------------------
|
||||
9353062be7720f1446d30b9e75573a4833886784
|
||||
(1 row)
|
||||
|
||||
-- expected: 9353062be7720f1446d30b9e75573a4833886784
|
||||
select encode(digest(pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: crlf mess
|
||||
|
||||
ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms
|
||||
a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs
|
||||
=mBP9
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'key', 'convert-crlf=1'), 'sha1'), 'hex');
|
||||
encode
|
||||
------------------------------------------
|
||||
7efefcab38467f7484d6fa43dc86cf5281bd78e2
|
||||
(1 row)
|
||||
|
||||
-- expected: 7efefcab38467f7484d6fa43dc86cf5281bd78e2
|
1
contrib/pgcrypto/expected/pgp-encrypt-DISABLED.out
Normal file
1
contrib/pgcrypto/expected/pgp-encrypt-DISABLED.out
Normal file
@ -0,0 +1 @@
|
||||
-- no random source
|
189
contrib/pgcrypto/expected/pgp-encrypt.out
Normal file
189
contrib/pgcrypto/expected/pgp-encrypt.out
Normal file
@ -0,0 +1,189 @@
|
||||
--
|
||||
-- PGP encrypt
|
||||
--
|
||||
select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), 'key');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
-- check whether the defaults are ok
|
||||
select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'),
|
||||
'key', 'expect-cipher-algo=aes128,
|
||||
expect-disable-mdc=0,
|
||||
expect-sess-key=0,
|
||||
expect-s2k-mode=3,
|
||||
expect-s2k-digest-algo=sha1,
|
||||
expect-compress-algo=0
|
||||
');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
-- maybe the expect- stuff simply does not work
|
||||
select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'),
|
||||
'key', 'expect-cipher-algo=bf,
|
||||
expect-disable-mdc=1,
|
||||
expect-sess-key=1,
|
||||
expect-s2k-mode=0,
|
||||
expect-s2k-digest-algo=md5,
|
||||
expect-compress-algo=1
|
||||
');
|
||||
NOTICE: pgp_decrypt: unexpected cipher_algo: expected 4 got 7
|
||||
NOTICE: pgp_decrypt: unexpected s2k_mode: expected 0 got 3
|
||||
NOTICE: pgp_decrypt: unexpected s2k_digest_algo: expected 1 got 2
|
||||
NOTICE: pgp_decrypt: unexpected use_sess_key: expected 1 got 0
|
||||
NOTICE: pgp_decrypt: unexpected disable_mdc: expected 1 got 0
|
||||
NOTICE: pgp_decrypt: unexpected compress_algo: expected 1 got 0
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
-- bytea as text
|
||||
select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz');
|
||||
ERROR: pgp_decrypt error: Not text data
|
||||
-- text as bytea
|
||||
select pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz');
|
||||
pgp_sym_decrypt_bytea
|
||||
-----------------------
|
||||
Text
|
||||
(1 row)
|
||||
|
||||
-- algorithm change
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=bf'),
|
||||
'key', 'expect-cipher-algo=bf');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes'),
|
||||
'key', 'expect-cipher-algo=aes128');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes192'),
|
||||
'key', 'expect-cipher-algo=aes192');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
-- s2k change
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 's2k-mode=0'),
|
||||
'key', 'expect-s2k-mode=0');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 's2k-mode=1'),
|
||||
'key', 'expect-s2k-mode=1');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 's2k-mode=3'),
|
||||
'key', 'expect-s2k-mode=3');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
-- s2k digest change
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
|
||||
'key', 'expect-s2k-digest-algo=md5');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=sha1'),
|
||||
'key', 'expect-s2k-digest-algo=sha1');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
-- sess key
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'sess-key=0'),
|
||||
'key', 'expect-sess-key=0');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'sess-key=1'),
|
||||
'key', 'expect-sess-key=1');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=bf'),
|
||||
'key', 'expect-sess-key=1, expect-cipher-algo=bf');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes192'),
|
||||
'key', 'expect-sess-key=1, expect-cipher-algo=aes192');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes256'),
|
||||
'key', 'expect-sess-key=1, expect-cipher-algo=aes256');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
-- no mdc
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'disable-mdc=1'),
|
||||
'key', 'expect-disable-mdc=1');
|
||||
pgp_sym_decrypt
|
||||
-----------------
|
||||
Secret.
|
||||
(1 row)
|
||||
|
||||
-- crlf
|
||||
select encode(pgp_sym_decrypt_bytea(
|
||||
pgp_sym_encrypt('1\n2\n3\r\n', 'key', 'convert-crlf=1'),
|
||||
'key'), 'hex');
|
||||
encode
|
||||
----------------------
|
||||
310d0a320d0a330d0d0a
|
||||
(1 row)
|
||||
|
||||
-- conversion should be lossless
|
||||
select encode(digest(pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('\r\n0\n1\r\r\n\n2\r', 'key', 'convert-crlf=1'),
|
||||
'key', 'convert-crlf=1'), 'sha1'), 'hex') as result,
|
||||
encode(digest('\r\n0\n1\r\r\n\n2\r', 'sha1'), 'hex') as expect;
|
||||
result | expect
|
||||
------------------------------------------+------------------------------------------
|
||||
47bde5d88d6ef8770572b9cbb4278b402aa69966 | 47bde5d88d6ef8770572b9cbb4278b402aa69966
|
||||
(1 row)
|
||||
|
65
contrib/pgcrypto/expected/pgp-info.out
Normal file
65
contrib/pgcrypto/expected/pgp-info.out
Normal file
@ -0,0 +1,65 @@
|
||||
--
|
||||
-- PGP info functions
|
||||
--
|
||||
-- pgp_key_id
|
||||
select pgp_key_id(dearmor(pubkey)) from keytbl where id=1;
|
||||
pgp_key_id
|
||||
------------------
|
||||
D936CF64BB73F466
|
||||
(1 row)
|
||||
|
||||
select pgp_key_id(dearmor(pubkey)) from keytbl where id=2;
|
||||
pgp_key_id
|
||||
------------------
|
||||
2C226E1FFE5CC7D4
|
||||
(1 row)
|
||||
|
||||
select pgp_key_id(dearmor(pubkey)) from keytbl where id=3;
|
||||
pgp_key_id
|
||||
------------------
|
||||
B68504FD128E1FF9
|
||||
(1 row)
|
||||
|
||||
select pgp_key_id(dearmor(pubkey)) from keytbl where id=4; -- should fail
|
||||
ERROR: No usable key found (expecting Elgamal key)
|
||||
select pgp_key_id(dearmor(pubkey)) from keytbl where id=5;
|
||||
pgp_key_id
|
||||
------------------
|
||||
D936CF64BB73F466
|
||||
(1 row)
|
||||
|
||||
select pgp_key_id(dearmor(seckey)) from keytbl where id=1;
|
||||
pgp_key_id
|
||||
------------------
|
||||
D936CF64BB73F466
|
||||
(1 row)
|
||||
|
||||
select pgp_key_id(dearmor(seckey)) from keytbl where id=2;
|
||||
pgp_key_id
|
||||
------------------
|
||||
2C226E1FFE5CC7D4
|
||||
(1 row)
|
||||
|
||||
select pgp_key_id(dearmor(seckey)) from keytbl where id=3;
|
||||
pgp_key_id
|
||||
------------------
|
||||
B68504FD128E1FF9
|
||||
(1 row)
|
||||
|
||||
select pgp_key_id(dearmor(seckey)) from keytbl where id=4; -- should fail
|
||||
ERROR: No usable key found (expecting Elgamal key)
|
||||
select pgp_key_id(dearmor(seckey)) from keytbl where id=5;
|
||||
pgp_key_id
|
||||
------------------
|
||||
D936CF64BB73F466
|
||||
(1 row)
|
||||
|
||||
select pgp_key_id(dearmor(data)) as data_key_id
|
||||
from encdata order by id;
|
||||
data_key_id
|
||||
------------------
|
||||
D936CF64BB73F466
|
||||
2C226E1FFE5CC7D4
|
||||
B68504FD128E1FF9
|
||||
(3 rows)
|
||||
|
1
contrib/pgcrypto/expected/pgp-pubkey-DISABLED.out
Normal file
1
contrib/pgcrypto/expected/pgp-pubkey-DISABLED.out
Normal file
@ -0,0 +1 @@
|
||||
-- no bignum support
|
441
contrib/pgcrypto/expected/pgp-pubkey-decrypt.out
Normal file
441
contrib/pgcrypto/expected/pgp-pubkey-decrypt.out
Normal file
@ -0,0 +1,441 @@
|
||||
--
|
||||
-- PGP Public Key Encryption
|
||||
--
|
||||
-- As most of the low-level stuff is tested in symmetric key
|
||||
-- tests, here's only public-key specific tests
|
||||
create table keytbl (
|
||||
id int4,
|
||||
name text,
|
||||
pubkey text,
|
||||
seckey text
|
||||
);
|
||||
create table encdata (
|
||||
id int4,
|
||||
data text
|
||||
);
|
||||
insert into keytbl (id, name, pubkey, seckey)
|
||||
values (1, 'elg1024', '
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
|
||||
tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
|
||||
xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
|
||||
klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
|
||||
YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
|
||||
PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
|
||||
jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
|
||||
saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
|
||||
IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx
|
||||
MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV
|
||||
AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc
|
||||
AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd
|
||||
ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P
|
||||
sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI
|
||||
+h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9
|
||||
6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF
|
||||
k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v
|
||||
iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F
|
||||
ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80
|
||||
=RWci
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
', '
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
lQG7BELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
|
||||
tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
|
||||
xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
|
||||
klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
|
||||
YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
|
||||
PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
|
||||
jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
|
||||
saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
|
||||
IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQAAAnj4i4st+s+C6
|
||||
WKTIDcL1Iy0Saq8lCp60H0VsZ2FtYWwgMTAyNCA8dGVzdEBleGFtcGxlLm9yZz6I
|
||||
XgQTEQIAHgUCQsghSAIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRAcKbwNGBdz
|
||||
ZDrbAJ9cp6AsjOhiLxwznsMJheGf4xkH8wCfUPjMCLm4tAEnyYn2hDNt7CB8B6Kd
|
||||
ATEEQsghShAEAIeUjW2yTALCfrEG3FhM3ZLvAHWAec2O0Mn/RDr59IN/W8wDYcZp
|
||||
m+oG0ZUDdIqMppQ8K2kylAH7gmYDXIP9D7MRRm/Zw3L4yFfKnVaZ6tT7szBbgW5h
|
||||
iOsHoOz49NXZT4jtMLdZS1/krm5Lam2MSPod9XN0Q2asY/igIMUfGDRjAAMGA/sE
|
||||
LNh3tWefqeDkoDBEYjcxdGnGVGJnNHvv/eoHy9H7dyD/kkhaOoRAa5ClYWSqD0kk
|
||||
a+SqTWhKG4XcbJyo1GsP6sqGhXDTM2+LBZPMKuVJQpEfoe9ruob/BbpXglfEiVE9
|
||||
VNiY7ZVyUdj3svYn4fK2X7ue1G3cHR2tL4lnOA4pYQAA9030E4u2ZKOfJBpUM+EM
|
||||
m9VmsGjaQZV4teB0R/q3W8sRIYhJBBgRAgAJBQJCyCFKAhsMAAoJEBwpvA0YF3Nk
|
||||
7a8AniFFotw1x2X+oryu3Q3nNtmxoKHpAJ9HU7jw7ydg33dI9J8gVkrmsSZ2/w==
|
||||
=nvqq
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
');
|
||||
insert into keytbl (id, name, pubkey, seckey)
|
||||
values (2, 'elg2048', '
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
mQGiBELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n
|
||||
vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke
|
||||
5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO
|
||||
RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij
|
||||
8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl
|
||||
Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt
|
||||
J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/
|
||||
T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5
|
||||
0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6a7QjRWxnYW1hbCAy
|
||||
MDQ4IDx0ZXN0MjA0OEBleGFtcGxlLm9yZz6IXgQTEQIAHgUCQsgiCgIbAwYLCQgH
|
||||
AwIDFQIDAxYCAQIeAQIXgAAKCRBI6c1W/qZo29PDAKCG724enIxRog1j+aeCp/uq
|
||||
or6mbwCePuKy2/1kD1FvnhkZ/R5fpm+pdm25Ag0EQsgiIhAIAJI3Gb2Ehtz1taQ9
|
||||
AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMX
|
||||
MhoWyw8ZF5Zs1mLIjFGVorePrm94N3MNPWM7x9M36bHUjx0vCZKFIhcGY1g+htE/
|
||||
QweaJzNVeA5z4qZmik41FbQyQSyHa3bOkTZu++/U6ghP+iDp5UDBjMTkVyqITUVN
|
||||
gC+MR+da/I60irBVhue7younh4ovF+CrVDQJC06HZl6CAJJyA81SmRfi+dmKbbjZ
|
||||
LF6rhz0norPjISJvkIqvdtM4VPBKI5wpgwCzpEqjuiKrAVujRT68zvBvJ4aVqb11
|
||||
k5QdJscAAwUH/jVJh0HbWAoiFTe+NvohfrA8vPcD0rtU3Y+siiqrabotnxJd2NuC
|
||||
bxghJYGfNtnx0KDjFbCRKJVeTFok4UnuVYhXdH/c6i0/rCTNdeW2D6pmR4GfBozR
|
||||
Pw/ARf+jONawGLyUj7uq13iquwMSE7VyNuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0R
|
||||
QsetMq/iNBWraayKZnWUd+eQqNzE+NUo7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiF
|
||||
Z1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qunfGW00ZMMTCWabg0ZgxPzMfMeIcm6525A
|
||||
Yn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/RdWaISQQYEQIACQUCQsgiIgIbDAAKCRBI
|
||||
6c1W/qZo25ZSAJ98WTrtl2HiX8ZqZq95v1+9cHtZPQCfZDoWQPybkNescLmXC7q5
|
||||
1kNTmEU=
|
||||
=8QM5
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
', '
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
lQG7BELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n
|
||||
vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke
|
||||
5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO
|
||||
RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij
|
||||
8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl
|
||||
Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt
|
||||
J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/
|
||||
T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5
|
||||
0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6awAAn2F+iNBElfJS
|
||||
8azqO/kEiIfpqu6/DQG0I0VsZ2FtYWwgMjA0OCA8dGVzdDIwNDhAZXhhbXBsZS5v
|
||||
cmc+iF0EExECAB4FAkLIIgoCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQSOnN
|
||||
Vv6maNvTwwCYkpcJmpl3aHCQdGomz7dFohDgjgCgiThZt2xTEi6GhBB1vuhk+f55
|
||||
n3+dAj0EQsgiIhAIAJI3Gb2Ehtz1taQ9AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D
|
||||
29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMXMhoWyw8ZF5Zs1mLIjFGVorePrm94N3MN
|
||||
PWM7x9M36bHUjx0vCZKFIhcGY1g+htE/QweaJzNVeA5z4qZmik41FbQyQSyHa3bO
|
||||
kTZu++/U6ghP+iDp5UDBjMTkVyqITUVNgC+MR+da/I60irBVhue7younh4ovF+Cr
|
||||
VDQJC06HZl6CAJJyA81SmRfi+dmKbbjZLF6rhz0norPjISJvkIqvdtM4VPBKI5wp
|
||||
gwCzpEqjuiKrAVujRT68zvBvJ4aVqb11k5QdJscAAwUH/jVJh0HbWAoiFTe+Nvoh
|
||||
frA8vPcD0rtU3Y+siiqrabotnxJd2NuCbxghJYGfNtnx0KDjFbCRKJVeTFok4Unu
|
||||
VYhXdH/c6i0/rCTNdeW2D6pmR4GfBozRPw/ARf+jONawGLyUj7uq13iquwMSE7Vy
|
||||
NuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0RQsetMq/iNBWraayKZnWUd+eQqNzE+NUo
|
||||
7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiFZ1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qun
|
||||
fGW00ZMMTCWabg0ZgxPzMfMeIcm6525AYn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/R
|
||||
dWYAAVQKFPXbRaxbdArwRVXMzSD3qj/+VwwhwEDt8zmBGnlBfwVdkjQQrDUMmV1S
|
||||
EwyISQQYEQIACQUCQsgiIgIbDAAKCRBI6c1W/qZo25ZSAJ4sgUfHTVsG/x3p3fcM
|
||||
3b5R86qKEACggYKSwPWCs0YVRHOWqZY0pnHtLH8=
|
||||
=3Dgk
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
');
|
||||
insert into keytbl (id, name, pubkey, seckey)
|
||||
values (3, 'elg4096', '
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
mQGiBELII7wRBACFuaAvb11cIvjJK9LkZr4cYuYhLWh3DJdojNNnLNiym5OEksvY
|
||||
05cw8OgqKtPzICU7o/mHXTWhzJYUt3i50/AeYygI8Q0uATS6RnDAKNlES1EMoHKz
|
||||
2a5iFbYs4bm4IwlkvYd8uWjcu+U0YLbxir39u+anIc6eT+q3WiH/q3zDRwCgkT98
|
||||
cnIG8iO8PdwDSP8G4Lt6TYED/R45GvCzJ4onQALLE92KkLUz8aFWSl05r84kczEN
|
||||
SxiP9Ss6m465RmwWHfwYAu4b+c4GeNyU8fIU2EM8cezchC+edEi3xu1s+pCV0Dk4
|
||||
18DGC8WKCICO30vBynuNmYg7W/7Zd4wtjss454fMW7+idVDNM701mmXBtI1nsBtG
|
||||
7Z4tA/9FxjFbJK9jh24RewfjHpLYqcfCo2SsUjOwsnMZ5yg2yv9KyVVQhRqwmrqt
|
||||
q8MRyjGmfoD9PPdCgvqgzy0hHvAHUtTm2zUczGTG+0g4hNIklxC/Mv6J4KE+NWTh
|
||||
uB4acqofHyaw2WnKOuRUsoDi6rG5AyjNMyAK/vVcEGj7J1tk27QjRWxnYW1hbCA0
|
||||
MDk2IDx0ZXN0NDA5NkBleGFtcGxlLm9yZz6IXgQTEQIAHgUCQsgjvAIbAwYLCQgH
|
||||
AwIDFQIDAxYCAQIeAQIXgAAKCRBj+HX2P2d0oAEDAJ9lI+CNmb42z3+a6TnVusM6
|
||||
FI7oLwCfUwA1zEcRdsT3nIkoYh0iKxFSDFW5BA0EQsgkdhAQAJQbLXlgcJ/jq+Xh
|
||||
Eujb77/eeftFJObNIRYD9fmJ7HFIXbUcknEpbs+cRH/nrj5dGSY3OT3jCXOUtvec
|
||||
sCoX/CpZWL0oqDjAiZtNSFiulw5Gav4gHYkWKgKdSo+2rkavEPqKIVHvMeXaJtGT
|
||||
d7v/AmL/P8T7gls93o5WFBOLtPbDvWqaKRy2U5TAhl1laiM0vGALRVjvSCgnGw9g
|
||||
FpSnXbO3AfenUSjDzZujfGLHtU44ixHSS/D4DepiF3YaYLsN4CBqZRv6FbMZD5W3
|
||||
DnJY4kS1kH0MzdcF19TlcZ3itTCcGIt1tMKf84mccPoqdMzH7vumBGTeFEly5Afp
|
||||
9berJcirqh2fzlunN0GS02z6SGWnjTbDlkNDxuxPSBbpcpNyD3jpYAUqSwRsZ/+5
|
||||
zkzcbGtDmvy9sJ5lAXkxGoIoQ1tEVX/LOHnh2NQHK8ourVOnr7MS0nozssITZJ5E
|
||||
XqtHiREjiYEuPyZiVZKJHLWuYYaF+n40znnz3sJuXFRreHhHbbvRdlYUU5mJV+XZ
|
||||
BLgKuS33NdpGeMIngnCc/9IQ6OZb6ixc94kbkd3w2PVr8CbKlu/IHTjWOO2mAo+D
|
||||
+OydlYl23FiM3KOyMP1HcEOJMB/nwkMtrvd+522Lu9n77ktKfot9IPrQDIQTyXjR
|
||||
3pCOFtCOBnk2tJHMPoG9jn9ah/LHAAMHEACDZ5I/MHGfmiKg2hrmqBu2J2j/deC8
|
||||
CpwcyDH1ovQ0gHvb9ESa+CVRU2Wdy2CD7Q9SmtMverB5eneL418iPVRcQdwRmQ2y
|
||||
IH4udlBa6ce9HTUCaecAZ4/tYBnaC0Av/9l9tz14eYcwRMDpB+bnkhgF+PZ1KAfD
|
||||
9wcY2aHbtsf3lZBc5h4owPJkxpe/BNzuJxW3q4VpSbLsZhwnCZ2wg7DRwP44wFIk
|
||||
00ptmoBY59gsU6I40XtzrF8JDr0cA57xND5RY21Z8lnnYRE1Tc8h5REps9ZIxW3/
|
||||
yl91404bPLqxczpUHQAMSTAmBaStPYX1nS51uofOhLs5SKPCUmxfGKIOhsD0oLUn
|
||||
78DnkONVGeXzBibSwwtbgfMzee4G8wSUfJ7w8WXz1TyanaGLnJ+DuKASSOrFoBCD
|
||||
HEDuWZWgSL74NOQupFRk0gxOPmqU94Y8HziQWma/cETbmD83q8rxN+GM2oBxQkQG
|
||||
xcbqMTHE7aVhV3tymbSWVaYhww3oIwsZS9oUIi1DnPEowS6CpVRrwdvLjLJnJzzV
|
||||
O3AFPn9eZ1Q7R1tNx+zZ4OOfhvI/OlRJ3HBx2L53embkbdY9gFYCCdTjPyjKoDIx
|
||||
kALgCajjCYMNUsAKNSd6mMCQ8TtvukSzkZS1RGKP27ohsdnzIVsiEAbxDMMcI4k1
|
||||
ul0LExUTCXSjeIhJBBgRAgAJBQJCyCR2AhsMAAoJEGP4dfY/Z3Sg19sAn0NDS8pb
|
||||
qrMpQAxSb7zRTmcXEFd9AJ435H0ttP/NhLHXC9ezgbCMmpXMOQ==
|
||||
=kRxT
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
', '
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
lQG7BELII7wRBACFuaAvb11cIvjJK9LkZr4cYuYhLWh3DJdojNNnLNiym5OEksvY
|
||||
05cw8OgqKtPzICU7o/mHXTWhzJYUt3i50/AeYygI8Q0uATS6RnDAKNlES1EMoHKz
|
||||
2a5iFbYs4bm4IwlkvYd8uWjcu+U0YLbxir39u+anIc6eT+q3WiH/q3zDRwCgkT98
|
||||
cnIG8iO8PdwDSP8G4Lt6TYED/R45GvCzJ4onQALLE92KkLUz8aFWSl05r84kczEN
|
||||
SxiP9Ss6m465RmwWHfwYAu4b+c4GeNyU8fIU2EM8cezchC+edEi3xu1s+pCV0Dk4
|
||||
18DGC8WKCICO30vBynuNmYg7W/7Zd4wtjss454fMW7+idVDNM701mmXBtI1nsBtG
|
||||
7Z4tA/9FxjFbJK9jh24RewfjHpLYqcfCo2SsUjOwsnMZ5yg2yv9KyVVQhRqwmrqt
|
||||
q8MRyjGmfoD9PPdCgvqgzy0hHvAHUtTm2zUczGTG+0g4hNIklxC/Mv6J4KE+NWTh
|
||||
uB4acqofHyaw2WnKOuRUsoDi6rG5AyjNMyAK/vVcEGj7J1tk2wAAoJCUNy6awTkw
|
||||
XfbLbpqh0fvDst7jDLa0I0VsZ2FtYWwgNDA5NiA8dGVzdDQwOTZAZXhhbXBsZS5v
|
||||
cmc+iF4EExECAB4FAkLII7wCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQY/h1
|
||||
9j9ndKABAwCeNEOVK87EzXYbtxYBsnjrUI948NIAn2+f3BXiBFDV5NvqPwIZ0m77
|
||||
Fwy4nQRMBELIJHYQEACUGy15YHCf46vl4RLo2++/3nn7RSTmzSEWA/X5iexxSF21
|
||||
HJJxKW7PnER/564+XRkmNzk94wlzlLb3nLAqF/wqWVi9KKg4wImbTUhYrpcORmr+
|
||||
IB2JFioCnUqPtq5GrxD6iiFR7zHl2ibRk3e7/wJi/z/E+4JbPd6OVhQTi7T2w71q
|
||||
mikctlOUwIZdZWojNLxgC0VY70goJxsPYBaUp12ztwH3p1Eow82bo3xix7VOOIsR
|
||||
0kvw+A3qYhd2GmC7DeAgamUb+hWzGQ+Vtw5yWOJEtZB9DM3XBdfU5XGd4rUwnBiL
|
||||
dbTCn/OJnHD6KnTMx+77pgRk3hRJcuQH6fW3qyXIq6odn85bpzdBktNs+khlp402
|
||||
w5ZDQ8bsT0gW6XKTcg946WAFKksEbGf/uc5M3GxrQ5r8vbCeZQF5MRqCKENbRFV/
|
||||
yzh54djUByvKLq1Tp6+zEtJ6M7LCE2SeRF6rR4kRI4mBLj8mYlWSiRy1rmGGhfp+
|
||||
NM55897CblxUa3h4R2270XZWFFOZiVfl2QS4Crkt9zXaRnjCJ4JwnP/SEOjmW+os
|
||||
XPeJG5Hd8Nj1a/AmypbvyB041jjtpgKPg/jsnZWJdtxYjNyjsjD9R3BDiTAf58JD
|
||||
La73fudti7vZ++5LSn6LfSD60AyEE8l40d6QjhbQjgZ5NrSRzD6BvY5/WofyxwAD
|
||||
BxAAg2eSPzBxn5oioNoa5qgbtido/3XgvAqcHMgx9aL0NIB72/REmvglUVNlnctg
|
||||
g+0PUprTL3qweXp3i+NfIj1UXEHcEZkNsiB+LnZQWunHvR01AmnnAGeP7WAZ2gtA
|
||||
L//Zfbc9eHmHMETA6Qfm55IYBfj2dSgHw/cHGNmh27bH95WQXOYeKMDyZMaXvwTc
|
||||
7icVt6uFaUmy7GYcJwmdsIOw0cD+OMBSJNNKbZqAWOfYLFOiONF7c6xfCQ69HAOe
|
||||
8TQ+UWNtWfJZ52ERNU3PIeURKbPWSMVt/8pfdeNOGzy6sXM6VB0ADEkwJgWkrT2F
|
||||
9Z0udbqHzoS7OUijwlJsXxiiDobA9KC1J+/A55DjVRnl8wYm0sMLW4HzM3nuBvME
|
||||
lHye8PFl89U8mp2hi5yfg7igEkjqxaAQgxxA7lmVoEi++DTkLqRUZNIMTj5qlPeG
|
||||
PB84kFpmv3BE25g/N6vK8TfhjNqAcUJEBsXG6jExxO2lYVd7cpm0llWmIcMN6CML
|
||||
GUvaFCItQ5zxKMEugqVUa8Hby4yyZyc81TtwBT5/XmdUO0dbTcfs2eDjn4byPzpU
|
||||
Sdxwcdi+d3pm5G3WPYBWAgnU4z8oyqAyMZAC4Amo4wmDDVLACjUnepjAkPE7b7pE
|
||||
s5GUtURij9u6IbHZ8yFbIhAG8QzDHCOJNbpdCxMVEwl0o3gAAckBdfKuasiNUn5G
|
||||
L5XRnSvaOFzftr8zteOlZChCSNvzH5k+i1j7RJbWq06OeKRywPzjfjgM2MvRzI43
|
||||
ICeISQQYEQIACQUCQsgkdgIbDAAKCRBj+HX2P2d0oNfbAJ9+G3SeXrk+dWwo9EGi
|
||||
hqMi2GVTsgCfeoQJPsc8FLYUgfymc/3xqAVLUtg=
|
||||
=Gjq6
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
');
|
||||
insert into keytbl (id, name, pubkey, seckey)
|
||||
values (4, 'rsa2048', '
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
mQELBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP
|
||||
ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2
|
||||
55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx
|
||||
5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K
|
||||
MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz
|
||||
R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYptB5SU0EgMjA0OCA8cnNhMjA0
|
||||
OEBleGFtcGxlLm9yZz6JATQEEwECAB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgEC
|
||||
HgECF4AACgkQnc+OnJvTHyQqHwf8DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liR
|
||||
nrLuVlLBpdO6CWmMUzfKRvyZlx54GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzw
|
||||
bLZyM5Gb3lsE/FEmE7Dxw/0Utf59uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDP
|
||||
D3dnU4uzKPhMcjnSN00pzjusP7C9NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv
|
||||
9bgGWopumlOkt8Zu5YG6+CtTbJXprPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhv
|
||||
S3NZKoJ/1DrGgoDAu1mGkM4KvLAxfDs/qQ9dZhtEmDbKPLTVEA==
|
||||
=lR4n
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
', '
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
lQOWBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP
|
||||
ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2
|
||||
55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx
|
||||
5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K
|
||||
MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz
|
||||
R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYpAAf/QZsrrz0c7dgWwGqMIpw6
|
||||
fP+/lLa74+fa2CFRWtYowEiKsfDg/wN7Ua07036dNhPa8aZPsU6SRzm5PybKOURe
|
||||
D9pNt0FxJkX0j5pCWfjSJgTbc1rCdqZ/oyBk/U6pQtf//zfw3PbDl7I8TC6GOt2w
|
||||
5NgcXdsWHP7LAmPctOVUyzFsenevR0MFTHkMbmKI1HpFm8XN/e1Fl+qIAD+OagTF
|
||||
5B32VvpoJtkh5nxnIuToNJsa9Iy7F9MM2CeFOyTMihMcjXKBBUaAYoF115irBvqu
|
||||
7N/qWmzqLg8yxBZ56mh6meCF3+67VA2y7fL8rhw2QuqgLg1JFlKAVL+9crCSrn//
|
||||
GQQA1kT7FytW6BNOffblFYZkrJer3icoRDqa/ljgH/yVaWoVT1igy0E9XzYO7MwP
|
||||
2usj/resLy0NC1qCthk51cZ/wthooMl88e5Wb4l5FYwBEac7muSBTo4W8cAH1hFj
|
||||
TWL6XAGvEzGX3Mt9pn8uYGlQLZAhJoNCAU2EOCbN1PchDvsEAOWNKYesuUVk8+sQ
|
||||
St0NDNhd9BWtTWTHkCZb1dKC3JTfr9PqkTBLrWFbYjkOtvdPAW7FDaXXXZfdH1jH
|
||||
WfwP3Q+I6sqgSaWpCS4dBAns3/RVtO7czVgyIwma04iIvJqderYrfvkUq95KfwP2
|
||||
V8wXkhrPPPxyrg5y3wQlpY2jb5RBBAC17SK1ms+DBtck4vpdjp3SJ32SbyC/DU30
|
||||
89Q12j74S7Zdu1qZlKnvy3kWPYX/hMuSzGZ+mLVJNFEqH2X01aFzppYz0hdI9PGB
|
||||
9tTFEqZWQL9ZkXfjc79Cgnt12pNukRbtw0N/kyutOdIFHVT79wVAd+powqziXJsC
|
||||
Kc+4xjwSCkZitB5SU0EgMjA0OCA8cnNhMjA0OEBleGFtcGxlLm9yZz6JATQEEwEC
|
||||
AB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQnc+OnJvTHyQqHwf8
|
||||
DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liRnrLuVlLBpdO6CWmMUzfKRvyZlx54
|
||||
GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzwbLZyM5Gb3lsE/FEmE7Dxw/0Utf59
|
||||
uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDPD3dnU4uzKPhMcjnSN00pzjusP7C9
|
||||
NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv9bgGWopumlOkt8Zu5YG6+CtTbJXp
|
||||
rPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhvS3NZKoJ/1DrGgoDAu1mGkM4KvLAx
|
||||
fDs/qQ9dZhtEmDbKPLTVEA==
|
||||
=WKAv
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
');
|
||||
insert into keytbl (id, name, pubkey, seckey)
|
||||
values (5, 'psw-elg1024', '
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
|
||||
tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
|
||||
xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
|
||||
klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
|
||||
YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
|
||||
PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
|
||||
jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
|
||||
saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
|
||||
IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx
|
||||
MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV
|
||||
AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc
|
||||
AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd
|
||||
ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P
|
||||
sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI
|
||||
+h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9
|
||||
6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF
|
||||
k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v
|
||||
iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F
|
||||
ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80
|
||||
=RWci
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
', '
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
lQHhBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
|
||||
tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
|
||||
xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
|
||||
klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
|
||||
YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
|
||||
PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
|
||||
jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
|
||||
saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
|
||||
IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQP4DAwL3TCgrYdj6
|
||||
+GAnoSqGa87twi8a6QRRYIlEx3ddUCDCjzkJmRfF+LFtvX3OtWWK0+Syi3kj2IK9
|
||||
YT7pF7QfRWxnYW1hbCAxMDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJC
|
||||
yCFIAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAn1ynoCyM
|
||||
6GIvHDOewwmF4Z/jGQfzAJ9Q+MwIubi0ASfJifaEM23sIHwHop0BVwRCyCFKEAQA
|
||||
h5SNbbJMAsJ+sQbcWEzdku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioym
|
||||
lDwraTKUAfuCZgNcg/0PsxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlP
|
||||
iO0wt1lLX+SubktqbYxI+h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSg
|
||||
MERiNzF0acZUYmc0e+/96gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxs
|
||||
nKjUaw/qyoaFcNMzb4sFk8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey
|
||||
9ifh8rZfu57UbdwdHa0viWc4Dilh/gMDAvdMKCth2Pr4YCCPsELdgJuzhGfDNRSg
|
||||
nKMRWBWHSJRk6JmCjM1iJQNHc4mMhR8gvi2TeqYLOhYjcF7nr/LA+JvLV+adj/mI
|
||||
SQQYEQIACQUCQsghSgIbDAAKCRAcKbwNGBdzZO2vAJ4hRaLcNcdl/qK8rt0N5zbZ
|
||||
saCh6QCfR1O48O8nYN93SPSfIFZK5rEmdv8=
|
||||
=Y6Qv
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
');
|
||||
-- elg1024 / aes128
|
||||
insert into encdata (id, data) values (1, '
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
hQEOA9k2z2S7c/RmEAQAgVWW0DeLrZ+1thWJGBPp2WRFL9HeNqqWHbKJCXJbz1Uy
|
||||
faUY7yxVvG5Eutmo+JMiY3mg23/DgVVXHQZsTWpGvGM6djgUNGKUjZDbW6Nog7Mr
|
||||
e78IywattCOmgUP9vIwwg3OVjuDCN/nVirGQFnXpJBc8DzWqDMWRWDy1M0ZsK7AD
|
||||
/2JTosSFxUdpON0DKtIY3GLzmh6Nk3iV0g8VgJKUBT1rhCXuMDj3snm//EMm7hTY
|
||||
PlnObq4mIhgz8NqprmhooxnU0Kapofb3P3wCHPpU14zxhXY8iKO/3JhBq2uFcx4X
|
||||
uBMwkW4AdNxY/mzJZELteTL8Tr0s7PISk+owb4URpG3n0jsBc0CVULxrjh5Ejkdw
|
||||
wCM195J6+KbQxOOFQ0b3uOVvv4dEgd/hRERCOq5EPaFhlHegyYJ7YO842vnSDA==
|
||||
=PABx
|
||||
-----END PGP MESSAGE-----
|
||||
');
|
||||
-- elg2048 / blowfish
|
||||
insert into encdata (id, data) values (2, '
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
hQIOAywibh/+XMfUEAf+OINhBngEsw4a/IJIeJvUgv1gTQzBwOdQEuc/runr4Oa8
|
||||
Skw/Bj0X/zgABVZLem1a35NHaNwaQaCFwMQ41YyWCu+jTdsiyX/Nw0w8LKKz0rNC
|
||||
vVpG6YuV7Turtsf8a5lXy1K0SHkLlgxQ6c76GS4gtSl5+bsL2+5R1gSRJ9NXqCQP
|
||||
OHRipEiYwBPqr5R21ZG0FXXNKGOGkj6jt/M/wh3WVtAhYuBI+HPKRfAEjd/Pu/eD
|
||||
e1zYtkH1dKKFmp44+nF0tTI274xpuso7ShfKYrOK3saFWrl0DWiWteUinjSA1YBY
|
||||
m7dG7NZ8PW+g1SZWhEoPjEEEHz3kWMvlKheMRDudnQf/dDyX6kZVIAQF/5B012hq
|
||||
QyVewgTGysowFIDn01uIewoEA9cASw699jw9IoJp+k5WZXnU+INllBLzQxniQCSu
|
||||
iEcr0x3fYqNtj9QBfbIqyRcY6HTWcmzyOUeGaSyX76j+tRAvtVtXpraFFFnaHB70
|
||||
YpXTjLkp8EBafzMghFaKDeXlr2TG/T7rbwcwWrFIwPqEAUKWN5m97Q3eyo8/ioMd
|
||||
YoFD64J9ovSsgbuU5IpIGAsjxK+NKzg/2STH7zZFEVCtgcIXsTHTZfiwS98/+1H9
|
||||
p1DIDaXIcUFV2ztmcKxh9gt2sXRz1W+x6D8O0k3nanU5yGG4miLKaq18fbcA0BD1
|
||||
+NIzAfelq6nvvxYKcGcamBMgLo5JkZOBHvyr6RsAKIT5QYc0QTjysTk9l0Am3gYc
|
||||
G2pAE+3k
|
||||
=TBHV
|
||||
-----END PGP MESSAGE-----
|
||||
');
|
||||
-- elg4096 / aes256
|
||||
insert into encdata (id, data) values (3, '
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
hQQOA7aFBP0Sjh/5EA/+JCgncc8IZmmRjPStWnGf9tVJhgHTn+smIclibGzs0deS
|
||||
SPSCitzpblwbUDvu964+/5e5Q1l7rRuNN+AgETlEd4eppv7Swn2ChdgOXxRwukcT
|
||||
Nh3G+PTFvD4ayi7w1db3qvXIt0MwN4Alt436wJmK1oz2Ka9IcyO+wHWrDy1nSGSx
|
||||
z5x7YEj+EZPgWc/YAvudqE8Jpzd/OT5zSHN09UFkIAk6NxisKaIstbEGFgpqtoDZ
|
||||
1SJM84XAdL2IcaJ3YY7k/yzwlawhsakKd4GSd5vWmAwvyzzbSiBMfKsDE16ePLNU
|
||||
ZBF7CzmlCBPZ7YrFAHLpXBXXkCQvzD2BEYOjse50ZEfJ036T7950Ozcdy1EQbGon
|
||||
nyQ4Gh0PBpnMcBuiXOceWuYzhlzFOzDtlVKdNTxFRDcbEyW2jo9xQYvCCLnYy8EH
|
||||
2M7S8jCtVYJBbn63a82ELv+3+kWYcsvBJv2ZVBh4ncrBu9o0P+OYS7ApoOU+j6p2
|
||||
+t0RXHksqXS1YiUwYF5KSw09EbYMgNZ9G04Px/PxLU6fSC9iDrGX7Xt3kOUP0mku
|
||||
C518fPckT0zzRXqfFruJNRzDytW50KxkOQZzU1/Az1YlYN9QzWeU4EtLPb2fftZo
|
||||
D0qH/ln+f9Op5t6sD2fcxZVECU1b/bFtZsxvwH406YL+UQ7hU/XnZrzVVzODal8P
|
||||
/j1hg7v7BdJqu1DTp9nFWUuwMFcYAczuXn29IG183NZ7Ts4whDeYEhS8eNoLPX4j
|
||||
txY12ILD/w/3Q4LoW/hPa6OdfEzsn0U5GLf1WiGmJE1H6ft2U/xUnerc/u0kt+FU
|
||||
WAisArd4MuKtf7B5Vu/VF3kUdrR0hTniUKUivmC4o1jSId31Dufxj4aadVyldXAr
|
||||
6TNBcdyragZjxEZ6hsBCYzA0Rd1a8atd6OaQoIEEfAzCu5Ks29pydHErStYGjWJ1
|
||||
KA5KPLVvjbHpDmRhlCcm8vgpYQsBYEB5gE9fx5yCTlsVhCB6y23h7hfdMqerDqkO
|
||||
ZOPsO5h+tiHCdIrQ36sMjuINy1/K2rYcXd+Crh2iHcfidpU9fvDz2ihTRNQlhjuT
|
||||
0cQZM5JhctEx4VXF4LDctRhit7Hn0iqsk604woQfJVvP8O673xSXT/kBY0A/v9C0
|
||||
3C4YoFNeSaKwbfZQ/4u1ZFPJxK2IIJa8UGpyAUewLMlzGVVagljybv/f4Z9ERAhy
|
||||
huq5sMmw8UPsrJF2TUGHz5WSIwoh0J/qovoQI09I9sdEnFczDvRavMO2Mldy3E5i
|
||||
exz9oewtel6GOmsZQSYWT/vJzbYMmvHNmNpVwwoKrLV6oI3kyQ80GHBwI1WlwHoK
|
||||
2iRB0w8q4VVvJeYAz8ZIp380cqC3pfO0uZsrOx4g3k4X0jsB5y7rF5xXcZfnVbvG
|
||||
DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglTVTfYmi1ToZDDipkALBhndQ==
|
||||
=L/M/
|
||||
-----END PGP MESSAGE-----
|
||||
');
|
||||
-- successful decrypt
|
||||
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
|
||||
from keytbl, encdata where keytbl.id=1 and encdata.id=1;
|
||||
pgp_pub_decrypt
|
||||
-----------------
|
||||
Secret msg
|
||||
(1 row)
|
||||
|
||||
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
|
||||
from keytbl, encdata where keytbl.id=2 and encdata.id=2;
|
||||
pgp_pub_decrypt
|
||||
-----------------
|
||||
Secret msg
|
||||
(1 row)
|
||||
|
||||
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
|
||||
from keytbl, encdata where keytbl.id=3 and encdata.id=3;
|
||||
pgp_pub_decrypt
|
||||
-----------------
|
||||
Secret msg
|
||||
(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
|
||||
-- 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)
|
||||
-- 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
|
||||
-- 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
|
||||
-- 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;
|
||||
pgp_pub_decrypt
|
||||
-----------------
|
||||
Secret msg
|
||||
(1 row)
|
||||
|
59
contrib/pgcrypto/expected/pgp-pubkey-encrypt.out
Normal file
59
contrib/pgcrypto/expected/pgp-pubkey-encrypt.out
Normal file
@ -0,0 +1,59 @@
|
||||
--
|
||||
-- PGP Public Key Encryption
|
||||
--
|
||||
-- successful encrypt/decrypt
|
||||
select pgp_pub_decrypt(
|
||||
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
|
||||
dearmor(seckey))
|
||||
from keytbl where keytbl.id=1;
|
||||
pgp_pub_decrypt
|
||||
-----------------
|
||||
Secret msg
|
||||
(1 row)
|
||||
|
||||
select pgp_pub_decrypt(
|
||||
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
|
||||
dearmor(seckey))
|
||||
from keytbl where keytbl.id=2;
|
||||
pgp_pub_decrypt
|
||||
-----------------
|
||||
Secret msg
|
||||
(1 row)
|
||||
|
||||
select pgp_pub_decrypt(
|
||||
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
|
||||
dearmor(seckey))
|
||||
from keytbl where keytbl.id=3;
|
||||
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)
|
||||
-- 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
|
||||
-- does text-to-bytea works
|
||||
select pgp_pub_decrypt_bytea(
|
||||
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
|
||||
dearmor(seckey))
|
||||
from keytbl where keytbl.id=1;
|
||||
pgp_pub_decrypt_bytea
|
||||
-----------------------
|
||||
Secret msg
|
||||
(1 row)
|
||||
|
||||
-- and bytea-to-text?
|
||||
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
|
1
contrib/pgcrypto/expected/pgp-zlib-DISABLED.out
Normal file
1
contrib/pgcrypto/expected/pgp-zlib-DISABLED.out
Normal file
@ -0,0 +1 @@
|
||||
-- zlib is disabled
|
108
contrib/pgcrypto/expected/sha2.out
Normal file
108
contrib/pgcrypto/expected/sha2.out
Normal file
@ -0,0 +1,108 @@
|
||||
--
|
||||
-- SHA2 family
|
||||
--
|
||||
-- SHA256
|
||||
SELECT encode(digest('', 'sha256'), 'hex');
|
||||
encode
|
||||
------------------------------------------------------------------
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('a', 'sha256'), 'hex');
|
||||
encode
|
||||
------------------------------------------------------------------
|
||||
ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('abc', 'sha256'), 'hex');
|
||||
encode
|
||||
------------------------------------------------------------------
|
||||
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha256'), 'hex');
|
||||
encode
|
||||
------------------------------------------------------------------
|
||||
248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha256'), 'hex');
|
||||
encode
|
||||
------------------------------------------------------------------
|
||||
f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e
|
||||
(1 row)
|
||||
|
||||
-- SHA384
|
||||
SELECT encode(digest('', 'sha384'), 'hex');
|
||||
encode
|
||||
--------------------------------------------------------------------------------------------------
|
||||
38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('a', 'sha384'), 'hex');
|
||||
encode
|
||||
--------------------------------------------------------------------------------------------------
|
||||
54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('abc', 'sha384'), 'hex');
|
||||
encode
|
||||
--------------------------------------------------------------------------------------------------
|
||||
cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha384'), 'hex');
|
||||
encode
|
||||
--------------------------------------------------------------------------------------------------
|
||||
3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu', 'sha384'), 'hex');
|
||||
encode
|
||||
--------------------------------------------------------------------------------------------------
|
||||
09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz', 'sha384'), 'hex');
|
||||
encode
|
||||
--------------------------------------------------------------------------------------------------
|
||||
3d208973ab3508dbbd7e2c2862ba290ad3010e4978c198dc4d8fd014e582823a89e16f9b2a7bbc1ac938e2d199e8bea4
|
||||
(1 row)
|
||||
|
||||
-- SHA512
|
||||
SELECT encode(digest('', 'sha512'), 'hex');
|
||||
encode
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('a', 'sha512'), 'hex');
|
||||
encode
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('abc', 'sha512'), 'hex');
|
||||
encode
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha512'), 'hex');
|
||||
encode
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu', 'sha512'), 'hex');
|
||||
encode
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909
|
||||
(1 row)
|
||||
|
||||
SELECT encode(digest('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz', 'sha512'), 'hex');
|
||||
encode
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
930d0cefcb30ff1133b6898121f1cf3d27578afcafe8677c5257cf069911f75d8f5831b56ebfda67b278e66dff8b84fe2b2870f742a580d8edb41987232850c9
|
||||
(1 row)
|
||||
|
365
contrib/pgcrypto/fortuna.c
Normal file
365
contrib/pgcrypto/fortuna.c
Normal file
@ -0,0 +1,365 @@
|
||||
/*
|
||||
* fortuna.c
|
||||
* Fortuna-like PRNG.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.1 2005/07/10 13:46:27 momjian Exp $
|
||||
*/
|
||||
|
||||
#include <postgres.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "rijndael.h"
|
||||
#include "sha2.h"
|
||||
|
||||
#include "fortuna.h"
|
||||
|
||||
|
||||
/*
|
||||
* Why Fortuna-like: There does not seem to be any definitive reference
|
||||
* on Fortuna in the net. Instead this implementation is based on
|
||||
* following references:
|
||||
*
|
||||
* http://en.wikipedia.org/wiki/Fortuna_(PRNG)
|
||||
* - Wikipedia article
|
||||
* http://jlcooke.ca/random/
|
||||
* - Jean-Luc Cooke Fortuna-based /dev/random driver for Linux.
|
||||
*/
|
||||
|
||||
/*
|
||||
* There is some confusion about whether and how to carry forward
|
||||
* the state of the pools. Seems like original Fortuna does not
|
||||
* do it, resetting hash after each request. I guess expecting
|
||||
* feeding to happen more often that requesting. This is absolutely
|
||||
* unsuitable for pgcrypto, as nothing asynchronous happens here.
|
||||
*
|
||||
* J.L. Cooke fixed this by feeding previous hash to new re-initialized
|
||||
* hash context.
|
||||
*
|
||||
* Fortuna predecessor Yarrow requires ability to query intermediate
|
||||
* 'final result' from hash, without affecting it.
|
||||
*
|
||||
* This implementation uses the Yarrow method - asking intermediate
|
||||
* results, but continuing with old state.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Algorithm parameters
|
||||
*/
|
||||
|
||||
/*
|
||||
* How many pools.
|
||||
*
|
||||
* Original Fortuna uses 32 pools, that means 32'th pool is
|
||||
* used not earlier than in 13th year. This is a waste in
|
||||
* pgcrypto, as we have very low-frequancy seeding. Here
|
||||
* is preferable to have all entropy usable in reasonable time.
|
||||
*
|
||||
* With 23 pools, 23th pool is used after 9 days which seems
|
||||
* more sane.
|
||||
*
|
||||
* In our case the minimal cycle time would be bit longer
|
||||
* than the system-randomness feeding frequency.
|
||||
*/
|
||||
#define NUM_POOLS 23
|
||||
|
||||
/* in microseconds */
|
||||
#define RESEED_INTERVAL 100000 /* 0.1 sec */
|
||||
|
||||
/* for one big request, reseed after this many bytes */
|
||||
#define RESEED_BYTES (1024*1024)
|
||||
|
||||
|
||||
/*
|
||||
* Algorithm constants
|
||||
*/
|
||||
|
||||
/* max sources */
|
||||
#define MAX_SOURCES 8
|
||||
|
||||
/* Both cipher key size and hash result size */
|
||||
#define BLOCK 32
|
||||
|
||||
/* cipher block size */
|
||||
#define CIPH_BLOCK 16
|
||||
|
||||
/* for internal wrappers */
|
||||
#define MD_CTX SHA256_CTX
|
||||
#define CIPH_CTX rijndael_ctx
|
||||
|
||||
struct fortuna_state {
|
||||
uint8 counter[CIPH_BLOCK];
|
||||
uint8 result[CIPH_BLOCK];
|
||||
uint8 key[BLOCK];
|
||||
MD_CTX pool[NUM_POOLS];
|
||||
CIPH_CTX ciph;
|
||||
unsigned source_pos[MAX_SOURCES];
|
||||
unsigned reseed_count;
|
||||
struct timeval last_reseed_time;
|
||||
};
|
||||
typedef struct fortuna_state FState;
|
||||
|
||||
|
||||
/*
|
||||
* Use our own wrappers here.
|
||||
* - Need to get intermediate result from digest, without affecting it.
|
||||
* - Need re-set key on a cipher context.
|
||||
* - Algorithms are guaranteed to exist.
|
||||
* - No memory allocations.
|
||||
*/
|
||||
|
||||
static void ciph_init(CIPH_CTX *ctx, const uint8 *key, int klen)
|
||||
{
|
||||
rijndael_set_key(ctx, (const uint32 *)key, klen, 1);
|
||||
}
|
||||
|
||||
static void ciph_encrypt(CIPH_CTX *ctx, const uint8 *in, uint8 *out)
|
||||
{
|
||||
rijndael_encrypt(ctx, (const uint32 *)in, (uint32 *)out);
|
||||
}
|
||||
|
||||
static void md_init(MD_CTX *ctx)
|
||||
{
|
||||
SHA256_Init(ctx);
|
||||
}
|
||||
|
||||
static void md_update(MD_CTX *ctx, const uint8 *data, int len)
|
||||
{
|
||||
SHA256_Update(ctx, data, len);
|
||||
}
|
||||
|
||||
static void md_result(MD_CTX *ctx, uint8 *dst)
|
||||
{
|
||||
SHA256_CTX tmp;
|
||||
memcpy(&tmp, ctx, sizeof(*ctx));
|
||||
SHA256_Final(dst, &tmp);
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* initialize state
|
||||
*/
|
||||
static void init_state(FState *st)
|
||||
{
|
||||
int i;
|
||||
memset(st, 0, sizeof(*st));
|
||||
for (i = 0; i < NUM_POOLS; i++)
|
||||
md_init(&st->pool[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Must not reseed more ofter than RESEED_PER_SEC
|
||||
* times per second.
|
||||
*/
|
||||
static int too_often(FState *st)
|
||||
{
|
||||
int ok;
|
||||
struct timeval tv;
|
||||
struct timeval *last = &st->last_reseed_time;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
ok = 0;
|
||||
if (tv.tv_sec != last->tv_sec)
|
||||
ok = 1;
|
||||
else if (tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
|
||||
ok = 1;
|
||||
|
||||
memcpy(last, &tv, sizeof(tv));
|
||||
memset(&tv, 0, sizeof(tv));
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* generate new key from all the pools
|
||||
*/
|
||||
static void reseed(FState *st)
|
||||
{
|
||||
unsigned k;
|
||||
unsigned n;
|
||||
MD_CTX key_md;
|
||||
uint8 buf[BLOCK];
|
||||
|
||||
/* check frequency */
|
||||
if (too_often(st))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Both #0 and #1 reseed would use only pool 0.
|
||||
* Just skip #0 then.
|
||||
*/
|
||||
n = ++st->reseed_count;
|
||||
|
||||
/*
|
||||
* The goal: use k-th pool only 1/(2^k) of the time.
|
||||
*/
|
||||
md_init(&key_md);
|
||||
for (k = 0; k < NUM_POOLS; k++) {
|
||||
md_result(&st->pool[k], buf);
|
||||
md_update(&key_md, buf, BLOCK);
|
||||
|
||||
if (n & 1 || !n)
|
||||
break;
|
||||
n >>= 1;
|
||||
}
|
||||
|
||||
/* add old key into mix too */
|
||||
md_update(&key_md, st->key, BLOCK);
|
||||
|
||||
/* now we have new key */
|
||||
md_result(&key_md, st->key);
|
||||
|
||||
/* use new key */
|
||||
ciph_init(&st->ciph, st->key, BLOCK);
|
||||
|
||||
memset(&key_md, 0, sizeof(key_md));
|
||||
memset(buf, 0, BLOCK);
|
||||
n = k = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* update pools
|
||||
*/
|
||||
static void add_entropy(FState *st, unsigned src_id, const uint8 *data, unsigned len)
|
||||
{
|
||||
unsigned pos;
|
||||
uint8 hash[BLOCK];
|
||||
MD_CTX md;
|
||||
|
||||
/* just in case there's a bug somewhere */
|
||||
if (src_id >= MAX_SOURCES)
|
||||
src_id = USER_ENTROPY;
|
||||
|
||||
/* hash given data */
|
||||
md_init(&md);
|
||||
md_update(&md, data, len);
|
||||
md_result(&md, hash);
|
||||
|
||||
/* update pools round-robin manner */
|
||||
pos = st->source_pos[src_id];
|
||||
md_update( &st->pool[pos], hash, BLOCK);
|
||||
|
||||
if (++pos >= NUM_POOLS)
|
||||
pos = 0;
|
||||
st->source_pos[src_id] = pos;
|
||||
|
||||
memset(hash, 0, BLOCK);
|
||||
memset(&md, 0, sizeof(md));
|
||||
}
|
||||
|
||||
/*
|
||||
* Endianess does not matter.
|
||||
* It just needs to change without repeating.
|
||||
*/
|
||||
static void inc_counter(FState *st)
|
||||
{
|
||||
uint32 *val = (uint32*)st->counter;
|
||||
if (++val[0])
|
||||
return;
|
||||
if (++val[1])
|
||||
return;
|
||||
if (++val[2])
|
||||
return;
|
||||
++val[3];
|
||||
}
|
||||
|
||||
static void extract_data(FState *st, unsigned count, uint8 *dst)
|
||||
{
|
||||
unsigned n;
|
||||
unsigned block_nr = 0;
|
||||
|
||||
/*
|
||||
* Every request should be with different key,
|
||||
* if possible.
|
||||
*/
|
||||
reseed(st);
|
||||
|
||||
/*
|
||||
* If the reseed didn't happen, don't use the old data
|
||||
* rather encrypt again.
|
||||
*/
|
||||
|
||||
while (count > 0) {
|
||||
/* must not give out too many bytes with one key */
|
||||
if (block_nr > (RESEED_BYTES / CIPH_BLOCK))
|
||||
{
|
||||
reseed(st);
|
||||
block_nr = 0;
|
||||
}
|
||||
|
||||
/* produce bytes */
|
||||
ciph_encrypt(&st->ciph, st->counter, st->result);
|
||||
block_nr++;
|
||||
|
||||
/* prepare for next time */
|
||||
inc_counter(st);
|
||||
|
||||
/* copy result */
|
||||
if (count > CIPH_BLOCK)
|
||||
n = CIPH_BLOCK;
|
||||
else
|
||||
n = count;
|
||||
memcpy(dst, st->result, n);
|
||||
dst += n;
|
||||
count -= n;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* public interface
|
||||
*/
|
||||
|
||||
static FState main_state;
|
||||
static int init_done = 0;
|
||||
|
||||
void fortuna_add_entropy(unsigned src_id, const uint8 *data, unsigned len)
|
||||
{
|
||||
if (!init_done)
|
||||
{
|
||||
init_state(&main_state);
|
||||
init_done = 1;
|
||||
}
|
||||
if (!data || !len)
|
||||
return;
|
||||
add_entropy(&main_state, src_id, data, len);
|
||||
}
|
||||
|
||||
void fortuna_get_bytes(unsigned len, uint8 *dst)
|
||||
{
|
||||
if (!init_done)
|
||||
{
|
||||
init_state(&main_state);
|
||||
init_done = 1;
|
||||
}
|
||||
if (!dst || !len)
|
||||
return;
|
||||
extract_data(&main_state, len, dst);
|
||||
}
|
||||
|
45
contrib/pgcrypto/fortuna.h
Normal file
45
contrib/pgcrypto/fortuna.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* fortuna.c
|
||||
* Fortuna PRNG.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.h,v 1.1 2005/07/10 13:46:28 momjian Exp $
|
||||
*/
|
||||
|
||||
#ifndef __FORTUNA_H
|
||||
#define __FORTUNA_H
|
||||
|
||||
/*
|
||||
* Event source ID's
|
||||
*/
|
||||
#define SYSTEM_ENTROPY 0
|
||||
#define USER_ENTROPY 1
|
||||
|
||||
void fortuna_get_bytes(unsigned len, uint8 *dst);
|
||||
void fortuna_add_entropy(unsigned src_id, const uint8 *data, unsigned len);
|
||||
|
||||
#endif
|
||||
|
556
contrib/pgcrypto/mbuf.c
Normal file
556
contrib/pgcrypto/mbuf.c
Normal file
@ -0,0 +1,556 @@
|
||||
/*
|
||||
* mbuf.c
|
||||
* Memory buffer operations.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/mbuf.c,v 1.1 2005/07/10 13:46:28 momjian Exp $
|
||||
*/
|
||||
|
||||
#include <postgres.h>
|
||||
|
||||
#include "px.h"
|
||||
#include "mbuf.h"
|
||||
|
||||
#define STEP (16*1024)
|
||||
|
||||
struct MBuf
|
||||
{
|
||||
uint8 *data;
|
||||
uint8 *data_end;
|
||||
uint8 *read_pos;
|
||||
uint8 *buf_end;
|
||||
int no_write:1;
|
||||
int own_data:1;
|
||||
};
|
||||
|
||||
int
|
||||
mbuf_avail(MBuf * mbuf)
|
||||
{
|
||||
return mbuf->data_end - mbuf->read_pos;
|
||||
}
|
||||
|
||||
int
|
||||
mbuf_size(MBuf * mbuf)
|
||||
{
|
||||
return mbuf->data_end - mbuf->data;
|
||||
}
|
||||
|
||||
int
|
||||
mbuf_tell(MBuf * mbuf)
|
||||
{
|
||||
return mbuf->read_pos - mbuf->data;
|
||||
}
|
||||
|
||||
int
|
||||
mbuf_free(MBuf * mbuf)
|
||||
{
|
||||
if (mbuf->own_data)
|
||||
{
|
||||
memset(mbuf->data, 0, mbuf->buf_end - mbuf->data);
|
||||
px_free(mbuf->data);
|
||||
}
|
||||
px_free(mbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_room(MBuf * mbuf, int block_len)
|
||||
{
|
||||
uint8 *newbuf;
|
||||
unsigned newlen;
|
||||
|
||||
if (mbuf->data_end + block_len <= mbuf->buf_end)
|
||||
return;
|
||||
|
||||
newlen = (mbuf->buf_end - mbuf->data)
|
||||
+ ((block_len + STEP + STEP - 1) & -STEP);
|
||||
|
||||
newbuf = px_realloc(mbuf->data, newlen);
|
||||
|
||||
mbuf->buf_end = newbuf + newlen;
|
||||
mbuf->data_end = newbuf + (mbuf->data_end - mbuf->data);
|
||||
mbuf->read_pos = newbuf + (mbuf->read_pos - mbuf->data);
|
||||
mbuf->data = newbuf;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
mbuf_append(MBuf * dst, const uint8 *buf, int len)
|
||||
{
|
||||
if (dst->no_write)
|
||||
{
|
||||
px_debug("mbuf_append: no_write");
|
||||
return PXE_BUG;
|
||||
}
|
||||
|
||||
prepare_room(dst, len);
|
||||
|
||||
memcpy(dst->data_end, buf, len);
|
||||
dst->data_end += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MBuf *
|
||||
mbuf_create(int len)
|
||||
{
|
||||
MBuf *mbuf;
|
||||
|
||||
if (!len)
|
||||
len = 8192;
|
||||
|
||||
mbuf = px_alloc(sizeof *mbuf);
|
||||
mbuf->data = px_alloc(len);
|
||||
mbuf->buf_end = mbuf->data + len;
|
||||
mbuf->data_end = mbuf->data;
|
||||
mbuf->read_pos = mbuf->data;
|
||||
|
||||
mbuf->no_write = 0;
|
||||
mbuf->own_data = 1;
|
||||
|
||||
return mbuf;
|
||||
}
|
||||
|
||||
MBuf *
|
||||
mbuf_create_from_data(const uint8 *data, int len)
|
||||
{
|
||||
MBuf *mbuf;
|
||||
|
||||
mbuf = px_alloc(sizeof *mbuf);
|
||||
mbuf->data = (uint8 *) data;
|
||||
mbuf->buf_end = mbuf->data + len;
|
||||
mbuf->data_end = mbuf->data + len;
|
||||
mbuf->read_pos = mbuf->data;
|
||||
|
||||
mbuf->no_write = 1;
|
||||
mbuf->own_data = 0;
|
||||
|
||||
return mbuf;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mbuf_grab(MBuf * mbuf, int len, uint8 **data_p)
|
||||
{
|
||||
if (len > mbuf_avail(mbuf))
|
||||
len = mbuf_avail(mbuf);
|
||||
|
||||
mbuf->no_write = 1;
|
||||
|
||||
*data_p = mbuf->read_pos;
|
||||
mbuf->read_pos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
int mbuf_rewind(MBuf *mbuf)
|
||||
{
|
||||
mbuf->read_pos = mbuf->data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mbuf_steal_data(MBuf * mbuf, uint8 **data_p)
|
||||
{
|
||||
int len = mbuf_size(mbuf);
|
||||
|
||||
mbuf->no_write = 1;
|
||||
mbuf->own_data = 0;
|
||||
|
||||
*data_p = mbuf->data;
|
||||
|
||||
mbuf->data = mbuf->data_end = mbuf->read_pos = mbuf->buf_end = NULL;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* PullFilter
|
||||
*/
|
||||
|
||||
struct PullFilter
|
||||
{
|
||||
PullFilter *src;
|
||||
const PullFilterOps *op;
|
||||
int buflen;
|
||||
uint8 *buf;
|
||||
int pos;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
int
|
||||
pullf_create(PullFilter ** pf_p, const PullFilterOps * op, void *init_arg, PullFilter * src)
|
||||
{
|
||||
PullFilter *pf;
|
||||
void *priv;
|
||||
int res;
|
||||
|
||||
if (op->init != NULL)
|
||||
{
|
||||
res = op->init(&priv, init_arg, src);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv = init_arg;
|
||||
res = 0;
|
||||
}
|
||||
|
||||
pf = px_alloc(sizeof(*pf));
|
||||
memset(pf, 0, sizeof(*pf));
|
||||
pf->buflen = res;
|
||||
pf->op = op;
|
||||
pf->priv = priv;
|
||||
pf->src = src;
|
||||
if (pf->buflen > 0)
|
||||
{
|
||||
pf->buf = px_alloc(pf->buflen);
|
||||
pf->pos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pf->buf = NULL;
|
||||
pf->pos = 0;
|
||||
}
|
||||
*pf_p = pf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pullf_free(PullFilter * pf)
|
||||
{
|
||||
if (pf->op->free)
|
||||
pf->op->free(pf->priv);
|
||||
|
||||
if (pf->buf)
|
||||
{
|
||||
memset(pf->buf, 0, pf->buflen);
|
||||
px_free(pf->buf);
|
||||
}
|
||||
|
||||
memset(pf, 0, sizeof(*pf));
|
||||
px_free(pf);
|
||||
}
|
||||
|
||||
/* may return less data than asked, 0 means eof */
|
||||
int
|
||||
pullf_read(PullFilter * pf, int len, uint8 **data_p)
|
||||
{
|
||||
int res;
|
||||
if (pf->op->pull)
|
||||
{
|
||||
if (pf->buflen && len > pf->buflen)
|
||||
len = pf->buflen;
|
||||
res = pf->op->pull(pf->priv, pf->src, len, data_p,
|
||||
pf->buf, pf->buflen);
|
||||
}
|
||||
else
|
||||
res = pullf_read(pf->src, len, data_p);
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
pullf_read_max(PullFilter * pf, int len, uint8 **data_p, uint8 *tmpbuf)
|
||||
{
|
||||
int res, total;
|
||||
uint8 *tmp;
|
||||
|
||||
res = pullf_read(pf, len, data_p);
|
||||
if (res <= 0 || res == len)
|
||||
return res;
|
||||
|
||||
/* read was shorter, use tmpbuf */
|
||||
memcpy(tmpbuf, *data_p, res);
|
||||
*data_p = tmpbuf;
|
||||
len -= res;
|
||||
total = res;
|
||||
|
||||
while (len > 0) {
|
||||
res = pullf_read(pf, len, &tmp);
|
||||
if (res < 0)
|
||||
{
|
||||
/* so the caller must clear only on success */
|
||||
memset(tmpbuf, 0, total);
|
||||
return res;
|
||||
}
|
||||
if (res == 0)
|
||||
break;
|
||||
memcpy(tmpbuf + total, tmp, res);
|
||||
total += res;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/*
|
||||
* caller wants exatly len bytes and dont bother with references
|
||||
*/
|
||||
int pullf_read_fixed(PullFilter *src, int len, uint8 *dst)
|
||||
{
|
||||
int res;
|
||||
uint8 *p;
|
||||
res = pullf_read_max(src, len, &p, dst);
|
||||
if (res < 0)
|
||||
return res;
|
||||
if (res != len)
|
||||
{
|
||||
px_debug("pullf_read_fixed: need=%d got=%d", len, res);
|
||||
return PXE_MBUF_SHORT_READ;
|
||||
}
|
||||
if (p != dst)
|
||||
memcpy(dst, p, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* read from MBuf
|
||||
*/
|
||||
static int
|
||||
pull_from_mbuf(void *arg, PullFilter * src, int len,
|
||||
uint8 **data_p, uint8 *buf, int buflen)
|
||||
{
|
||||
MBuf *mbuf = arg;
|
||||
return mbuf_grab(mbuf, len, data_p);
|
||||
}
|
||||
|
||||
static const struct PullFilterOps mbuf_reader = {
|
||||
NULL, pull_from_mbuf, NULL
|
||||
};
|
||||
|
||||
int
|
||||
pullf_create_mbuf_reader(PullFilter ** mp_p, MBuf * src)
|
||||
{
|
||||
return pullf_create(mp_p, &mbuf_reader, src, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PushFilter
|
||||
*/
|
||||
|
||||
struct PushFilter
|
||||
{
|
||||
PushFilter *next;
|
||||
const PushFilterOps *op;
|
||||
int block_size;
|
||||
uint8 *buf;
|
||||
int pos;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
int
|
||||
pushf_create(PushFilter ** mp_p, const PushFilterOps * op, void *init_arg, PushFilter * next)
|
||||
{
|
||||
PushFilter *mp;
|
||||
void *priv;
|
||||
int res;
|
||||
|
||||
if (op->init != NULL)
|
||||
{
|
||||
res = op->init(next, init_arg, &priv);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv = init_arg;
|
||||
res = 0;
|
||||
}
|
||||
|
||||
mp = px_alloc(sizeof(*mp));
|
||||
memset(mp, 0, sizeof(*mp));
|
||||
mp->block_size = res;
|
||||
mp->op = op;
|
||||
mp->priv = priv;
|
||||
mp->next = next;
|
||||
if (mp->block_size > 0)
|
||||
{
|
||||
mp->buf = px_alloc(mp->block_size);
|
||||
mp->pos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mp->buf = NULL;
|
||||
mp->pos = 0;
|
||||
}
|
||||
*mp_p = mp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pushf_free(PushFilter * mp)
|
||||
{
|
||||
if (mp->op->free)
|
||||
mp->op->free(mp->priv);
|
||||
|
||||
if (mp->buf)
|
||||
{
|
||||
memset(mp->buf, 0, mp->block_size);
|
||||
px_free(mp->buf);
|
||||
}
|
||||
|
||||
memset(mp, 0, sizeof(*mp));
|
||||
px_free(mp);
|
||||
}
|
||||
|
||||
void
|
||||
pushf_free_all(PushFilter * mp)
|
||||
{
|
||||
PushFilter *tmp;
|
||||
|
||||
while (mp)
|
||||
{
|
||||
tmp = mp->next;
|
||||
pushf_free(mp);
|
||||
mp = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
wrap_process(PushFilter * mp, const uint8 *data, int len)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (mp->op->push != NULL)
|
||||
res = mp->op->push(mp->next, mp->priv, data, len);
|
||||
else
|
||||
res = pushf_write(mp->next, data, len);
|
||||
if (res > 0)
|
||||
return PXE_BUG;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* consumes all data, returns len on success */
|
||||
int
|
||||
pushf_write(PushFilter * mp, const uint8 *data, int len)
|
||||
{
|
||||
int need,
|
||||
res;
|
||||
|
||||
/*
|
||||
* no buffering
|
||||
*/
|
||||
if (mp->block_size <= 0)
|
||||
return wrap_process(mp, data, len);
|
||||
|
||||
/*
|
||||
* try to empty buffer
|
||||
*/
|
||||
need = mp->block_size - mp->pos;
|
||||
if (need > 0)
|
||||
{
|
||||
if (len < need)
|
||||
{
|
||||
memcpy(mp->buf + mp->pos, data, len);
|
||||
mp->pos += len;
|
||||
return 0;
|
||||
}
|
||||
memcpy(mp->buf + mp->pos, data, need);
|
||||
len -= need;
|
||||
data += need;
|
||||
}
|
||||
|
||||
/*
|
||||
* buffer full, process
|
||||
*/
|
||||
res = wrap_process(mp, mp->buf, mp->block_size);
|
||||
if (res < 0)
|
||||
return res;
|
||||
mp->pos = 0;
|
||||
|
||||
/*
|
||||
* now process directly from data
|
||||
*/
|
||||
while (len > 0)
|
||||
{
|
||||
if (len > mp->block_size)
|
||||
{
|
||||
res = wrap_process(mp, data, mp->block_size);
|
||||
if (res < 0)
|
||||
return res;
|
||||
data += mp->block_size;
|
||||
len -= mp->block_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(mp->buf, data, len);
|
||||
mp->pos += len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pushf_flush(PushFilter * mp)
|
||||
{
|
||||
int res;
|
||||
|
||||
while (mp)
|
||||
{
|
||||
if (mp->block_size > 0)
|
||||
{
|
||||
res = wrap_process(mp, mp->buf, mp->pos);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
if (mp->op->flush)
|
||||
{
|
||||
res = mp->op->flush(mp->next, mp->priv);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
mp = mp->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* write to MBuf
|
||||
*/
|
||||
static int
|
||||
push_into_mbuf(PushFilter * next, void *arg, const uint8 *data, int len)
|
||||
{
|
||||
int res = 0;
|
||||
MBuf *mbuf = arg;
|
||||
|
||||
if (len > 0)
|
||||
res = mbuf_append(mbuf, data, len);
|
||||
return res < 0 ? res : 0;
|
||||
}
|
||||
|
||||
static const struct PushFilterOps mbuf_filter = {
|
||||
NULL, push_into_mbuf, NULL, NULL
|
||||
};
|
||||
|
||||
int pushf_create_mbuf_writer(PushFilter **res, MBuf *dst)
|
||||
{
|
||||
return pushf_create(res, &mbuf_filter, dst, NULL);
|
||||
}
|
||||
|
121
contrib/pgcrypto/mbuf.h
Normal file
121
contrib/pgcrypto/mbuf.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* mbuf.h
|
||||
* Memory buffer operations.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/mbuf.h,v 1.1 2005/07/10 13:46:28 momjian Exp $
|
||||
*/
|
||||
|
||||
#ifndef __PX_MBUF_H
|
||||
#define __PX_MBUF_H
|
||||
|
||||
typedef struct MBuf MBuf;
|
||||
typedef struct PushFilter PushFilter;
|
||||
typedef struct PullFilter PullFilter;
|
||||
typedef struct PushFilterOps PushFilterOps;
|
||||
typedef struct PullFilterOps PullFilterOps;
|
||||
|
||||
struct PushFilterOps
|
||||
{
|
||||
/* should return needed buffer size, 0- no buffering, <0 on error
|
||||
* if NULL, no buffering, and priv=init_arg
|
||||
*/
|
||||
int (*init) (PushFilter * next, void *init_arg, void **priv_p);
|
||||
/* send data to next. should consume all?
|
||||
* if null, it will be simply copied (in-place)
|
||||
* returns 0 on error
|
||||
*/
|
||||
int (*push) (PushFilter * next, void *priv,
|
||||
const uint8 *src, int len);
|
||||
int (*flush) (PushFilter * next, void *priv);
|
||||
void (*free) (void *priv);
|
||||
};
|
||||
|
||||
struct PullFilterOps
|
||||
{
|
||||
/* should return needed buffer size, 0- no buffering, <0 on error
|
||||
* if NULL, no buffering, and priv=init_arg
|
||||
*/
|
||||
int (*init) (void **priv_p, void *init_arg, PullFilter * src);
|
||||
/* request data from src, put result ptr to data_p
|
||||
* can use ptr from src or use buf as work area
|
||||
* if NULL in-place copy
|
||||
*/
|
||||
int (*pull) (void *priv, PullFilter * src, int len,
|
||||
uint8 **data_p, uint8 *buf, int buflen);
|
||||
void (*free) (void *priv);
|
||||
};
|
||||
|
||||
/*
|
||||
* Memory buffer
|
||||
*/
|
||||
MBuf *mbuf_create(int len);
|
||||
MBuf *mbuf_create_from_data(const uint8 *data, int len);
|
||||
int mbuf_tell(MBuf * mbuf);
|
||||
int mbuf_avail(MBuf * mbuf);
|
||||
int mbuf_size(MBuf * mbuf);
|
||||
int mbuf_grab(MBuf * mbuf, int len, uint8 **data_p);
|
||||
int mbuf_steal_data(MBuf * mbuf, uint8 **data_p);
|
||||
int mbuf_append(MBuf * dst, const uint8 *buf, int cnt);
|
||||
int mbuf_rewind(MBuf * mbuf);
|
||||
int mbuf_free(MBuf * mbuf);
|
||||
|
||||
/*
|
||||
* Push filter
|
||||
*/
|
||||
int pushf_create(PushFilter ** res, const PushFilterOps * ops, void *init_arg,
|
||||
PushFilter * next);
|
||||
int pushf_write(PushFilter * mp, const uint8 *data, int len);
|
||||
void pushf_free_all(PushFilter * mp);
|
||||
void pushf_free(PushFilter * mp);
|
||||
int pushf_flush(PushFilter * mp);
|
||||
|
||||
int pushf_create_mbuf_writer(PushFilter ** mp_p, MBuf * mbuf);
|
||||
|
||||
/*
|
||||
* Pull filter
|
||||
*/
|
||||
int pullf_create(PullFilter ** res, const PullFilterOps * ops,
|
||||
void *init_arg, PullFilter * src);
|
||||
int pullf_read(PullFilter * mp, int len, uint8 **data_p);
|
||||
int pullf_read_max(PullFilter * mp, int len,
|
||||
uint8 **data_p, uint8 *tmpbuf);
|
||||
void pullf_free(PullFilter * mp);
|
||||
int pullf_read_fixed(PullFilter *src, int len, uint8 *dst);
|
||||
|
||||
int pullf_create_mbuf_reader(PullFilter ** pf_p, MBuf * mbuf);
|
||||
|
||||
#define GETBYTE(pf, dst) \
|
||||
do { \
|
||||
uint8 __b; \
|
||||
int __res = pullf_read_fixed(pf, 1, &__b); \
|
||||
if (__res < 0) \
|
||||
return __res; \
|
||||
(dst) = __b; \
|
||||
} while (0)
|
||||
|
||||
#endif /* __PX_MBUF_H */
|
||||
|
383
contrib/pgcrypto/pgp-armor.c
Normal file
383
contrib/pgcrypto/pgp-armor.c
Normal file
@ -0,0 +1,383 @@
|
||||
/*
|
||||
* pgp-armor.c
|
||||
* PGP ascii-armor.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-armor.c,v 1.1 2005/07/10 13:46:28 momjian Exp $
|
||||
*/
|
||||
|
||||
#include <postgres.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "px.h"
|
||||
#include "mbuf.h"
|
||||
#include "pgp.h"
|
||||
|
||||
/*
|
||||
* BASE64 - duplicated :(
|
||||
*/
|
||||
|
||||
static const unsigned char _base64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static int
|
||||
b64_encode(const uint8 *src, unsigned len, uint8 *dst)
|
||||
{
|
||||
uint8 *p,
|
||||
*lend = dst + 76;
|
||||
const uint8 *s,
|
||||
*end = src + len;
|
||||
int pos = 2;
|
||||
unsigned long buf = 0;
|
||||
|
||||
s = src;
|
||||
p = dst;
|
||||
|
||||
while (s < end)
|
||||
{
|
||||
buf |= *s << (pos << 3);
|
||||
pos--;
|
||||
s++;
|
||||
|
||||
/*
|
||||
* write it out
|
||||
*/
|
||||
if (pos < 0)
|
||||
{
|
||||
*p++ = _base64[(buf >> 18) & 0x3f];
|
||||
*p++ = _base64[(buf >> 12) & 0x3f];
|
||||
*p++ = _base64[(buf >> 6) & 0x3f];
|
||||
*p++ = _base64[buf & 0x3f];
|
||||
|
||||
pos = 2;
|
||||
buf = 0;
|
||||
}
|
||||
if (p >= lend)
|
||||
{
|
||||
*p++ = '\n';
|
||||
lend = p + 76;
|
||||
}
|
||||
}
|
||||
if (pos != 2)
|
||||
{
|
||||
*p++ = _base64[(buf >> 18) & 0x3f];
|
||||
*p++ = _base64[(buf >> 12) & 0x3f];
|
||||
*p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '=';
|
||||
*p++ = '=';
|
||||
}
|
||||
|
||||
return p - dst;
|
||||
}
|
||||
|
||||
/* probably should use lookup table */
|
||||
static int
|
||||
b64_decode(const uint8 *src, unsigned len, uint8 *dst)
|
||||
{
|
||||
const uint8 *srcend = src + len,
|
||||
*s = src;
|
||||
uint8 *p = dst;
|
||||
char c;
|
||||
unsigned b = 0;
|
||||
unsigned long buf = 0;
|
||||
int pos = 0,
|
||||
end = 0;
|
||||
|
||||
while (s < srcend)
|
||||
{
|
||||
c = *s++;
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
b = c - 'A';
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
b = c - 'a' + 26;
|
||||
else if (c >= '0' && c <= '9')
|
||||
b = c - '0' + 52;
|
||||
else if (c == '+')
|
||||
b = 62;
|
||||
else if (c == '/')
|
||||
b = 63;
|
||||
else if (c == '=')
|
||||
{
|
||||
/*
|
||||
* end sequence
|
||||
*/
|
||||
if (!end)
|
||||
{
|
||||
if (pos == 2)
|
||||
end = 1;
|
||||
else if (pos == 3)
|
||||
end = 2;
|
||||
else
|
||||
return PXE_PGP_CORRUPT_ARMOR;
|
||||
}
|
||||
b = 0;
|
||||
}
|
||||
else if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
|
||||
continue;
|
||||
else
|
||||
return PXE_PGP_CORRUPT_ARMOR;
|
||||
|
||||
/*
|
||||
* add it to buffer
|
||||
*/
|
||||
buf = (buf << 6) + b;
|
||||
pos++;
|
||||
if (pos == 4)
|
||||
{
|
||||
*p++ = (buf >> 16) & 255;
|
||||
if (end == 0 || end > 1)
|
||||
*p++ = (buf >> 8) & 255;
|
||||
if (end == 0 || end > 2)
|
||||
*p++ = buf & 255;
|
||||
buf = 0;
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos != 0)
|
||||
return PXE_PGP_CORRUPT_ARMOR;
|
||||
return p - dst;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
b64_enc_len(unsigned srclen)
|
||||
{
|
||||
/*
|
||||
* 3 bytes will be converted to 4, linefeed after 76 chars
|
||||
*/
|
||||
return (srclen + 2) * 4 / 3 + srclen / (76 * 3 / 4);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
b64_dec_len(unsigned srclen)
|
||||
{
|
||||
return (srclen * 3) >> 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* PGP armor
|
||||
*/
|
||||
|
||||
static const char *armor_header = "-----BEGIN PGP MESSAGE-----\n\n";
|
||||
static const char *armor_footer = "\n-----END PGP MESSAGE-----\n";
|
||||
|
||||
/* CRC24 implementation from rfc2440 */
|
||||
#define CRC24_INIT 0x00b704ceL
|
||||
#define CRC24_POLY 0x01864cfbL
|
||||
static long
|
||||
crc24(const uint8 *data, unsigned len)
|
||||
{
|
||||
unsigned crc = CRC24_INIT;
|
||||
int i;
|
||||
|
||||
while (len--)
|
||||
{
|
||||
crc ^= (*data++) << 16;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
crc <<= 1;
|
||||
if (crc & 0x1000000)
|
||||
crc ^= CRC24_POLY;
|
||||
}
|
||||
}
|
||||
return crc & 0xffffffL;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_armor_encode(const uint8 *src, unsigned len, uint8 *dst)
|
||||
{
|
||||
int n;
|
||||
uint8 *pos = dst;
|
||||
unsigned crc = crc24(src, len);
|
||||
|
||||
n = strlen(armor_header);
|
||||
memcpy(pos, armor_header, n);
|
||||
pos += n;
|
||||
|
||||
n = b64_encode(src, len, pos);
|
||||
pos += n;
|
||||
|
||||
if (*(pos - 1) != '\n')
|
||||
*pos++ = '\n';
|
||||
|
||||
*pos++ = '=';
|
||||
pos[3] = _base64[crc & 0x3f];
|
||||
crc >>= 6;
|
||||
pos[2] = _base64[crc & 0x3f];
|
||||
crc >>= 6;
|
||||
pos[1] = _base64[crc & 0x3f];
|
||||
crc >>= 6;
|
||||
pos[0] = _base64[crc & 0x3f];
|
||||
pos += 4;
|
||||
|
||||
n = strlen(armor_footer);
|
||||
memcpy(pos, armor_footer, n);
|
||||
pos += n;
|
||||
|
||||
return pos - dst;
|
||||
}
|
||||
|
||||
static const uint8 *
|
||||
find_str(const uint8 *data, const uint8 *data_end, const char *str, int strlen)
|
||||
{
|
||||
const uint8 *p = data;
|
||||
if (!strlen)
|
||||
return NULL;
|
||||
if (data_end - data < strlen)
|
||||
return NULL;
|
||||
while (p < data_end) {
|
||||
p = memchr(p, str[0], data_end - p);
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
if (p + strlen > data_end)
|
||||
return NULL;
|
||||
if (memcmp(p, str, strlen) == 0)
|
||||
return p;
|
||||
p++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
find_header(const uint8 *data, const uint8 *datend,
|
||||
const uint8 **start_p, int is_end)
|
||||
{
|
||||
const uint8 *p = data;
|
||||
static const char *start_sep = "-----BEGIN";
|
||||
static const char *end_sep = "-----END";
|
||||
const char *sep = is_end ? end_sep : start_sep;
|
||||
|
||||
/* find header line */
|
||||
while (1)
|
||||
{
|
||||
p = find_str(p, datend, sep, strlen(sep));
|
||||
if (p == NULL)
|
||||
return PXE_PGP_CORRUPT_ARMOR;
|
||||
/* it must start at beginning of line */
|
||||
if (p == data || *(p - 1) == '\n')
|
||||
break;
|
||||
p += strlen(sep);
|
||||
}
|
||||
*start_p = p;
|
||||
p += strlen(sep);
|
||||
|
||||
/* check if header text ok */
|
||||
for (; p < datend && *p != '-'; p++)
|
||||
{
|
||||
/* various junk can be there, but definitely not line-feed */
|
||||
if (*p >= ' ')
|
||||
continue;
|
||||
return PXE_PGP_CORRUPT_ARMOR;
|
||||
}
|
||||
if (datend - p < 5 || memcmp(p, sep, 5) != 0)
|
||||
return PXE_PGP_CORRUPT_ARMOR;
|
||||
p += 5;
|
||||
|
||||
/* check if at end of line */
|
||||
if (p < datend)
|
||||
{
|
||||
if (*p != '\n' && *p != '\r')
|
||||
return PXE_PGP_CORRUPT_ARMOR;
|
||||
if (*p == '\r')
|
||||
p++;
|
||||
if (p < datend && *p == '\n')
|
||||
p++;
|
||||
}
|
||||
return p - *start_p;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_armor_decode(const uint8 *src, unsigned len, uint8 *dst)
|
||||
{
|
||||
const uint8 *p = src;
|
||||
const uint8 *data_end = src + len;
|
||||
long crc;
|
||||
const uint8 *base64_start, *armor_end;
|
||||
const uint8 *base64_end = NULL;
|
||||
uint8 buf[4];
|
||||
int hlen;
|
||||
int res = PXE_PGP_CORRUPT_ARMOR;
|
||||
|
||||
/* armor start */
|
||||
hlen = find_header(src, data_end, &p, 0);
|
||||
if (hlen <= 0)
|
||||
goto out;
|
||||
p += hlen;
|
||||
|
||||
/* armor end */
|
||||
hlen = find_header(p, data_end, &armor_end, 1);
|
||||
if (hlen <= 0)
|
||||
goto out;
|
||||
|
||||
/* skip comments - find empty line */
|
||||
while (p < armor_end && *p != '\n' && *p != '\r')
|
||||
{
|
||||
p = memchr(p, '\n', armor_end - p);
|
||||
if (!p)
|
||||
goto out;
|
||||
|
||||
/* step to start of next line */
|
||||
p++;
|
||||
}
|
||||
base64_start = p;
|
||||
|
||||
/* find crc pos */
|
||||
for (p = armor_end; p >= base64_start; p--)
|
||||
if (*p == '=')
|
||||
{
|
||||
base64_end = p - 1;
|
||||
break;
|
||||
}
|
||||
if (base64_end == NULL)
|
||||
goto out;
|
||||
|
||||
/* decode crc */
|
||||
if (b64_decode(p + 1, 4, buf) != 3)
|
||||
goto out;
|
||||
crc = (((long)buf[0]) << 16) + (((long)buf[1]) << 8) + (long)buf[2];
|
||||
|
||||
/* decode data */
|
||||
res = b64_decode(base64_start, base64_end - base64_start, dst);
|
||||
|
||||
/* check crc */
|
||||
if (res >= 0 && crc24(dst, res) != crc)
|
||||
res = PXE_PGP_CORRUPT_ARMOR;
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
||||
unsigned
|
||||
pgp_armor_enc_len(unsigned len)
|
||||
{
|
||||
return b64_enc_len(len) + strlen(armor_header) + strlen(armor_footer) + 16;
|
||||
}
|
||||
|
||||
unsigned
|
||||
pgp_armor_dec_len(unsigned len)
|
||||
{
|
||||
return b64_dec_len(len);
|
||||
}
|
||||
|
257
contrib/pgcrypto/pgp-cfb.c
Normal file
257
contrib/pgcrypto/pgp-cfb.c
Normal file
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* pgp-cfb.c
|
||||
* Implements both normal and PGP-specific CFB mode.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-cfb.c,v 1.1 2005/07/10 13:46:28 momjian Exp $
|
||||
*/
|
||||
|
||||
#include <postgres.h>
|
||||
#include "mbuf.h"
|
||||
#include "px.h"
|
||||
#include "pgp.h"
|
||||
|
||||
typedef int (*mix_data_t)(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst);
|
||||
|
||||
struct PGP_CFB
|
||||
{
|
||||
PX_Cipher *ciph;
|
||||
int block_size;
|
||||
int pos;
|
||||
int block_no;
|
||||
int resync;
|
||||
uint8 fr[PGP_MAX_BLOCK];
|
||||
uint8 fre[PGP_MAX_BLOCK];
|
||||
uint8 encbuf[PGP_MAX_BLOCK];
|
||||
};
|
||||
|
||||
int
|
||||
pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len,
|
||||
int resync, uint8 *iv)
|
||||
{
|
||||
int res;
|
||||
PX_Cipher *ciph;
|
||||
PGP_CFB *ctx;
|
||||
|
||||
res = pgp_load_cipher(algo, &ciph);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = px_cipher_init(ciph, key, key_len, NULL);
|
||||
if (res < 0)
|
||||
{
|
||||
px_cipher_free(ciph);
|
||||
return res;
|
||||
}
|
||||
|
||||
ctx = px_alloc(sizeof(*ctx));
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->ciph = ciph;
|
||||
ctx->block_size = px_cipher_block_size(ciph);
|
||||
ctx->resync = resync;
|
||||
|
||||
if (iv)
|
||||
memcpy(ctx->fr, iv, ctx->block_size);
|
||||
|
||||
*ctx_p = ctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pgp_cfb_free(PGP_CFB *ctx)
|
||||
{
|
||||
px_cipher_free(ctx->ciph);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
px_free(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Data processing for normal CFB. (PGP_PKT_SYMENCRYPTED_DATA_MDC)
|
||||
*/
|
||||
static int
|
||||
mix_encrypt_normal(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
||||
{
|
||||
int i;
|
||||
for (i = ctx->pos; i < ctx->pos + len; i++)
|
||||
*dst++ = ctx->encbuf[i] = ctx->fre[i] ^ (*data++);
|
||||
ctx->pos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
mix_decrypt_normal(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
||||
{
|
||||
int i;
|
||||
for (i = ctx->pos; i < ctx->pos + len; i++)
|
||||
{
|
||||
ctx->encbuf[i] = *data++;
|
||||
*dst++ = ctx->fre[i] ^ ctx->encbuf[i];
|
||||
}
|
||||
ctx->pos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Data processing for old PGP CFB mode. (PGP_PKT_SYMENCRYPTED_DATA)
|
||||
*
|
||||
* The goal is to hide the horror from the rest of the code,
|
||||
* thus its all concentrated here.
|
||||
*/
|
||||
static int
|
||||
mix_encrypt_resync(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
||||
{
|
||||
int i,n;
|
||||
/* block #2 is 2 bytes long */
|
||||
if (ctx->block_no == 2)
|
||||
{
|
||||
n = 2 - ctx->pos;
|
||||
if (len < n)
|
||||
n = len;
|
||||
for (i = ctx->pos; i < ctx->pos + n; i++)
|
||||
*dst++ = ctx->encbuf[i] = ctx->fre[i] ^ (*data++);
|
||||
|
||||
ctx->pos += n;
|
||||
len -= n;
|
||||
|
||||
if (ctx->pos == 2)
|
||||
{
|
||||
memcpy(ctx->fr, ctx->encbuf + 2, ctx->block_size - 2);
|
||||
memcpy(ctx->fr + ctx->block_size - 2, ctx->encbuf, 2);
|
||||
ctx->pos = 0;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
for (i = ctx->pos; i < ctx->pos + len; i++)
|
||||
*dst++ = ctx->encbuf[i] = ctx->fre[i] ^ (*data++);
|
||||
ctx->pos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
mix_decrypt_resync(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
||||
{
|
||||
int i,n;
|
||||
/* block #2 is 2 bytes long */
|
||||
if (ctx->block_no == 2)
|
||||
{
|
||||
n = 2 - ctx->pos;
|
||||
if (len < n)
|
||||
n = len;
|
||||
for (i = ctx->pos; i < ctx->pos + n; i++)
|
||||
{
|
||||
ctx->encbuf[i] = *data++;
|
||||
*dst++ = ctx->fre[i] ^ ctx->encbuf[i];
|
||||
}
|
||||
ctx->pos += n;
|
||||
len -= n;
|
||||
|
||||
if (ctx->pos == 2)
|
||||
{
|
||||
memcpy(ctx->fr, ctx->encbuf + 2, ctx->block_size - 2);
|
||||
memcpy(ctx->fr + ctx->block_size - 2, ctx->encbuf, 2);
|
||||
ctx->pos = 0;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
for (i = ctx->pos; i < ctx->pos + len; i++)
|
||||
{
|
||||
ctx->encbuf[i] = *data++;
|
||||
*dst++ = ctx->fre[i] ^ ctx->encbuf[i];
|
||||
}
|
||||
ctx->pos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* common code for both encrypt and decrypt.
|
||||
*/
|
||||
static int
|
||||
cfb_process(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst,
|
||||
mix_data_t mix_data)
|
||||
{
|
||||
int n;
|
||||
int res;
|
||||
|
||||
while (len > 0 && ctx->pos > 0)
|
||||
{
|
||||
n = ctx->block_size - ctx->pos;
|
||||
if (len < n)
|
||||
n = len;
|
||||
|
||||
n = mix_data(ctx, data, n, dst);
|
||||
data += n;
|
||||
dst += n;
|
||||
len -= n;
|
||||
|
||||
if (ctx->pos == ctx->block_size)
|
||||
{
|
||||
memcpy(ctx->fr, ctx->encbuf, ctx->block_size);
|
||||
ctx->pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
px_cipher_encrypt(ctx->ciph, ctx->fr, ctx->block_size, ctx->fre);
|
||||
if (ctx->block_no < 5)
|
||||
ctx->block_no++;
|
||||
|
||||
n = ctx->block_size;
|
||||
if (len < n)
|
||||
n = len;
|
||||
|
||||
res = mix_data(ctx, data, n, dst);
|
||||
data += res;
|
||||
dst += res;
|
||||
len -= res;
|
||||
|
||||
if (ctx->pos == ctx->block_size)
|
||||
{
|
||||
memcpy(ctx->fr, ctx->encbuf, ctx->block_size);
|
||||
ctx->pos = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* public interface
|
||||
*/
|
||||
|
||||
int
|
||||
pgp_cfb_encrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
||||
{
|
||||
mix_data_t mix = ctx->resync ? mix_encrypt_resync : mix_encrypt_normal;
|
||||
return cfb_process(ctx, data, len, dst, mix);
|
||||
}
|
||||
|
||||
int
|
||||
pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
||||
{
|
||||
mix_data_t mix = ctx->resync ? mix_decrypt_resync : mix_decrypt_normal;
|
||||
return cfb_process(ctx, data, len, dst, mix);
|
||||
}
|
||||
|
322
contrib/pgcrypto/pgp-compress.c
Normal file
322
contrib/pgcrypto/pgp-compress.c
Normal file
@ -0,0 +1,322 @@
|
||||
/*
|
||||
* pgp-compress.c
|
||||
* ZIP and ZLIB compression via zlib.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-compress.c,v 1.1 2005/07/10 13:46:28 momjian Exp $
|
||||
*/
|
||||
|
||||
#include <postgres.h>
|
||||
|
||||
#include "mbuf.h"
|
||||
#include "px.h"
|
||||
#include "pgp.h"
|
||||
|
||||
|
||||
/*
|
||||
* Compressed pkt writer
|
||||
*/
|
||||
|
||||
#ifndef DISABLE_ZLIB
|
||||
|
||||
#include <zlib.h>
|
||||
#define ZIP_OUT_BUF 8192
|
||||
#define ZIP_IN_BLOCK 8192
|
||||
|
||||
struct ZipStat
|
||||
{
|
||||
uint8 type;
|
||||
int buf_len;
|
||||
int hdr_done;
|
||||
z_stream stream;
|
||||
uint8 buf[ZIP_OUT_BUF];
|
||||
};
|
||||
|
||||
static void *
|
||||
z_alloc(void *priv, unsigned n_items, unsigned item_len)
|
||||
{
|
||||
return px_alloc(n_items * item_len);
|
||||
}
|
||||
|
||||
static void
|
||||
z_free(void *priv, void *addr)
|
||||
{
|
||||
px_free(addr);
|
||||
}
|
||||
|
||||
static int
|
||||
compress_init(PushFilter * next, void *init_arg, void **priv_p)
|
||||
{
|
||||
int res;
|
||||
struct ZipStat *st;
|
||||
PGP_Context *ctx = init_arg;
|
||||
uint8 type = ctx->compress_algo;
|
||||
|
||||
if (type != PGP_COMPR_ZLIB && type != PGP_COMPR_ZIP)
|
||||
return PXE_PGP_UNSUPPORTED_COMPR;
|
||||
|
||||
/*
|
||||
* init
|
||||
*/
|
||||
st = px_alloc(sizeof(*st));
|
||||
memset(st, 0, sizeof(*st));
|
||||
st->buf_len = ZIP_OUT_BUF;
|
||||
st->stream.zalloc = z_alloc;
|
||||
st->stream.zfree = z_free;
|
||||
|
||||
if (type == PGP_COMPR_ZIP)
|
||||
res = deflateInit2(&st->stream, ctx->compress_level,
|
||||
Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
|
||||
else
|
||||
res = deflateInit(&st->stream, ctx->compress_level);
|
||||
if (res != Z_OK)
|
||||
{
|
||||
px_free(st);
|
||||
return PXE_PGP_COMPRESSION_ERROR;
|
||||
}
|
||||
*priv_p = st;
|
||||
|
||||
return ZIP_IN_BLOCK;
|
||||
}
|
||||
|
||||
/* writes compressed data packet */
|
||||
|
||||
/* cant handle zero-len incoming data, but shouldnt */
|
||||
static int
|
||||
compress_process(PushFilter * next, void *priv, const uint8 *data, int len)
|
||||
{
|
||||
int res,
|
||||
n_out;
|
||||
struct ZipStat *st = priv;
|
||||
|
||||
/*
|
||||
* process data
|
||||
*/
|
||||
while (len > 0)
|
||||
{
|
||||
st->stream.next_in = (void *) data;
|
||||
st->stream.avail_in = len;
|
||||
st->stream.next_out = st->buf;
|
||||
st->stream.avail_out = st->buf_len;
|
||||
res = deflate(&st->stream, 0);
|
||||
if (res != Z_OK)
|
||||
return PXE_PGP_COMPRESSION_ERROR;
|
||||
|
||||
n_out = st->buf_len - st->stream.avail_out;
|
||||
if (n_out > 0)
|
||||
{
|
||||
res = pushf_write(next, st->buf, n_out);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
len = st->stream.avail_in;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
compress_flush(PushFilter * next, void *priv)
|
||||
{
|
||||
int res,
|
||||
zres,
|
||||
n_out;
|
||||
struct ZipStat *st = priv;
|
||||
|
||||
st->stream.next_in = NULL;
|
||||
st->stream.avail_in = 0;
|
||||
while (1)
|
||||
{
|
||||
st->stream.next_out = st->buf;
|
||||
st->stream.avail_out = st->buf_len;
|
||||
zres = deflate(&st->stream, Z_FINISH);
|
||||
if (zres != Z_STREAM_END && zres != Z_OK)
|
||||
return PXE_PGP_COMPRESSION_ERROR;
|
||||
n_out = st->buf_len - st->stream.avail_out;
|
||||
if (n_out > 0)
|
||||
{
|
||||
res = pushf_write(next, st->buf, n_out);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
if (zres == Z_STREAM_END)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
compress_free(void *priv)
|
||||
{
|
||||
struct ZipStat *st = priv;
|
||||
|
||||
deflateEnd(&st->stream);
|
||||
memset(st, 0, sizeof(*st));
|
||||
px_free(st);
|
||||
}
|
||||
|
||||
static const PushFilterOps
|
||||
compress_filter = {
|
||||
compress_init, compress_process, compress_flush, compress_free
|
||||
};
|
||||
|
||||
int
|
||||
pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst)
|
||||
{
|
||||
return pushf_create(res, &compress_filter, ctx, dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decompress
|
||||
*/
|
||||
struct DecomprData
|
||||
{
|
||||
int buf_len; /* = ZIP_OUT_BUF */
|
||||
int buf_data; /* available data */
|
||||
uint8 *pos;
|
||||
z_stream stream;
|
||||
int eof;
|
||||
uint8 buf[ZIP_OUT_BUF];
|
||||
};
|
||||
|
||||
static int
|
||||
decompress_init(void **priv_p, void *arg, PullFilter *src)
|
||||
{
|
||||
PGP_Context *ctx = arg;
|
||||
struct DecomprData *dec;
|
||||
int res;
|
||||
|
||||
if (ctx->compress_algo != PGP_COMPR_ZLIB
|
||||
&& ctx->compress_algo != PGP_COMPR_ZIP)
|
||||
return PXE_PGP_UNSUPPORTED_COMPR;
|
||||
|
||||
dec = px_alloc(sizeof(*dec));
|
||||
memset(dec, 0, sizeof(*dec));
|
||||
dec->buf_len = ZIP_OUT_BUF;
|
||||
*priv_p = dec;
|
||||
|
||||
dec->stream.zalloc = z_alloc;
|
||||
dec->stream.zfree = z_free;
|
||||
|
||||
if (ctx->compress_algo == PGP_COMPR_ZIP)
|
||||
res = inflateInit2(&dec->stream, -15);
|
||||
else
|
||||
res = inflateInit(&dec->stream);
|
||||
if (res != Z_OK)
|
||||
{
|
||||
px_free(dec);
|
||||
px_debug("decompress_init: inflateInit error");
|
||||
return PXE_PGP_COMPRESSION_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decompress_read(void *priv, PullFilter *src, int len,
|
||||
uint8 **data_p, uint8 *buf, int buflen)
|
||||
{
|
||||
int res;
|
||||
int flush;
|
||||
struct DecomprData *dec = priv;
|
||||
|
||||
restart:
|
||||
if (dec->buf_data > 0)
|
||||
{
|
||||
if (len > dec->buf_data)
|
||||
len = dec->buf_data;
|
||||
*data_p = dec->pos;
|
||||
dec->pos += len;
|
||||
dec->buf_data -= len;
|
||||
return len;
|
||||
}
|
||||
|
||||
if (dec->eof)
|
||||
return 0;
|
||||
|
||||
if (dec->stream.avail_in == 0) {
|
||||
uint8 *tmp;
|
||||
res = pullf_read(src, 8192, &tmp);
|
||||
if (res < 0)
|
||||
return res;
|
||||
dec->stream.next_in = tmp;
|
||||
dec->stream.avail_in = res;
|
||||
}
|
||||
|
||||
dec->stream.next_out = dec->buf;
|
||||
dec->stream.avail_out = dec->buf_len;
|
||||
dec->pos = dec->buf;
|
||||
|
||||
// Z_NO_FLUSH, Z_SYNC_FLUSH,
|
||||
flush = dec->stream.avail_in ? Z_SYNC_FLUSH : Z_FINISH;
|
||||
res = inflate(&dec->stream, flush);
|
||||
if (res != Z_OK && res != Z_STREAM_END)
|
||||
{
|
||||
px_debug("decompress_read: inflate error: %d", res);
|
||||
return PXE_PGP_CORRUPT_DATA;
|
||||
}
|
||||
|
||||
dec->buf_data = dec->buf_len - dec->stream.avail_out;
|
||||
if (res == Z_STREAM_END)
|
||||
dec->eof = 1;
|
||||
goto restart;
|
||||
}
|
||||
|
||||
static void decompress_free(void *priv)
|
||||
{
|
||||
struct DecomprData *dec = priv;
|
||||
inflateEnd(&dec->stream);
|
||||
memset(dec, 0, sizeof(*dec));
|
||||
px_free(dec);
|
||||
}
|
||||
|
||||
static const PullFilterOps
|
||||
decompress_filter = {
|
||||
decompress_init, decompress_read, decompress_free
|
||||
};
|
||||
|
||||
int
|
||||
pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
|
||||
{
|
||||
return pullf_create(res, &decompress_filter, ctx, src);
|
||||
}
|
||||
|
||||
#else /* DISABLE_ZLIB */
|
||||
|
||||
int
|
||||
pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst)
|
||||
{
|
||||
return PXE_PGP_UNSUPPORTED_COMPR;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
|
||||
{
|
||||
return PXE_PGP_UNSUPPORTED_COMPR;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
1156
contrib/pgcrypto/pgp-decrypt.c
Normal file
1156
contrib/pgcrypto/pgp-decrypt.c
Normal file
File diff suppressed because it is too large
Load Diff
698
contrib/pgcrypto/pgp-encrypt.c
Normal file
698
contrib/pgcrypto/pgp-encrypt.c
Normal file
@ -0,0 +1,698 @@
|
||||
/*
|
||||
* pgp-encrypt.c
|
||||
* OpenPGP encrypt.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-encrypt.c,v 1.1 2005/07/10 13:46:28 momjian Exp $
|
||||
*/
|
||||
|
||||
#include <postgres.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mbuf.h"
|
||||
#include "px.h"
|
||||
#include "pgp.h"
|
||||
|
||||
|
||||
#define MDC_DIGEST_LEN 20
|
||||
#define STREAM_ID 0xE0
|
||||
#define STREAM_BLOCK_SHIFT 14
|
||||
|
||||
static uint8 *
|
||||
render_newlen(uint8 *h, int len)
|
||||
{
|
||||
if (len <= 191)
|
||||
{
|
||||
*h++ = len & 255;
|
||||
}
|
||||
else if (len > 191 && len <= 8383)
|
||||
{
|
||||
*h++ = ((len - 192) >> 8) + 192;
|
||||
*h++ = (len - 192) & 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
*h++ = 255;
|
||||
*h++ = (len >> 24) & 255;
|
||||
*h++ = (len >> 16) & 255;
|
||||
*h++ = (len >> 8) & 255;
|
||||
*h++ = len & 255;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
static int write_tag_only(PushFilter *dst, int tag)
|
||||
{
|
||||
uint8 hdr = 0xC0 | tag;
|
||||
return pushf_write(dst, &hdr, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
write_normal_header(PushFilter * dst, int tag, int len)
|
||||
{
|
||||
uint8 hdr[8];
|
||||
uint8 *h = hdr;
|
||||
|
||||
*h++ = 0xC0 | tag;
|
||||
h = render_newlen(h, len);
|
||||
return pushf_write(dst, hdr, h - hdr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MAC writer
|
||||
*/
|
||||
|
||||
static int
|
||||
mdc_init(PushFilter * dst, void *init_arg, void **priv_p)
|
||||
{
|
||||
int res;
|
||||
PX_MD *md;
|
||||
|
||||
res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
*priv_p = md;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mdc_write(PushFilter * dst, void *priv, const uint8 *data, int len)
|
||||
{
|
||||
PX_MD *md = priv;
|
||||
|
||||
px_md_update(md, data, len);
|
||||
return pushf_write(dst, data, len);
|
||||
}
|
||||
|
||||
static int
|
||||
mdc_flush(PushFilter * dst, void *priv)
|
||||
{
|
||||
int res;
|
||||
uint8 pkt[2 + MDC_DIGEST_LEN];
|
||||
PX_MD *md = priv;
|
||||
|
||||
/*
|
||||
* create mdc pkt
|
||||
*/
|
||||
pkt[0] = 0xD3;
|
||||
pkt[1] = 0x14; /* MDC_DIGEST_LEN */
|
||||
px_md_update(md, pkt, 2);
|
||||
px_md_finish(md, pkt + 2);
|
||||
|
||||
res = pushf_write(dst, pkt, 2 + MDC_DIGEST_LEN);
|
||||
memset(pkt, 0, 2 + MDC_DIGEST_LEN);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
mdc_free(void *priv)
|
||||
{
|
||||
PX_MD *md = priv;
|
||||
|
||||
px_md_free(md);
|
||||
}
|
||||
|
||||
static const PushFilterOps mdc_filter = {
|
||||
mdc_init, mdc_write, mdc_flush, mdc_free
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Encrypted pkt writer
|
||||
*/
|
||||
#define ENCBUF 8192
|
||||
struct EncStat
|
||||
{
|
||||
PGP_CFB *ciph;
|
||||
uint8 buf[ENCBUF];
|
||||
};
|
||||
|
||||
static int
|
||||
encrypt_init(PushFilter * next, void *init_arg, void **priv_p)
|
||||
{
|
||||
struct EncStat *st;
|
||||
PGP_Context *ctx = init_arg;
|
||||
PGP_CFB *ciph;
|
||||
int resync = 1;
|
||||
int res;
|
||||
|
||||
/* should we use newer packet format? */
|
||||
if (ctx->disable_mdc == 0)
|
||||
{
|
||||
uint8 ver = 1;
|
||||
resync = 0;
|
||||
res = pushf_write(next, &ver, 1);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
res = pgp_cfb_create(&ciph, ctx->cipher_algo,
|
||||
ctx->sess_key, ctx->sess_key_len, resync, NULL);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
st = px_alloc(sizeof(*st));
|
||||
memset(st, 0, sizeof(*st));
|
||||
st->ciph = ciph;
|
||||
|
||||
*priv_p = st;
|
||||
return ENCBUF;
|
||||
}
|
||||
|
||||
static int
|
||||
encrypt_process(PushFilter * next, void *priv, const uint8 *data, int len)
|
||||
{
|
||||
int res;
|
||||
struct EncStat *st = priv;
|
||||
int avail = len;
|
||||
|
||||
while (avail > 0)
|
||||
{
|
||||
int tmplen = avail > ENCBUF ? ENCBUF : avail;
|
||||
res = pgp_cfb_encrypt(st->ciph, data, tmplen, st->buf);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = pushf_write(next, st->buf, tmplen);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
data += tmplen;
|
||||
avail -= tmplen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
encrypt_free(void *priv)
|
||||
{
|
||||
struct EncStat *st = priv;
|
||||
|
||||
memset(st, 0, sizeof(*st));
|
||||
px_free(st);
|
||||
}
|
||||
|
||||
static const PushFilterOps encrypt_filter = {
|
||||
encrypt_init, encrypt_process, NULL, encrypt_free
|
||||
};
|
||||
|
||||
/*
|
||||
* Write Streamable pkts
|
||||
*/
|
||||
|
||||
struct PktStreamStat
|
||||
{
|
||||
int final_done;
|
||||
int pkt_block;
|
||||
};
|
||||
|
||||
static int
|
||||
pkt_stream_init(PushFilter * next, void *init_arg, void **priv_p)
|
||||
{
|
||||
struct PktStreamStat *st;
|
||||
|
||||
st = px_alloc(sizeof(*st));
|
||||
st->final_done = 0;
|
||||
st->pkt_block = 1 << STREAM_BLOCK_SHIFT;
|
||||
*priv_p = st;
|
||||
|
||||
return st->pkt_block;
|
||||
}
|
||||
|
||||
static int
|
||||
pkt_stream_process(PushFilter * next, void *priv, const uint8 *data, int len)
|
||||
{
|
||||
int res;
|
||||
uint8 hdr[8];
|
||||
uint8 *h = hdr;
|
||||
struct PktStreamStat *st = priv;
|
||||
|
||||
if (st->final_done)
|
||||
return PXE_BUG;
|
||||
|
||||
if (len == st->pkt_block)
|
||||
*h++ = STREAM_ID | STREAM_BLOCK_SHIFT;
|
||||
else
|
||||
{
|
||||
h = render_newlen(h, len);
|
||||
st->final_done = 1;
|
||||
}
|
||||
|
||||
res = pushf_write(next, hdr, h - hdr);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
return pushf_write(next, data, len);
|
||||
}
|
||||
|
||||
static int
|
||||
pkt_stream_flush(PushFilter * next, void *priv)
|
||||
{
|
||||
int res;
|
||||
uint8 hdr[8];
|
||||
uint8 *h = hdr;
|
||||
struct PktStreamStat *st = priv;
|
||||
|
||||
/* stream MUST end with normal packet. */
|
||||
if (!st->final_done)
|
||||
{
|
||||
h = render_newlen(h, 0);
|
||||
res = pushf_write(next, hdr, h - hdr);
|
||||
if (res < 0)
|
||||
return res;
|
||||
st->final_done = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pkt_stream_free(void *priv)
|
||||
{
|
||||
struct PktStreamStat *st = priv;
|
||||
|
||||
memset(st, 0, sizeof(*st));
|
||||
px_free(st);
|
||||
}
|
||||
|
||||
static const PushFilterOps pkt_stream_filter = {
|
||||
pkt_stream_init, pkt_stream_process, pkt_stream_flush, pkt_stream_free
|
||||
};
|
||||
|
||||
int pgp_create_pkt_writer(PushFilter *dst, int tag, PushFilter **res_p)
|
||||
{
|
||||
int res;
|
||||
res = write_tag_only(dst, tag);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
return pushf_create(res_p, &pkt_stream_filter, NULL, dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* Text conversion filter
|
||||
*/
|
||||
|
||||
static int
|
||||
crlf_process(PushFilter * dst, void *priv, const uint8 *data, int len)
|
||||
{
|
||||
const uint8 * data_end = data + len;
|
||||
const uint8 * p2, * p1 = data;
|
||||
int line_len;
|
||||
static const uint8 crlf[] = { '\r', '\n' };
|
||||
int res = 0;
|
||||
while (p1 < data_end)
|
||||
{
|
||||
p2 = memchr(p1, '\n', data_end - p1);
|
||||
if (p2 == NULL)
|
||||
p2 = data_end;
|
||||
|
||||
line_len = p2 - p1;
|
||||
|
||||
/* write data */
|
||||
res = 0;
|
||||
if (line_len > 0)
|
||||
{
|
||||
res = pushf_write(dst, p1, line_len);
|
||||
if (res < 0)
|
||||
break;
|
||||
p1 += line_len;
|
||||
}
|
||||
|
||||
/* write crlf */
|
||||
while (p1 < data_end && *p1 == '\n')
|
||||
{
|
||||
res = pushf_write(dst, crlf, 2);
|
||||
if (res < 0)
|
||||
break;
|
||||
p1++;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static const PushFilterOps crlf_filter = {
|
||||
NULL, crlf_process, NULL, NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize literal data packet
|
||||
*/
|
||||
static int
|
||||
init_litdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
|
||||
{
|
||||
int res;
|
||||
int hdrlen;
|
||||
uint8 hdr[6];
|
||||
uint32 t;
|
||||
PushFilter *pkt;
|
||||
int type;
|
||||
|
||||
/*
|
||||
* Create header
|
||||
*/
|
||||
|
||||
if (ctx->text_mode)
|
||||
type = ctx->unicode_mode ? 'u' : 't';
|
||||
else
|
||||
type = 'b';
|
||||
|
||||
/*
|
||||
* Store the creation time into packet.
|
||||
* The goal is to have as few known bytes as possible.
|
||||
*/
|
||||
t = (uint32)time(NULL);
|
||||
|
||||
hdr[0] = type;
|
||||
hdr[1] = 0;
|
||||
hdr[2] = (t >> 24) & 255;
|
||||
hdr[3] = (t >> 16) & 255;
|
||||
hdr[4] = (t >> 8) & 255;
|
||||
hdr[5] = t & 255;
|
||||
hdrlen = 6;
|
||||
|
||||
res = write_tag_only(dst, PGP_PKT_LITERAL_DATA);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = pushf_create(&pkt, &pkt_stream_filter, ctx, dst);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = pushf_write(pkt, hdr, hdrlen);
|
||||
if (res < 0)
|
||||
{
|
||||
pushf_free(pkt);
|
||||
return res;
|
||||
}
|
||||
|
||||
*pf_res = pkt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize compression filter
|
||||
*/
|
||||
static int
|
||||
init_compress(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
|
||||
{
|
||||
int res;
|
||||
uint8 type = ctx->compress_algo;
|
||||
PushFilter *pkt;
|
||||
|
||||
res = write_tag_only(dst, PGP_PKT_COMPRESSED_DATA);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = pushf_create(&pkt, &pkt_stream_filter, ctx, dst);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = pushf_write(pkt, &type, 1);
|
||||
if (res >= 0)
|
||||
res = pgp_compress_filter(pf_res, ctx, pkt);
|
||||
|
||||
if (res < 0)
|
||||
pushf_free(pkt);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize encdata packet
|
||||
*/
|
||||
static int
|
||||
init_encdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
|
||||
{
|
||||
int res;
|
||||
int tag;
|
||||
|
||||
if (ctx->disable_mdc)
|
||||
tag = PGP_PKT_SYMENCRYPTED_DATA;
|
||||
else
|
||||
tag = PGP_PKT_SYMENCRYPTED_DATA_MDC;
|
||||
|
||||
res = write_tag_only(dst, tag);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
return pushf_create(pf_res, &pkt_stream_filter, ctx, dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* write prefix
|
||||
*/
|
||||
static int
|
||||
write_prefix(PGP_Context *ctx, PushFilter * dst)
|
||||
{
|
||||
uint8 prefix[PGP_MAX_BLOCK + 2];
|
||||
int res,
|
||||
bs;
|
||||
|
||||
bs = pgp_get_cipher_block_size(ctx->cipher_algo);
|
||||
res = px_get_random_bytes(prefix, bs);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
prefix[bs + 0] = prefix[bs - 2];
|
||||
prefix[bs + 1] = prefix[bs - 1];
|
||||
|
||||
res = pushf_write(dst, prefix, bs + 2);
|
||||
memset(prefix, 0, bs + 2);
|
||||
return res < 0 ? res : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* write symmetrically encrypted session key packet
|
||||
*/
|
||||
|
||||
static int
|
||||
symencrypt_sesskey(PGP_Context *ctx, uint8 *dst)
|
||||
{
|
||||
int res;
|
||||
PGP_CFB *cfb;
|
||||
uint8 algo = ctx->cipher_algo;
|
||||
|
||||
res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
|
||||
ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
pgp_cfb_encrypt(cfb, &algo, 1, dst);
|
||||
pgp_cfb_encrypt(cfb, ctx->sess_key, ctx->sess_key_len, dst + 1);
|
||||
|
||||
pgp_cfb_free(cfb);
|
||||
return ctx->sess_key_len + 1;
|
||||
}
|
||||
|
||||
/* 5.3: Symmetric-Key Encrypted Session-Key */
|
||||
static int
|
||||
write_symenc_sesskey(PGP_Context *ctx, PushFilter *dst)
|
||||
{
|
||||
uint8 pkt[256];
|
||||
int pktlen;
|
||||
int res;
|
||||
uint8 *p = pkt;
|
||||
|
||||
*p++ = 4; /* 5.3 - version number */
|
||||
*p++ = ctx->s2k_cipher_algo;
|
||||
|
||||
*p++ = ctx->s2k.mode;
|
||||
*p++ = ctx->s2k.digest_algo;
|
||||
if (ctx->s2k.mode > 0)
|
||||
{
|
||||
memcpy(p, ctx->s2k.salt, 8);
|
||||
p += 8;
|
||||
}
|
||||
if (ctx->s2k.mode == 3)
|
||||
*p++ = ctx->s2k.iter;
|
||||
|
||||
if (ctx->use_sess_key)
|
||||
{
|
||||
res = symencrypt_sesskey(ctx, p);
|
||||
if (res < 0)
|
||||
return res;
|
||||
p += res;
|
||||
}
|
||||
|
||||
pktlen = p - pkt;
|
||||
res = write_normal_header(dst, PGP_PKT_SYMENCRYPTED_SESSKEY, pktlen);
|
||||
if (res >= 0)
|
||||
res = pushf_write(dst, pkt, pktlen);
|
||||
|
||||
memset(pkt, 0, pktlen);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* key setup
|
||||
*/
|
||||
static int
|
||||
init_s2k_key(PGP_Context * ctx)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (ctx->s2k_cipher_algo < 0)
|
||||
ctx->s2k_cipher_algo = ctx->cipher_algo;
|
||||
|
||||
res = pgp_s2k_fill(&ctx->s2k, ctx->s2k_mode, ctx->s2k_digest_algo);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
return pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
|
||||
ctx->sym_key, ctx->sym_key_len);
|
||||
}
|
||||
|
||||
static int
|
||||
init_sess_key(PGP_Context *ctx)
|
||||
{
|
||||
int res;
|
||||
if (ctx->use_sess_key || ctx->pub_key)
|
||||
{
|
||||
ctx->sess_key_len = pgp_get_cipher_key_size(ctx->cipher_algo);
|
||||
res = px_get_random_bytes(ctx->sess_key, ctx->sess_key_len);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->sess_key_len = ctx->s2k.key_len;
|
||||
memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* combine
|
||||
*/
|
||||
int
|
||||
pgp_encrypt(PGP_Context * ctx, MBuf * src, MBuf * dst)
|
||||
{
|
||||
int res;
|
||||
int len;
|
||||
uint8 *buf;
|
||||
PushFilter *pf, *pf_tmp;
|
||||
|
||||
/*
|
||||
* do we have any key
|
||||
*/
|
||||
if (!ctx->sym_key && !ctx->pub_key)
|
||||
return PXE_ARGUMENT_ERROR;
|
||||
|
||||
/* MBuf writer */
|
||||
res = pushf_create_mbuf_writer(&pf, dst);
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* initialize symkey
|
||||
*/
|
||||
if (ctx->sym_key)
|
||||
{
|
||||
res = init_s2k_key(ctx);
|
||||
if (res < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = init_sess_key(ctx);
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* write keypkt
|
||||
*/
|
||||
if (ctx->pub_key)
|
||||
res = pgp_write_pubenc_sesskey(ctx, pf);
|
||||
else
|
||||
res = write_symenc_sesskey(ctx, pf);
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
/* encrypted data pkt */
|
||||
res = init_encdata_packet(&pf_tmp, ctx, pf);
|
||||
if (res < 0)
|
||||
goto out;
|
||||
pf = pf_tmp;
|
||||
|
||||
/* encrypter */
|
||||
res = pushf_create(&pf_tmp, &encrypt_filter, ctx, pf);
|
||||
if (res < 0)
|
||||
goto out;
|
||||
pf = pf_tmp;
|
||||
|
||||
/* hasher */
|
||||
if (ctx->disable_mdc == 0)
|
||||
{
|
||||
res = pushf_create(&pf_tmp, &mdc_filter, ctx, pf);
|
||||
if (res < 0)
|
||||
goto out;
|
||||
pf = pf_tmp;
|
||||
}
|
||||
|
||||
/* prefix */
|
||||
res = write_prefix(ctx, pf);
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
/* compressor */
|
||||
if (ctx->compress_algo > 0 && ctx->compress_level > 0)
|
||||
{
|
||||
res = init_compress(&pf_tmp, ctx, pf);
|
||||
if (res < 0)
|
||||
goto out;
|
||||
pf = pf_tmp;
|
||||
}
|
||||
|
||||
/* data streamer */
|
||||
res = init_litdata_packet(&pf_tmp, ctx, pf);
|
||||
if (res < 0)
|
||||
goto out;
|
||||
pf = pf_tmp;
|
||||
|
||||
|
||||
/* text conversion? */
|
||||
if (ctx->text_mode && ctx->convert_crlf)
|
||||
{
|
||||
res = pushf_create(&pf_tmp, &crlf_filter, ctx, pf);
|
||||
if (res < 0)
|
||||
goto out;
|
||||
pf = pf_tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* chain complete
|
||||
*/
|
||||
|
||||
len = mbuf_grab(src, mbuf_avail(src), &buf);
|
||||
res = pushf_write(pf, buf, len);
|
||||
if (res >= 0)
|
||||
res = pushf_flush(pf);
|
||||
out:
|
||||
pushf_free_all(pf);
|
||||
return res;
|
||||
}
|
||||
|
213
contrib/pgcrypto/pgp-info.c
Normal file
213
contrib/pgcrypto/pgp-info.c
Normal file
@ -0,0 +1,213 @@
|
||||
/*
|
||||
* pgp-info.c
|
||||
* Provide info about PGP data.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-info.c,v 1.1 2005/07/10 13:46:28 momjian Exp $
|
||||
*/
|
||||
#include <postgres.h>
|
||||
|
||||
#include "px.h"
|
||||
#include "mbuf.h"
|
||||
#include "pgp.h"
|
||||
|
||||
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;
|
||||
|
||||
res = _pgp_read_public_key(pkt, pk);
|
||||
if (res < 0)
|
||||
goto err;
|
||||
res = pgp_skip_packet(pkt);
|
||||
if (res < 0)
|
||||
goto err;
|
||||
|
||||
res = 0;
|
||||
if (pk->algo == PGP_PUB_ELG_ENCRYPT)
|
||||
{
|
||||
memcpy(keyid_buf, pk->key_id, 8);
|
||||
res = 1;
|
||||
}
|
||||
err:
|
||||
pgp_key_free(pk);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int read_pubenc_keyid(PullFilter *pkt, uint8 *keyid_buf)
|
||||
{
|
||||
uint8 ver;
|
||||
int res;
|
||||
|
||||
GETBYTE(pkt, ver);
|
||||
if (ver != 3)
|
||||
return -1;
|
||||
|
||||
res = pullf_read_fixed(pkt, 8, keyid_buf);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
return pgp_skip_packet(pkt);
|
||||
}
|
||||
|
||||
static const char hextbl[] = "0123456789ABCDEF";
|
||||
|
||||
static int
|
||||
print_key(uint8 *keyid, char *dst)
|
||||
{
|
||||
int i;
|
||||
unsigned c;
|
||||
for (i = 0; i < 8; i++) {
|
||||
c = keyid[i];
|
||||
*dst++ = hextbl[(c >> 4) & 0x0F];
|
||||
*dst++ = hextbl[c & 0x0F];
|
||||
}
|
||||
*dst = 0;
|
||||
return 8*2;
|
||||
}
|
||||
|
||||
static const uint8 any_key[] =
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
/*
|
||||
* dst should have room for 17 bytes
|
||||
*/
|
||||
int
|
||||
pgp_get_keyid(MBuf *pgp_data, char *dst)
|
||||
{
|
||||
int res;
|
||||
PullFilter *src;
|
||||
PullFilter *pkt = NULL;
|
||||
int len;
|
||||
uint8 tag;
|
||||
int got_pub_key=0, got_symenc_key=0, got_pubenc_key=0;
|
||||
int got_data=0;
|
||||
uint8 keyid_buf[8];
|
||||
|
||||
|
||||
res = pullf_create_mbuf_reader(&src, pgp_data);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
while (1) {
|
||||
res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
|
||||
if (res <= 0)
|
||||
break;
|
||||
res = pgp_create_pkt_reader(&pkt, src, len, res, NULL);
|
||||
if (res < 0)
|
||||
break;
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case PGP_PKT_SECRET_KEY:
|
||||
case PGP_PKT_PUBLIC_KEY:
|
||||
case PGP_PKT_SECRET_SUBKEY:
|
||||
case PGP_PKT_PUBLIC_SUBKEY:
|
||||
res = read_pubkey_keyid(pkt, keyid_buf);
|
||||
if (res < 0)
|
||||
break;
|
||||
if (res > 0)
|
||||
got_pub_key++;
|
||||
break;
|
||||
case PGP_PKT_PUBENCRYPTED_SESSKEY:
|
||||
got_pubenc_key++;
|
||||
res = read_pubenc_keyid(pkt, keyid_buf);
|
||||
break;
|
||||
case PGP_PKT_SYMENCRYPTED_DATA:
|
||||
case PGP_PKT_SYMENCRYPTED_DATA_MDC:
|
||||
got_data = 1;
|
||||
break;
|
||||
case PGP_PKT_SYMENCRYPTED_SESSKEY:
|
||||
got_symenc_key++;
|
||||
/* fallthru */
|
||||
case PGP_PKT_SIGNATURE:
|
||||
case PGP_PKT_MARKER:
|
||||
case PGP_PKT_TRUST:
|
||||
case PGP_PKT_USER_ID:
|
||||
case PGP_PKT_USER_ATTR:
|
||||
case PGP_PKT_PRIV_61:
|
||||
res = pgp_skip_packet(pkt);
|
||||
break;
|
||||
default:
|
||||
res = PXE_PGP_CORRUPT_DATA;
|
||||
}
|
||||
|
||||
if (pkt)
|
||||
pullf_free(pkt);
|
||||
pkt = NULL;
|
||||
|
||||
if (res < 0 || got_data)
|
||||
break;
|
||||
}
|
||||
|
||||
pullf_free(src);
|
||||
if (pkt)
|
||||
pullf_free(pkt);
|
||||
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
/* now check sanity */
|
||||
if (got_pub_key && got_pubenc_key)
|
||||
res = PXE_PGP_CORRUPT_DATA;
|
||||
|
||||
if (got_pub_key > 1)
|
||||
res = -1;
|
||||
|
||||
if (got_pubenc_key > 1)
|
||||
res = -1;
|
||||
|
||||
/*
|
||||
* if still ok, look what we got
|
||||
*/
|
||||
if (res >= 0)
|
||||
{
|
||||
if (got_pubenc_key || got_pub_key)
|
||||
{
|
||||
if (memcmp(keyid_buf, any_key, 8) == 0)
|
||||
{
|
||||
memcpy(dst, "ANYKEY", 7);
|
||||
res = 6;
|
||||
}
|
||||
else
|
||||
res = print_key(keyid_buf, dst);
|
||||
}
|
||||
else if (got_symenc_key)
|
||||
{
|
||||
memcpy(dst, "SYMKEY", 7);
|
||||
res = 6;
|
||||
}
|
||||
else
|
||||
res = PXE_PGP_NO_USABLE_KEY;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
50
contrib/pgcrypto/pgp-mpi-internal.c
Normal file
50
contrib/pgcrypto/pgp-mpi-internal.c
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* pgp-mpi-internal.c
|
||||
* OpenPGP MPI functions.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-internal.c,v 1.1 2005/07/10 13:46:28 momjian Exp $
|
||||
*/
|
||||
#include <postgres.h>
|
||||
|
||||
#include "px.h"
|
||||
#include "mbuf.h"
|
||||
#include "pgp.h"
|
||||
|
||||
int
|
||||
pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
|
||||
PGP_MPI **c1_p, PGP_MPI **c2_p)
|
||||
{
|
||||
return PXE_PGP_NO_BIGNUM;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2,
|
||||
PGP_MPI **msg_p)
|
||||
{
|
||||
return PXE_PGP_NO_BIGNUM;
|
||||
}
|
||||
|
197
contrib/pgcrypto/pgp-mpi-openssl.c
Normal file
197
contrib/pgcrypto/pgp-mpi-openssl.c
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* pgp-mpi-openssl.c
|
||||
* OpenPGP MPI functions using OpenSSL BIGNUM code.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-openssl.c,v 1.1 2005/07/10 13:46:29 momjian Exp $
|
||||
*/
|
||||
#include <postgres.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "px.h"
|
||||
#include "mbuf.h"
|
||||
#include "pgp.h"
|
||||
|
||||
static BIGNUM *
|
||||
mpi_to_bn(PGP_MPI *n)
|
||||
{
|
||||
BIGNUM *bn = BN_bin2bn(n->data, n->bytes, NULL);
|
||||
if (!bn)
|
||||
return NULL;
|
||||
if (BN_num_bits(bn) != n->bits)
|
||||
{
|
||||
px_debug("mpi_to_bn: bignum conversion failed: mpi=%d, bn=%d",
|
||||
n->bits, BN_num_bits(bn));
|
||||
BN_clear_free(bn);
|
||||
return NULL;
|
||||
}
|
||||
return bn;
|
||||
}
|
||||
|
||||
static PGP_MPI *
|
||||
bn_to_mpi(BIGNUM *bn)
|
||||
{
|
||||
int res;
|
||||
PGP_MPI *n;
|
||||
|
||||
res = pgp_mpi_alloc(BN_num_bits(bn), &n);
|
||||
if (res < 0)
|
||||
return NULL;
|
||||
|
||||
if (BN_num_bytes(bn) != n->bytes)
|
||||
{
|
||||
px_debug("bn_to_mpi: bignum conversion failed: bn=%d, mpi=%d",
|
||||
BN_num_bytes(bn), n->bytes);
|
||||
pgp_mpi_free(n);
|
||||
return NULL;
|
||||
}
|
||||
BN_bn2bin(bn, n->data);
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decide the number of bits in the random componont k
|
||||
*
|
||||
* It should be in the same range as p for signing (which
|
||||
* is deprecated), but can be much smaller for encrypting.
|
||||
*
|
||||
* Until I research it further, I just mimic gpg behaviour.
|
||||
* It has a special mapping table, for values <= 5120,
|
||||
* above that it uses 'arbitrary high number'. Following
|
||||
* algorihm hovers 10-70 bits above gpg values. And for
|
||||
* larger p, it uses gpg's algorihm.
|
||||
*
|
||||
* The point is - if k gets large, encryption will be
|
||||
* really slow. It does not matter for decryption.
|
||||
*/
|
||||
static int
|
||||
decide_k_bits(int p_bits)
|
||||
{
|
||||
if (p_bits <= 5120)
|
||||
return p_bits / 10 + 160;
|
||||
else
|
||||
return (p_bits / 8 + 200) * 3 / 2;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
|
||||
PGP_MPI **c1_p, PGP_MPI **c2_p)
|
||||
{
|
||||
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 *k = BN_new();
|
||||
BIGNUM *yk = BN_new();
|
||||
BIGNUM *c1 = BN_new();
|
||||
BIGNUM *c2 = BN_new();
|
||||
BN_CTX *tmp = BN_CTX_new();
|
||||
|
||||
if (!m || !p || !g || !y || !k || !yk || !c1 || !c2 || !tmp)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* generate k
|
||||
*/
|
||||
k_bits = decide_k_bits(BN_num_bits(p));
|
||||
if (!BN_generate_prime(k, k_bits, 0, NULL, NULL, NULL, NULL))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* c1 = g^k
|
||||
* c2 = m * y^k
|
||||
*/
|
||||
if (!BN_mod_exp(c1, g, k, p, tmp))
|
||||
goto err;
|
||||
if (!BN_mod_exp(yk, y, k, p, tmp))
|
||||
goto err;
|
||||
if (!BN_mod_mul(c2, m, yk, p, tmp))
|
||||
goto err;
|
||||
|
||||
/* result */
|
||||
*c1_p = bn_to_mpi(c1);
|
||||
*c2_p = bn_to_mpi(c2);
|
||||
if (*c1_p && *c2_p)
|
||||
res = 0;
|
||||
err:
|
||||
if (tmp) BN_CTX_free(tmp);
|
||||
if (c2) BN_clear_free(c2);
|
||||
if (c1) BN_clear_free(c1);
|
||||
if (yk) BN_clear_free(yk);
|
||||
if (k) BN_clear_free(k);
|
||||
if (y) BN_clear_free(y);
|
||||
if (g) BN_clear_free(g);
|
||||
if (p) BN_clear_free(p);
|
||||
if (m) BN_clear_free(m);
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2,
|
||||
PGP_MPI **msg_p)
|
||||
{
|
||||
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 *c1x = BN_new();
|
||||
BIGNUM *div = BN_new();
|
||||
BIGNUM *m = BN_new();
|
||||
BN_CTX *tmp = BN_CTX_new();
|
||||
|
||||
if (!c1 || !c2 || !p || !x || !c1x || !div || !m || !tmp)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* m = c2 / (c1^x)
|
||||
*/
|
||||
if (!BN_mod_exp(c1x, c1, x, p, tmp))
|
||||
goto err;
|
||||
if (!BN_mod_inverse(div, c1x, p, tmp))
|
||||
goto err;
|
||||
if (!BN_mod_mul(m, c2, div, p, tmp))
|
||||
goto err;
|
||||
|
||||
/* result */
|
||||
*msg_p = bn_to_mpi(m);
|
||||
if (*msg_p)
|
||||
res = 0;
|
||||
err:
|
||||
if (tmp) BN_CTX_free(tmp);
|
||||
if (m) BN_clear_free(m);
|
||||
if (div) BN_clear_free(div);
|
||||
if (c1x) BN_clear_free(c1x);
|
||||
if (x) BN_clear_free(x);
|
||||
if (p) BN_clear_free(p);
|
||||
if (c2) BN_clear_free(c2);
|
||||
if (c1) BN_clear_free(c1);
|
||||
return res;
|
||||
}
|
||||
|
134
contrib/pgcrypto/pgp-mpi.c
Normal file
134
contrib/pgcrypto/pgp-mpi.c
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* pgp-mpi.c
|
||||
* OpenPGP MPI helper functions.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi.c,v 1.1 2005/07/10 13:46:29 momjian Exp $
|
||||
*/
|
||||
#include <postgres.h>
|
||||
|
||||
#include "px.h"
|
||||
#include "mbuf.h"
|
||||
#include "pgp.h"
|
||||
|
||||
int pgp_mpi_alloc(int bits, PGP_MPI **mpi)
|
||||
{
|
||||
PGP_MPI *n;
|
||||
int len = (bits + 7) / 8;
|
||||
if (bits < 0 || bits > 0xFFFF)
|
||||
{
|
||||
px_debug("pgp_mpi_alloc: unreasonable request: bits=%d", bits);
|
||||
return PXE_PGP_CORRUPT_DATA;
|
||||
}
|
||||
n = px_alloc(sizeof(*n) + len);
|
||||
n->bits = bits;
|
||||
n->bytes = len;
|
||||
n->data = (uint8*)(n) + sizeof(*n);
|
||||
*mpi = n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pgp_mpi_create(uint8 *data, int bits, PGP_MPI **mpi)
|
||||
{
|
||||
int res;
|
||||
PGP_MPI *n;
|
||||
|
||||
res = pgp_mpi_alloc(bits, &n);
|
||||
if (res < 0)
|
||||
return res;
|
||||
memcpy(n->data, data, n->bytes);
|
||||
*mpi = n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pgp_mpi_free(PGP_MPI *mpi)
|
||||
{
|
||||
memset(mpi, 0, sizeof(*mpi) + mpi->bytes);
|
||||
px_free(mpi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pgp_mpi_read(PullFilter *src, PGP_MPI **mpi)
|
||||
{
|
||||
int res;
|
||||
uint8 hdr[2];
|
||||
int bits;
|
||||
PGP_MPI *n;
|
||||
|
||||
res = pullf_read_fixed(src, 2, hdr);
|
||||
if (res < 0)
|
||||
return res;
|
||||
bits = ((unsigned)hdr[0] << 8) + hdr[1];
|
||||
|
||||
res = pgp_mpi_alloc(bits, &n);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = pullf_read_fixed(src, n->bytes, n->data);
|
||||
if (res < 0)
|
||||
pgp_mpi_free(n);
|
||||
else
|
||||
*mpi = n;
|
||||
return res;
|
||||
}
|
||||
|
||||
int pgp_mpi_write(PushFilter *dst, PGP_MPI *n)
|
||||
{
|
||||
int res;
|
||||
uint8 buf[2];
|
||||
|
||||
buf[0] = n->bits >> 8;
|
||||
buf[1] = n->bits & 0xFF;
|
||||
res = pushf_write(dst, buf, 2);
|
||||
if (res >= 0)
|
||||
res = pushf_write(dst, n->data, n->bytes);
|
||||
return res;
|
||||
}
|
||||
|
||||
int pgp_mpi_hash(PX_MD *md, PGP_MPI *n)
|
||||
{
|
||||
uint8 buf[2];
|
||||
|
||||
buf[0] = n->bits >> 8;
|
||||
buf[1] = n->bits & 0xFF;
|
||||
px_md_update(md, buf, 2);
|
||||
px_md_update(md, n->data, n->bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned pgp_mpi_cksum(unsigned cksum, PGP_MPI *n)
|
||||
{
|
||||
int i;
|
||||
|
||||
cksum += n->bits >> 8;
|
||||
cksum += n->bits & 0xFF;
|
||||
for (i = 0; i < n->bytes; i++)
|
||||
cksum += n->data[i];
|
||||
|
||||
return cksum;
|
||||
}
|
||||
|
901
contrib/pgcrypto/pgp-pgsql.c
Normal file
901
contrib/pgcrypto/pgp-pgsql.c
Normal file
@ -0,0 +1,901 @@
|
||||
/*
|
||||
* pgp-pgsql.c
|
||||
* PostgreSQL wrappers for pgp.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pgsql.c,v 1.1 2005/07/10 13:46:29 momjian Exp $
|
||||
*/
|
||||
|
||||
#include <postgres.h>
|
||||
#include <fmgr.h>
|
||||
#include <parser/scansup.h>
|
||||
#include <mb/pg_wchar.h>
|
||||
|
||||
#include "mbuf.h"
|
||||
#include "px.h"
|
||||
#include "pgp.h"
|
||||
|
||||
/*
|
||||
* public functions
|
||||
*/
|
||||
Datum pgp_sym_encrypt_text(PG_FUNCTION_ARGS);
|
||||
Datum pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS);
|
||||
Datum pgp_sym_decrypt_text(PG_FUNCTION_ARGS);
|
||||
Datum pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum pgp_pub_encrypt_text(PG_FUNCTION_ARGS);
|
||||
Datum pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS);
|
||||
Datum pgp_pub_decrypt_text(PG_FUNCTION_ARGS);
|
||||
Datum pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum pgp_key_id_w(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum pg_armor(PG_FUNCTION_ARGS);
|
||||
Datum pg_dearmor(PG_FUNCTION_ARGS);
|
||||
|
||||
/* function headers */
|
||||
|
||||
PG_FUNCTION_INFO_V1(pgp_sym_encrypt_bytea);
|
||||
PG_FUNCTION_INFO_V1(pgp_sym_encrypt_text);
|
||||
PG_FUNCTION_INFO_V1(pgp_sym_decrypt_bytea);
|
||||
PG_FUNCTION_INFO_V1(pgp_sym_decrypt_text);
|
||||
|
||||
PG_FUNCTION_INFO_V1(pgp_pub_encrypt_bytea);
|
||||
PG_FUNCTION_INFO_V1(pgp_pub_encrypt_text);
|
||||
PG_FUNCTION_INFO_V1(pgp_pub_decrypt_bytea);
|
||||
PG_FUNCTION_INFO_V1(pgp_pub_decrypt_text);
|
||||
|
||||
PG_FUNCTION_INFO_V1(pgp_key_id_w);
|
||||
|
||||
PG_FUNCTION_INFO_V1(pg_armor);
|
||||
PG_FUNCTION_INFO_V1(pg_dearmor);
|
||||
|
||||
/*
|
||||
* check for NULL arguments
|
||||
*/
|
||||
#define CHECK_ARGS() \
|
||||
do { \
|
||||
int a; \
|
||||
for (a = 0; a < PG_NARGS(); a++) { \
|
||||
if (PG_ARGISNULL(a)) \
|
||||
PG_RETURN_NULL(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Mix user data into RNG. It is for user own interests to have
|
||||
* RNG state shuffled.
|
||||
*/
|
||||
static void add_entropy(text *data1, text *data2, text *data3)
|
||||
{
|
||||
PX_MD *md;
|
||||
uint8 sha1[20];
|
||||
int res;
|
||||
|
||||
if (!data1 && !data2 && !data3)
|
||||
return;
|
||||
|
||||
res = px_find_digest("sha1", &md);
|
||||
if (res < 0)
|
||||
return;
|
||||
|
||||
if (data1)
|
||||
px_md_update(md, VARDATA(data1), VARSIZE(data1) - VARHDRSZ);
|
||||
if (data2)
|
||||
px_md_update(md, VARDATA(data2), VARSIZE(data2) - VARHDRSZ);
|
||||
if (data3)
|
||||
px_md_update(md, VARDATA(data3), VARSIZE(data3) - VARHDRSZ);
|
||||
|
||||
px_md_finish(md, sha1);
|
||||
px_md_free(md);
|
||||
|
||||
res = px_add_entropy(sha1, 20);
|
||||
memset(sha1, 0, 20);
|
||||
|
||||
if (res < 0)
|
||||
ereport(NOTICE, (errmsg("add_entropy: %s", px_strerror(res))));
|
||||
}
|
||||
|
||||
/*
|
||||
* returns src in case of no conversion or error
|
||||
*/
|
||||
static text *convert_charset(text *src, int cset_from, int cset_to)
|
||||
{
|
||||
int src_len = VARSIZE(src) - VARHDRSZ;
|
||||
int dst_len;
|
||||
unsigned char *dst;
|
||||
unsigned char *csrc = VARDATA(src);
|
||||
text *res;
|
||||
|
||||
dst = pg_do_encoding_conversion(csrc, src_len, cset_from, cset_to);
|
||||
if (dst == csrc)
|
||||
return src;
|
||||
|
||||
dst_len = strlen(dst);
|
||||
res = palloc(dst_len + VARHDRSZ);
|
||||
memcpy(VARDATA(res), dst, dst_len);
|
||||
VARATT_SIZEP(res) = VARHDRSZ + dst_len;
|
||||
pfree(dst);
|
||||
return res;
|
||||
}
|
||||
|
||||
static text *convert_from_utf8(text *src)
|
||||
{
|
||||
return convert_charset(src, PG_UTF8, GetDatabaseEncoding());
|
||||
}
|
||||
|
||||
static text *convert_to_utf8(text *src)
|
||||
{
|
||||
return convert_charset(src, GetDatabaseEncoding(), PG_UTF8);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_and_pfree(text *p)
|
||||
{
|
||||
memset(p, 0, VARSIZE(p));
|
||||
pfree(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* expect-* arguments storage
|
||||
*/
|
||||
struct debug_expect {
|
||||
int debug;
|
||||
int expect;
|
||||
int cipher_algo;
|
||||
int s2k_mode;
|
||||
int s2k_cipher_algo;
|
||||
int s2k_digest_algo;
|
||||
int compress_algo;
|
||||
int use_sess_key;
|
||||
int disable_mdc;
|
||||
int unicode_mode;
|
||||
};
|
||||
|
||||
static void fill_expect(struct debug_expect *ex, int text_mode)
|
||||
{
|
||||
ex->debug = 0;
|
||||
ex->expect = 0;
|
||||
ex->cipher_algo = -1;
|
||||
ex->s2k_mode = -1;
|
||||
ex->s2k_cipher_algo = -1;
|
||||
ex->s2k_digest_algo = -1;
|
||||
ex->compress_algo = -1;
|
||||
ex->use_sess_key = -1;
|
||||
ex->disable_mdc = -1;
|
||||
ex->unicode_mode = -1;
|
||||
}
|
||||
|
||||
#define EX_MSG(arg) \
|
||||
ereport(NOTICE, (errmsg( \
|
||||
"pgp_decrypt: unexpected %s: expected %d got %d", \
|
||||
CppAsString(arg), ex->arg, ctx->arg)))
|
||||
|
||||
#define EX_CHECK(arg) do { \
|
||||
if (ex->arg >= 0 && ex->arg != ctx->arg) EX_MSG(arg); \
|
||||
} while (0)
|
||||
|
||||
static void check_expect(PGP_Context *ctx, struct debug_expect *ex)
|
||||
{
|
||||
EX_CHECK(cipher_algo);
|
||||
EX_CHECK(s2k_mode);
|
||||
EX_CHECK(s2k_digest_algo);
|
||||
EX_CHECK(use_sess_key);
|
||||
if (ctx->use_sess_key)
|
||||
EX_CHECK(s2k_cipher_algo);
|
||||
EX_CHECK(disable_mdc);
|
||||
EX_CHECK(compress_algo);
|
||||
EX_CHECK(unicode_mode);
|
||||
}
|
||||
|
||||
static void show_debug(const char *msg)
|
||||
{
|
||||
ereport(NOTICE, (errmsg("dbg: %s", msg)));
|
||||
}
|
||||
|
||||
static int set_arg(PGP_Context *ctx, char *key, char*val,
|
||||
struct debug_expect *ex)
|
||||
{
|
||||
int res = 0;
|
||||
if (strcmp(key, "cipher-algo") == 0)
|
||||
res = pgp_set_cipher_algo(ctx, val);
|
||||
else if (strcmp(key, "disable-mdc") == 0)
|
||||
res = pgp_disable_mdc(ctx, atoi(val));
|
||||
else if (strcmp(key, "sess-key") == 0)
|
||||
res = pgp_set_sess_key(ctx, atoi(val));
|
||||
else if (strcmp(key, "s2k-mode") == 0)
|
||||
res = pgp_set_s2k_mode(ctx, atoi(val));
|
||||
else if (strcmp(key, "s2k-digest-algo") == 0)
|
||||
res = pgp_set_s2k_digest_algo(ctx, val);
|
||||
else if (strcmp(key, "s2k-cipher-algo") == 0)
|
||||
res = pgp_set_s2k_cipher_algo(ctx, val);
|
||||
else if (strcmp(key, "compress-algo") == 0)
|
||||
res = pgp_set_compress_algo(ctx, atoi(val));
|
||||
else if (strcmp(key, "compress-level") == 0)
|
||||
res = pgp_set_compress_level(ctx, atoi(val));
|
||||
else if (strcmp(key, "convert-crlf") == 0)
|
||||
res = pgp_set_convert_crlf(ctx, atoi(val));
|
||||
else if (strcmp(key, "unicode-mode") == 0)
|
||||
res = pgp_set_unicode_mode(ctx, atoi(val));
|
||||
/* decrypt debug */
|
||||
else if (ex != NULL && strcmp(key, "debug") == 0)
|
||||
ex->debug = atoi(val);
|
||||
else if (ex != NULL && strcmp(key, "expect-cipher-algo") == 0)
|
||||
{
|
||||
ex->expect = 1;
|
||||
ex->cipher_algo = pgp_get_cipher_code(val);
|
||||
}
|
||||
else if (ex != NULL && strcmp(key, "expect-disable-mdc") == 0)
|
||||
{
|
||||
ex->expect = 1;
|
||||
ex->disable_mdc = atoi(val);
|
||||
}
|
||||
else if (ex != NULL && strcmp(key, "expect-sess-key") == 0)
|
||||
{
|
||||
ex->expect = 1;
|
||||
ex->use_sess_key = atoi(val);
|
||||
}
|
||||
else if (ex != NULL && strcmp(key, "expect-s2k-mode") == 0)
|
||||
{
|
||||
ex->expect = 1;
|
||||
ex->s2k_mode = atoi(val);
|
||||
}
|
||||
else if (ex != NULL && strcmp(key, "expect-s2k-digest-algo") == 0)
|
||||
{
|
||||
ex->expect = 1;
|
||||
ex->s2k_digest_algo = pgp_get_digest_code(val);
|
||||
}
|
||||
else if (ex != NULL && strcmp(key, "expect-s2k-cipher-algo") == 0)
|
||||
{
|
||||
ex->expect = 1;
|
||||
ex->s2k_cipher_algo = pgp_get_cipher_code(val);
|
||||
}
|
||||
else if (ex != NULL && strcmp(key, "expect-compress-algo") == 0)
|
||||
{
|
||||
ex->expect = 1;
|
||||
ex->compress_algo = atoi(val);
|
||||
}
|
||||
else if (ex != NULL && strcmp(key, "expect-unicode-mode") == 0)
|
||||
{
|
||||
ex->expect = 1;
|
||||
ex->unicode_mode = atoi(val);
|
||||
}
|
||||
else
|
||||
res = PXE_ARGUMENT_ERROR;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find next word. Handle ',' and '=' as words. Skip whitespace.
|
||||
* Put word info into res_p, res_len.
|
||||
* Returns ptr to next word.
|
||||
*/
|
||||
static char *getword(char *p, char **res_p, int *res_len)
|
||||
{
|
||||
/* whitespace at start */
|
||||
while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
|
||||
p++;
|
||||
|
||||
/* word data */
|
||||
*res_p = p;
|
||||
if (*p == '=' || *p == ',')
|
||||
p++;
|
||||
else
|
||||
while (*p && !(*p == ' ' || *p == '\t' || *p == '\n'
|
||||
|| *p == '=' || *p == ','))
|
||||
p++;
|
||||
|
||||
/* word end */
|
||||
*res_len = p - *res_p;
|
||||
|
||||
/* whitespace at end */
|
||||
while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
|
||||
p++;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert to lowercase asciiz string.
|
||||
*/
|
||||
static char *downcase_convert(const uint8 *s, int len)
|
||||
{
|
||||
int c, i;
|
||||
char *res = palloc(len + 1);
|
||||
for (i = 0; i < len; i++) {
|
||||
c = s[i];
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
c += 'a' - 'A';
|
||||
res[i] = c;
|
||||
}
|
||||
res[len] = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int parse_args(PGP_Context *ctx, uint8 *args, int arg_len,
|
||||
struct debug_expect *ex)
|
||||
{
|
||||
char *str = downcase_convert(args, arg_len);
|
||||
char *key, *val;
|
||||
int key_len, val_len;
|
||||
int res = 0;
|
||||
char *p = str;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
res = PXE_ARGUMENT_ERROR;
|
||||
p = getword(p, &key, &key_len);
|
||||
if (*p++ != '=')
|
||||
break;
|
||||
p = getword(p, &val, &val_len);
|
||||
if (*p == '\0')
|
||||
;
|
||||
else if (*p++ != ',')
|
||||
break;
|
||||
|
||||
if (*key == 0 || *val == 0 || val_len == 0)
|
||||
break;
|
||||
|
||||
key[key_len] = 0;
|
||||
val[val_len] = 0;
|
||||
|
||||
res = set_arg(ctx, key, val, ex);
|
||||
if (res < 0)
|
||||
break;
|
||||
}
|
||||
pfree(str);
|
||||
return res;
|
||||
}
|
||||
|
||||
static MBuf *
|
||||
create_mbuf_from_vardata(text *data)
|
||||
{
|
||||
return mbuf_create_from_data(VARDATA(data), VARSIZE(data) - VARHDRSZ);
|
||||
}
|
||||
|
||||
static void
|
||||
init_work(PGP_Context **ctx_p, int is_text,
|
||||
text *args, struct debug_expect *ex)
|
||||
{
|
||||
int err = pgp_init(ctx_p);
|
||||
|
||||
fill_expect(ex, is_text);
|
||||
|
||||
if (err == 0 && args != NULL)
|
||||
err = parse_args(*ctx_p, VARDATA(args), VARSIZE(args) - VARHDRSZ, ex);
|
||||
|
||||
if (err)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("%s", px_strerror(err))));
|
||||
}
|
||||
|
||||
if (ex->debug)
|
||||
px_set_debug_handler(show_debug);
|
||||
|
||||
pgp_set_text_mode(*ctx_p, is_text);
|
||||
}
|
||||
|
||||
static bytea *
|
||||
encrypt_internal(int is_pubenc, int is_text,
|
||||
text *data, text *key, text *args)
|
||||
{
|
||||
MBuf *src, *dst;
|
||||
uint8 tmp[VARHDRSZ];
|
||||
uint8 *restmp;
|
||||
bytea *res;
|
||||
int res_len;
|
||||
PGP_Context *ctx;
|
||||
int err;
|
||||
struct debug_expect ex;
|
||||
text *tmp_data = NULL;
|
||||
|
||||
/*
|
||||
* Add data and key info RNG.
|
||||
*/
|
||||
add_entropy(data, key, NULL);
|
||||
|
||||
init_work(&ctx, is_text, args, &ex);
|
||||
|
||||
if (is_text && pgp_get_unicode_mode(ctx))
|
||||
{
|
||||
tmp_data = convert_to_utf8(data);
|
||||
if (tmp_data == data)
|
||||
tmp_data = NULL;
|
||||
else
|
||||
data = tmp_data;
|
||||
}
|
||||
|
||||
src = create_mbuf_from_vardata(data);
|
||||
dst = mbuf_create(VARSIZE(data) + 128);
|
||||
|
||||
/*
|
||||
* reserve room for header
|
||||
*/
|
||||
mbuf_append(dst, tmp, VARHDRSZ);
|
||||
|
||||
/*
|
||||
* set key
|
||||
*/
|
||||
if (is_pubenc)
|
||||
{
|
||||
MBuf *kbuf = create_mbuf_from_vardata(key);
|
||||
err = pgp_set_pubkey(ctx, kbuf,
|
||||
NULL, 0, 0);
|
||||
mbuf_free(kbuf);
|
||||
}
|
||||
else
|
||||
err = pgp_set_symkey(ctx, VARDATA(key), VARSIZE(key) - VARHDRSZ);
|
||||
|
||||
/*
|
||||
* encrypt
|
||||
*/
|
||||
if (err >= 0)
|
||||
err = pgp_encrypt(ctx, src, dst);
|
||||
|
||||
/*
|
||||
* check for error
|
||||
*/
|
||||
if (err)
|
||||
{
|
||||
if (ex.debug)
|
||||
px_set_debug_handler(NULL);
|
||||
if (tmp_data)
|
||||
clear_and_pfree(tmp_data);
|
||||
pgp_free(ctx);
|
||||
mbuf_free(src);
|
||||
mbuf_free(dst);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("pgp_encrypt error: %s", px_strerror(err))));
|
||||
}
|
||||
|
||||
/* res_len includes VARHDRSZ */
|
||||
res_len = mbuf_steal_data(dst, &restmp);
|
||||
res = (bytea *) restmp;
|
||||
VARATT_SIZEP(res) = res_len;
|
||||
|
||||
if (tmp_data)
|
||||
clear_and_pfree(tmp_data);
|
||||
pgp_free(ctx);
|
||||
mbuf_free(src);
|
||||
mbuf_free(dst);
|
||||
|
||||
px_set_debug_handler(NULL);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static bytea *
|
||||
decrypt_internal(int is_pubenc, int need_text, text *data,
|
||||
text *key, text *keypsw, text *args)
|
||||
{
|
||||
int err;
|
||||
MBuf *src = NULL, *dst = NULL;
|
||||
uint8 tmp[VARHDRSZ];
|
||||
uint8 *restmp;
|
||||
bytea *res;
|
||||
int res_len;
|
||||
PGP_Context *ctx = NULL;
|
||||
struct debug_expect ex;
|
||||
int got_unicode = 0;
|
||||
|
||||
|
||||
init_work(&ctx, need_text, args, &ex);
|
||||
|
||||
src = mbuf_create_from_data(VARDATA(data), VARSIZE(data) - VARHDRSZ);
|
||||
dst = mbuf_create(VARSIZE(data) + 2048);
|
||||
|
||||
/*
|
||||
* reserve room for header
|
||||
*/
|
||||
mbuf_append(dst, tmp, VARHDRSZ);
|
||||
|
||||
/*
|
||||
* set key
|
||||
*/
|
||||
if (is_pubenc)
|
||||
{
|
||||
uint8 *psw = NULL;
|
||||
int psw_len = 0;
|
||||
MBuf *kbuf;
|
||||
if (keypsw)
|
||||
{
|
||||
psw = VARDATA(keypsw);
|
||||
psw_len = VARSIZE(keypsw) - VARHDRSZ;
|
||||
}
|
||||
kbuf = create_mbuf_from_vardata(key);
|
||||
err = pgp_set_pubkey(ctx, kbuf, psw, psw_len, 1);
|
||||
mbuf_free(kbuf);
|
||||
}
|
||||
else
|
||||
err = pgp_set_symkey(ctx, VARDATA(key), VARSIZE(key) - VARHDRSZ);
|
||||
|
||||
/*
|
||||
* decrypt
|
||||
*/
|
||||
if (err >= 0)
|
||||
err = pgp_decrypt(ctx, src, dst);
|
||||
|
||||
/*
|
||||
* failed?
|
||||
*/
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
if (ex.expect)
|
||||
check_expect(ctx, &ex);
|
||||
|
||||
/* remember the setting */
|
||||
got_unicode = pgp_get_unicode_mode(ctx);
|
||||
|
||||
out:
|
||||
if (src)
|
||||
mbuf_free(src);
|
||||
if (ctx)
|
||||
pgp_free(ctx);
|
||||
|
||||
if (err)
|
||||
{
|
||||
px_set_debug_handler(NULL);
|
||||
if (dst)
|
||||
mbuf_free(dst);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("pgp_decrypt error: %s", px_strerror(err))));
|
||||
}
|
||||
|
||||
res_len = mbuf_steal_data(dst, &restmp);
|
||||
mbuf_free(dst);
|
||||
|
||||
/* res_len includes VARHDRSZ */
|
||||
res = (bytea *) restmp;
|
||||
VARATT_SIZEP(res) = res_len;
|
||||
|
||||
if (need_text && got_unicode)
|
||||
{
|
||||
text *utf = convert_from_utf8(res);
|
||||
if (utf != res)
|
||||
{
|
||||
clear_and_pfree(res);
|
||||
res = utf;
|
||||
}
|
||||
}
|
||||
px_set_debug_handler(NULL);
|
||||
|
||||
/*
|
||||
* add successfull decryptions also into RNG
|
||||
*/
|
||||
add_entropy(res, key, keypsw);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrappers for symmetric-key functions
|
||||
*/
|
||||
Datum
|
||||
pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *data,
|
||||
*key;
|
||||
text *arg = NULL;
|
||||
text *res;
|
||||
|
||||
CHECK_ARGS();
|
||||
data = PG_GETARG_BYTEA_P(0);
|
||||
key = PG_GETARG_BYTEA_P(1);
|
||||
if (PG_NARGS() > 2)
|
||||
arg = PG_GETARG_BYTEA_P(2);
|
||||
|
||||
res = encrypt_internal(0, 0, data, key, arg);
|
||||
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
if (PG_NARGS() > 2)
|
||||
PG_FREE_IF_COPY(arg, 2);
|
||||
PG_RETURN_TEXT_P(res);
|
||||
}
|
||||
|
||||
Datum
|
||||
pgp_sym_encrypt_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *data,
|
||||
*key;
|
||||
text *arg = NULL;
|
||||
text *res;
|
||||
|
||||
CHECK_ARGS();
|
||||
data = PG_GETARG_BYTEA_P(0);
|
||||
key = PG_GETARG_BYTEA_P(1);
|
||||
if (PG_NARGS() > 2)
|
||||
arg = PG_GETARG_BYTEA_P(2);
|
||||
|
||||
res = encrypt_internal(0, 1, data, key, arg);
|
||||
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
if (PG_NARGS() > 2)
|
||||
PG_FREE_IF_COPY(arg, 2);
|
||||
PG_RETURN_TEXT_P(res);
|
||||
}
|
||||
|
||||
|
||||
Datum
|
||||
pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *data,
|
||||
*key;
|
||||
text *arg = NULL;
|
||||
text *res;
|
||||
|
||||
CHECK_ARGS();
|
||||
data = PG_GETARG_BYTEA_P(0);
|
||||
key = PG_GETARG_BYTEA_P(1);
|
||||
if (PG_NARGS() > 2)
|
||||
arg = PG_GETARG_BYTEA_P(2);
|
||||
|
||||
res = decrypt_internal(0, 0, data, key, NULL, arg);
|
||||
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
if (PG_NARGS() > 2)
|
||||
PG_FREE_IF_COPY(arg, 2);
|
||||
PG_RETURN_TEXT_P(res);
|
||||
}
|
||||
|
||||
Datum
|
||||
pgp_sym_decrypt_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *data,
|
||||
*key;
|
||||
text *arg = NULL;
|
||||
text *res;
|
||||
|
||||
CHECK_ARGS();
|
||||
data = PG_GETARG_BYTEA_P(0);
|
||||
key = PG_GETARG_BYTEA_P(1);
|
||||
if (PG_NARGS() > 2)
|
||||
arg = PG_GETARG_BYTEA_P(2);
|
||||
|
||||
res = decrypt_internal(0, 1, data, key, NULL, arg);
|
||||
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
if (PG_NARGS() > 2)
|
||||
PG_FREE_IF_COPY(arg, 2);
|
||||
PG_RETURN_TEXT_P(res);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrappers for public-key functions
|
||||
*/
|
||||
|
||||
Datum
|
||||
pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *data,
|
||||
*key;
|
||||
text *arg = NULL;
|
||||
text *res;
|
||||
|
||||
CHECK_ARGS();
|
||||
data = PG_GETARG_BYTEA_P(0);
|
||||
key = PG_GETARG_BYTEA_P(1);
|
||||
if (PG_NARGS() > 2)
|
||||
arg = PG_GETARG_BYTEA_P(2);
|
||||
|
||||
res = encrypt_internal(1, 0, data, key, arg);
|
||||
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
if (PG_NARGS() > 2)
|
||||
PG_FREE_IF_COPY(arg, 2);
|
||||
PG_RETURN_TEXT_P(res);
|
||||
}
|
||||
|
||||
Datum
|
||||
pgp_pub_encrypt_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *data,
|
||||
*key;
|
||||
text *arg = NULL;
|
||||
text *res;
|
||||
|
||||
CHECK_ARGS();
|
||||
data = PG_GETARG_BYTEA_P(0);
|
||||
key = PG_GETARG_BYTEA_P(1);
|
||||
if (PG_NARGS() > 2)
|
||||
arg = PG_GETARG_BYTEA_P(2);
|
||||
|
||||
res = encrypt_internal(1, 1, data, key, arg);
|
||||
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
if (PG_NARGS() > 2)
|
||||
PG_FREE_IF_COPY(arg, 2);
|
||||
PG_RETURN_TEXT_P(res);
|
||||
}
|
||||
|
||||
|
||||
Datum
|
||||
pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *data,
|
||||
*key;
|
||||
text *psw = NULL,
|
||||
*arg = NULL;
|
||||
text *res;
|
||||
|
||||
CHECK_ARGS();
|
||||
data = PG_GETARG_BYTEA_P(0);
|
||||
key = PG_GETARG_BYTEA_P(1);
|
||||
if (PG_NARGS() > 2)
|
||||
psw = PG_GETARG_BYTEA_P(2);
|
||||
if (PG_NARGS() > 3)
|
||||
arg = PG_GETARG_BYTEA_P(3);
|
||||
|
||||
res = decrypt_internal(1, 0, data, key, psw, arg);
|
||||
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
if (PG_NARGS() > 2)
|
||||
PG_FREE_IF_COPY(psw, 2);
|
||||
if (PG_NARGS() > 3)
|
||||
PG_FREE_IF_COPY(arg, 3);
|
||||
PG_RETURN_TEXT_P(res);
|
||||
}
|
||||
|
||||
Datum
|
||||
pgp_pub_decrypt_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *data,
|
||||
*key;
|
||||
text *psw = NULL,
|
||||
*arg = NULL;
|
||||
text *res;
|
||||
|
||||
CHECK_ARGS();
|
||||
data = PG_GETARG_BYTEA_P(0);
|
||||
key = PG_GETARG_BYTEA_P(1);
|
||||
if (PG_NARGS() > 2)
|
||||
psw = PG_GETARG_BYTEA_P(2);
|
||||
if (PG_NARGS() > 3)
|
||||
arg = PG_GETARG_BYTEA_P(3);
|
||||
|
||||
res = decrypt_internal(1, 1, data, key, psw, arg);
|
||||
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_FREE_IF_COPY(key, 1);
|
||||
if (PG_NARGS() > 2)
|
||||
PG_FREE_IF_COPY(psw, 2);
|
||||
if (PG_NARGS() > 3)
|
||||
PG_FREE_IF_COPY(arg, 3);
|
||||
PG_RETURN_TEXT_P(res);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrappers for PGP ascii armor
|
||||
*/
|
||||
|
||||
Datum
|
||||
pg_armor(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *data;
|
||||
text *res;
|
||||
int data_len,
|
||||
res_len,
|
||||
guess_len;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
data = PG_GETARG_BYTEA_P(0);
|
||||
data_len = VARSIZE(data) - VARHDRSZ;
|
||||
|
||||
guess_len = pgp_armor_enc_len(data_len);
|
||||
res = palloc(VARHDRSZ + guess_len);
|
||||
|
||||
res_len = pgp_armor_encode(VARDATA(data), data_len, VARDATA(res));
|
||||
if (res_len > guess_len)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("Overflow - encode estimate too small")));
|
||||
VARATT_SIZEP(res) = VARHDRSZ + res_len;
|
||||
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_RETURN_TEXT_P(res);
|
||||
}
|
||||
|
||||
Datum
|
||||
pg_dearmor(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *data;
|
||||
bytea *res;
|
||||
int data_len,
|
||||
res_len,
|
||||
guess_len;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
data = PG_GETARG_TEXT_P(0);
|
||||
data_len = VARSIZE(data) - VARHDRSZ;
|
||||
|
||||
guess_len = pgp_armor_dec_len(data_len);
|
||||
res = palloc(VARHDRSZ + guess_len);
|
||||
|
||||
res_len = pgp_armor_decode(VARDATA(data), data_len, VARDATA(res));
|
||||
if (res_len < 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("dearmor: %s", px_strerror(res_len))));
|
||||
if (res_len > guess_len)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("Overflow - decode estimate too small")));
|
||||
VARATT_SIZEP(res) = VARHDRSZ + res_len;
|
||||
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_RETURN_TEXT_P(res);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrappers for PGP key id
|
||||
*/
|
||||
|
||||
Datum
|
||||
pgp_key_id_w(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *data;
|
||||
text *res;
|
||||
int res_len;
|
||||
MBuf *buf;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
data = PG_GETARG_BYTEA_P(0);
|
||||
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,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("%s", px_strerror(res_len))));
|
||||
VARATT_SIZEP(res) = VARHDRSZ + res_len;
|
||||
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_RETURN_TEXT_P(res);
|
||||
}
|
||||
|
193
contrib/pgcrypto/pgp-pubdec.c
Normal file
193
contrib/pgcrypto/pgp-pubdec.c
Normal file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* pgp-pubdec.c
|
||||
* Decrypt public-key encrypted session key.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubdec.c,v 1.1 2005/07/10 13:46:29 momjian Exp $
|
||||
*/
|
||||
#include <postgres.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "px.h"
|
||||
#include "mbuf.h"
|
||||
#include "pgp.h"
|
||||
|
||||
/*
|
||||
* padded msg = 02 || PS || 00 || M
|
||||
* PS - pad bytes
|
||||
* M - msg
|
||||
*/
|
||||
static uint8 *
|
||||
check_eme_pkcs1_v15(uint8 *data, int len)
|
||||
{
|
||||
uint8 *data_end = data + len;
|
||||
uint8 *p = data;
|
||||
int rnd = 0;
|
||||
|
||||
if (len < 1 + 8 + 1)
|
||||
return NULL;
|
||||
|
||||
if (*p++ != 2)
|
||||
return NULL;
|
||||
|
||||
while (p < data_end && *p) {
|
||||
p++;
|
||||
rnd++;
|
||||
}
|
||||
|
||||
if (p == data_end)
|
||||
return NULL;
|
||||
if (*p != 0)
|
||||
return NULL;
|
||||
if (rnd < 8)
|
||||
return NULL;
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* secret message: 1 byte algo, sesskey, 2 byte cksum
|
||||
* ignore algo in cksum
|
||||
*/
|
||||
static int
|
||||
control_cksum(uint8 *msg, int msglen)
|
||||
{
|
||||
int i;
|
||||
unsigned my_cksum, got_cksum;
|
||||
|
||||
if (msglen < 3)
|
||||
return PXE_PGP_CORRUPT_DATA;
|
||||
|
||||
my_cksum = 0;
|
||||
for (i = 1; i < msglen - 2; i++)
|
||||
my_cksum += msg[i];
|
||||
my_cksum &= 0xFFFF;
|
||||
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 0;
|
||||
}
|
||||
|
||||
/* key id is missing - user is expected to try all keys */
|
||||
static const uint8
|
||||
any_key[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
int
|
||||
pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
|
||||
{
|
||||
int ver;
|
||||
int algo;
|
||||
int res;
|
||||
uint8 key_id[8];
|
||||
PGP_MPI *c1, *c2;
|
||||
PGP_PubKey *pk;
|
||||
uint8 *msg;
|
||||
int msglen;
|
||||
PGP_MPI *m;
|
||||
|
||||
pk = ctx->pub_key;
|
||||
if (pk == NULL) {
|
||||
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);
|
||||
return PXE_PGP_CORRUPT_DATA;
|
||||
}
|
||||
|
||||
/*
|
||||
* check if keyid's match - user-friendly msg
|
||||
*/
|
||||
res = pullf_read_fixed(pkt, 8, key_id);
|
||||
if (res < 0)
|
||||
return res;
|
||||
if (memcmp(key_id, any_key, 8) != 0
|
||||
&& memcmp(key_id, pk->key_id, 8) != 0)
|
||||
{
|
||||
px_debug("key_id's does not match");
|
||||
return PXE_PGP_WRONG_KEYID;
|
||||
}
|
||||
|
||||
GETBYTE(pkt, algo);
|
||||
if (algo != PGP_PUB_ELG_ENCRYPT)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* extract message
|
||||
*/
|
||||
msg = check_eme_pkcs1_v15(m->data, m->bytes);
|
||||
if (msg == NULL) {
|
||||
px_debug("check_eme_pkcs1_v15 failed");
|
||||
return PXE_PGP_CORRUPT_DATA;
|
||||
}
|
||||
msglen = m->bytes - (msg - m->data);
|
||||
|
||||
res = control_cksum(msg, msglen);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
/*
|
||||
* got sesskey
|
||||
*/
|
||||
ctx->cipher_algo = *msg;
|
||||
ctx->sess_key_len = msglen - 3;
|
||||
memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len);
|
||||
|
||||
return pgp_expect_packet_end(pkt);
|
||||
}
|
||||
|
||||
|
230
contrib/pgcrypto/pgp-pubenc.c
Normal file
230
contrib/pgcrypto/pgp-pubenc.c
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* pgp-pubenc.c
|
||||
* Encrypt session key with public key.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubenc.c,v 1.1 2005/07/10 13:46:29 momjian Exp $
|
||||
*/
|
||||
#include <postgres.h>
|
||||
|
||||
#include "px.h"
|
||||
#include "mbuf.h"
|
||||
#include "pgp.h"
|
||||
|
||||
/*
|
||||
* padded msg: 02 || non-zero pad bytes || 00 || msg
|
||||
*/
|
||||
static int
|
||||
pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p)
|
||||
{
|
||||
int res;
|
||||
uint8 *buf, *p;
|
||||
int pad_len = res_len - 2 - data_len;
|
||||
|
||||
if (pad_len < 8)
|
||||
return PXE_BUG;
|
||||
|
||||
buf = px_alloc(res_len);
|
||||
buf[0] = 0x02;
|
||||
res = px_get_random_bytes(buf + 1, pad_len);
|
||||
if (res < 0)
|
||||
{
|
||||
px_free(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* pad must not contain zero bytes */
|
||||
p = buf + 1;
|
||||
while (p < buf + 1 + pad_len)
|
||||
{
|
||||
if (*p == 0)
|
||||
{
|
||||
res = px_get_random_bytes(p, 1);
|
||||
if (res < 0)
|
||||
break;
|
||||
}
|
||||
if (*p != 0)
|
||||
p++;
|
||||
}
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
memset(buf, 0, res_len);
|
||||
px_free(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
buf[pad_len + 1] = 0;
|
||||
memcpy(buf + pad_len + 2, data, data_len);
|
||||
*res_p = buf;
|
||||
|
||||
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)
|
||||
{
|
||||
uint8 *secmsg;
|
||||
int res, i, full_bytes;
|
||||
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];
|
||||
|
||||
/*
|
||||
* create "secret message"
|
||||
*/
|
||||
secmsg = px_alloc(klen + 3);
|
||||
secmsg[0] = ctx->cipher_algo;
|
||||
memcpy(secmsg + 1, ctx->sess_key, klen);
|
||||
secmsg[klen + 1] = (cksum >> 8) & 0xFF;
|
||||
secmsg[klen + 2] = cksum & 0xFF;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
/* first byte will be 0x02 */
|
||||
int full_bits = full_bytes * 8 - 6;
|
||||
res = pgp_mpi_create(padded, full_bits, &m);
|
||||
}
|
||||
|
||||
if (padded)
|
||||
{
|
||||
memset(padded, 0, full_bytes);
|
||||
px_free(padded);
|
||||
}
|
||||
memset(secmsg, 0, klen + 3);
|
||||
px_free(secmsg);
|
||||
|
||||
if (res >= 0)
|
||||
*msg_p = m;
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
*/
|
||||
res = pgp_create_pkt_writer(dst, PGP_PKT_PUBENCRYPTED_SESSKEY, &pkt);
|
||||
if (res < 0)
|
||||
goto err;
|
||||
res = pushf_write(pkt, &ver, 1);
|
||||
if (res < 0)
|
||||
goto err;
|
||||
res = pushf_write(pkt, pk->key_id, 8);
|
||||
if (res < 0)
|
||||
goto err;
|
||||
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);
|
||||
if (res < 0)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* done, signal packet end
|
||||
*/
|
||||
res = pushf_flush(pkt);
|
||||
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;
|
||||
}
|
||||
|
||||
|
448
contrib/pgcrypto/pgp-pubkey.c
Normal file
448
contrib/pgcrypto/pgp-pubkey.c
Normal file
@ -0,0 +1,448 @@
|
||||
/*
|
||||
* pgp-pubkey.c
|
||||
* Read public or secret key.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubkey.c,v 1.1 2005/07/10 13:46:29 momjian Exp $
|
||||
*/
|
||||
#include <postgres.h>
|
||||
|
||||
#include "px.h"
|
||||
#include "mbuf.h"
|
||||
#include "pgp.h"
|
||||
|
||||
#define PXE_PGP_BAD_KEY -90
|
||||
|
||||
int pgp_key_alloc(PGP_PubKey **pk_p)
|
||||
{
|
||||
PGP_PubKey *pk;
|
||||
pk = px_alloc(sizeof(*pk));
|
||||
memset(pk, 0, sizeof(*pk));
|
||||
*pk_p = pk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
memset(pk, 0, sizeof(*pk));
|
||||
px_free(pk);
|
||||
}
|
||||
|
||||
static int
|
||||
calc_key_id(PGP_PubKey *pk)
|
||||
{
|
||||
int res;
|
||||
PX_MD *md;
|
||||
int len;
|
||||
uint8 hdr[3];
|
||||
uint8 hash[20];
|
||||
|
||||
res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
len = 1 + 4 + 1;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
||||
hdr[0] = 0x99;
|
||||
hdr[1] = len >> 8;
|
||||
hdr[2] = len & 0xFF;
|
||||
px_md_update(md, hdr, 3);
|
||||
|
||||
px_md_update(md, &pk->ver, 1);
|
||||
px_md_update(md, pk->time, 4);
|
||||
px_md_update(md, &pk->algo, 1);
|
||||
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
px_md_finish(md, hash);
|
||||
px_md_free(md);
|
||||
|
||||
memcpy(pk->key_id, hash + 12, 8);
|
||||
memset(hash, 0, 20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey *pk)
|
||||
{
|
||||
int res;
|
||||
|
||||
/* get version */
|
||||
GETBYTE(pkt, pk->ver);
|
||||
if (pk->ver != 4) {
|
||||
px_debug("\tunsupported version: %d", pk->ver);
|
||||
return PXE_PGP_NOT_V4_KEYPKT;
|
||||
}
|
||||
|
||||
/* read time */
|
||||
res = pullf_read_fixed(pkt, 4, pk->time);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
/* 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);
|
||||
break;
|
||||
case PGP_PUB_ELG_ENCRYPT:
|
||||
res = pgp_mpi_read(pkt, &pk->elg_p);
|
||||
if (res < 0) break;
|
||||
res = pgp_mpi_read(pkt, &pk->elg_g);
|
||||
if (res < 0) break;
|
||||
res = pgp_mpi_read(pkt, &pk->elg_y);
|
||||
if (res < 0) break;
|
||||
|
||||
res = calc_key_id(pk);
|
||||
break;
|
||||
default:
|
||||
px_debug("unknown public algo: %d", pk->algo);
|
||||
res = PXE_PGP_UNKNOWN_PUBALGO;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define HIDE_CLEAR 0
|
||||
#define HIDE_CKSUM 255
|
||||
#define HIDE_SHA1 254
|
||||
|
||||
static int
|
||||
check_key_sha1(PullFilter *src, PGP_PubKey *pk)
|
||||
{
|
||||
int res;
|
||||
uint8 got_sha1[20];
|
||||
uint8 my_sha1[20];
|
||||
PX_MD *md;
|
||||
|
||||
res = pullf_read_fixed(src, 20, got_sha1);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
|
||||
if (res < 0)
|
||||
goto err;
|
||||
switch (pk->algo)
|
||||
{
|
||||
case PGP_PUB_ELG_ENCRYPT:
|
||||
pgp_mpi_hash(md, pk->elg_x);
|
||||
break;
|
||||
}
|
||||
px_md_finish(md, my_sha1);
|
||||
px_md_free(md);
|
||||
|
||||
if (memcmp(my_sha1, got_sha1, 20) != 0)
|
||||
{
|
||||
px_debug("key sha1 check failed");
|
||||
res = PXE_PGP_KEYPKT_CORRUPT;
|
||||
}
|
||||
err:
|
||||
memset(got_sha1, 0, 20);
|
||||
memset(my_sha1, 0, 20);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
check_key_cksum(PullFilter *src, PGP_PubKey *pk)
|
||||
{
|
||||
int res;
|
||||
unsigned got_cksum, my_cksum = 0;
|
||||
uint8 buf[2];
|
||||
|
||||
res = pullf_read_fixed(src, 2, buf);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
got_cksum = ((unsigned)buf[0] << 8) + buf[1];
|
||||
switch (pk->algo)
|
||||
{
|
||||
case PGP_PUB_ELG_ENCRYPT:
|
||||
my_cksum = pgp_mpi_cksum(0, pk->elg_x);
|
||||
break;
|
||||
}
|
||||
if (my_cksum != got_cksum)
|
||||
{
|
||||
px_debug("key cksum check failed");
|
||||
return PXE_PGP_KEYPKT_CORRUPT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_secret_key(PullFilter *pkt, PGP_PubKey *pk,
|
||||
const uint8 *key, int key_len)
|
||||
{
|
||||
int res;
|
||||
int hide_type;
|
||||
int cipher_algo;
|
||||
int bs;
|
||||
uint8 iv[512];
|
||||
PullFilter *pf_decrypt = NULL, *pf_key;
|
||||
PGP_CFB *cfb = NULL;
|
||||
PGP_S2K s2k;
|
||||
|
||||
/* first read public key part */
|
||||
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?
|
||||
*/
|
||||
GETBYTE(pkt, hide_type);
|
||||
if (hide_type == HIDE_SHA1 || hide_type == HIDE_CKSUM) {
|
||||
if (key == NULL)
|
||||
return PXE_PGP_NEED_SECRET_PSW;
|
||||
GETBYTE(pkt, cipher_algo);
|
||||
res = pgp_s2k_read(pkt, &s2k);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = pgp_s2k_process(&s2k, cipher_algo, key, key_len);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
bs = pgp_get_cipher_block_size(cipher_algo);
|
||||
if (bs == 0) {
|
||||
px_debug("unknown cipher algo=%d", cipher_algo);
|
||||
return PXE_PGP_UNSUPPORTED_CIPHER;
|
||||
}
|
||||
res = pullf_read_fixed(pkt, bs, iv);
|
||||
if (res < 0)
|
||||
return res;
|
||||
/*
|
||||
* create decrypt filter
|
||||
*/
|
||||
res = pgp_cfb_create(&cfb, cipher_algo, s2k.key, s2k.key_len, 0, iv);
|
||||
if (res < 0)
|
||||
return res;
|
||||
res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
|
||||
if (res < 0)
|
||||
return res;
|
||||
pf_key = pf_decrypt;
|
||||
} else if (hide_type == HIDE_CLEAR) {
|
||||
pf_key = pkt;
|
||||
} else {
|
||||
px_debug("unknown hide type");
|
||||
return PXE_PGP_KEYPKT_CORRUPT;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
break;
|
||||
case PGP_PUB_ELG_ENCRYPT:
|
||||
res = pgp_mpi_read(pf_key, &pk->elg_x);
|
||||
break;
|
||||
default:
|
||||
px_debug("unknown public algo: %d", pk->algo);
|
||||
res = PXE_PGP_KEYPKT_CORRUPT;
|
||||
}
|
||||
/* read checksum / sha1 */
|
||||
if (res >= 0)
|
||||
{
|
||||
if (hide_type == HIDE_SHA1)
|
||||
res = check_key_sha1(pf_key, pk);
|
||||
else
|
||||
res = check_key_cksum(pf_key, pk);
|
||||
}
|
||||
if (res >= 0)
|
||||
res = pgp_expect_packet_end(pf_key);
|
||||
|
||||
if (pf_decrypt)
|
||||
pullf_free(pf_decrypt);
|
||||
if (cfb)
|
||||
pgp_cfb_free(cfb);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
|
||||
const uint8 *key, int key_len, int pubtype)
|
||||
{
|
||||
PullFilter *pkt = NULL;
|
||||
int res;
|
||||
uint8 tag;
|
||||
int len;
|
||||
PGP_PubKey *pk = NULL;
|
||||
int got_key = 0;
|
||||
int n_subkey = 0;
|
||||
|
||||
res = pgp_key_alloc(&pk);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
/*
|
||||
* Search for Elgamal 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)
|
||||
break;
|
||||
res = pgp_create_pkt_reader(&pkt, src, len, res, NULL);
|
||||
if (res < 0)
|
||||
break;
|
||||
|
||||
switch (tag) {
|
||||
case PGP_PKT_SECRET_KEY:
|
||||
if (got_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++;
|
||||
|
||||
if (n_subkey > 1)
|
||||
res = PXE_PGP_MULTIPLE_SUBKEYS;
|
||||
else if (pubtype == 1)
|
||||
res = process_secret_key(pkt, pk, key, key_len);
|
||||
else
|
||||
res = PXE_PGP_EXPECT_PUBLIC_KEY;
|
||||
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);
|
||||
else
|
||||
res = PXE_PGP_EXPECT_SECRET_KEY;
|
||||
break;
|
||||
case PGP_PKT_SIGNATURE:
|
||||
case PGP_PKT_MARKER:
|
||||
case PGP_PKT_TRUST:
|
||||
case PGP_PKT_USER_ID:
|
||||
case PGP_PKT_USER_ATTR:
|
||||
case PGP_PKT_PRIV_61:
|
||||
res = pgp_skip_packet(pkt);
|
||||
break;
|
||||
default:
|
||||
px_debug("unknown/unexpected packet: %d", tag);
|
||||
res = PXE_PGP_UNEXPECTED_PKT;
|
||||
}
|
||||
pullf_free(pkt);
|
||||
pkt = NULL;
|
||||
|
||||
if (res < 0)
|
||||
break;
|
||||
|
||||
if (pk->algo == PGP_PUB_ELG_ENCRYPT)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pkt)
|
||||
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;
|
||||
}
|
||||
}
|
||||
return res < 0 ? res : 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt,
|
||||
const uint8 *key, int key_len, int pubtype)
|
||||
{
|
||||
int res;
|
||||
PullFilter *src;
|
||||
PGP_PubKey *pk = NULL;
|
||||
|
||||
res = pullf_create_mbuf_reader(&src, keypkt);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = internal_read_key(src, &pk, key, key_len, pubtype);
|
||||
pullf_free(src);
|
||||
|
||||
if (res >= 0)
|
||||
ctx->pub_key = pk;
|
||||
|
||||
return res < 0 ? res : 0;
|
||||
}
|
||||
|
299
contrib/pgcrypto/pgp-s2k.c
Normal file
299
contrib/pgcrypto/pgp-s2k.c
Normal file
@ -0,0 +1,299 @@
|
||||
/*
|
||||
* pgp-s2k.c
|
||||
* OpenPGP string2key functions.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-s2k.c,v 1.1 2005/07/10 13:46:29 momjian Exp $
|
||||
*/
|
||||
|
||||
#include <postgres.h>
|
||||
|
||||
#include "px.h"
|
||||
#include "mbuf.h"
|
||||
#include "pgp.h"
|
||||
|
||||
static int
|
||||
calc_s2k_simple(PGP_S2K * s2k, PX_MD *md, const uint8 *key,
|
||||
unsigned key_len)
|
||||
{
|
||||
unsigned md_bs,
|
||||
md_rlen;
|
||||
uint8 buf[PGP_MAX_DIGEST];
|
||||
unsigned preload;
|
||||
unsigned remain;
|
||||
uint8 *dst = s2k->key;
|
||||
|
||||
md_bs = px_md_block_size(md);
|
||||
md_rlen = px_md_result_size(md);
|
||||
|
||||
remain = s2k->key_len;
|
||||
preload = 0;
|
||||
while (remain > 0)
|
||||
{
|
||||
px_md_reset(md);
|
||||
|
||||
if (preload)
|
||||
{
|
||||
memset(buf, 0, preload);
|
||||
px_md_update(md, buf, preload);
|
||||
}
|
||||
preload++;
|
||||
|
||||
px_md_update(md, key, key_len);
|
||||
px_md_finish(md, buf);
|
||||
|
||||
if (remain > md_rlen)
|
||||
{
|
||||
memcpy(dst, buf, md_rlen);
|
||||
dst += md_rlen;
|
||||
remain -= md_rlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(dst, buf, remain);
|
||||
remain = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
calc_s2k_salted(PGP_S2K * s2k, PX_MD *md, const uint8 *key, unsigned key_len)
|
||||
{
|
||||
unsigned md_bs,
|
||||
md_rlen;
|
||||
uint8 buf[PGP_MAX_DIGEST];
|
||||
unsigned preload = 0;
|
||||
uint8 *dst;
|
||||
unsigned remain;
|
||||
|
||||
md_bs = px_md_block_size(md);
|
||||
md_rlen = px_md_result_size(md);
|
||||
|
||||
dst = s2k->key;
|
||||
remain = s2k->key_len;
|
||||
while (remain > 0)
|
||||
{
|
||||
px_md_reset(md);
|
||||
|
||||
if (preload > 0)
|
||||
{
|
||||
memset(buf, 0, preload);
|
||||
px_md_update(md, buf, preload);
|
||||
}
|
||||
preload++;
|
||||
|
||||
px_md_update(md, s2k->salt, PGP_S2K_SALT);
|
||||
px_md_update(md, key, key_len);
|
||||
px_md_finish(md, buf);
|
||||
|
||||
if (remain > md_rlen)
|
||||
{
|
||||
memcpy(dst, buf, md_rlen);
|
||||
remain -= md_rlen;
|
||||
dst += md_rlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(dst, buf, remain);
|
||||
remain = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
calc_s2k_iter_salted(PGP_S2K * s2k, PX_MD *md, const uint8 *key,
|
||||
unsigned key_len)
|
||||
{
|
||||
unsigned md_bs,
|
||||
md_rlen;
|
||||
uint8 buf[PGP_MAX_DIGEST];
|
||||
uint8 *dst;
|
||||
unsigned preload = 0;
|
||||
unsigned remain,
|
||||
c,
|
||||
cval,
|
||||
curcnt,
|
||||
count;
|
||||
|
||||
cval = s2k->iter;
|
||||
count = ((unsigned) 16 + (cval & 15)) << ((cval >> 4) + 6);
|
||||
|
||||
md_bs = px_md_block_size(md);
|
||||
md_rlen = px_md_result_size(md);
|
||||
|
||||
remain = s2k->key_len;
|
||||
dst = s2k->key;
|
||||
while (remain > 0)
|
||||
{
|
||||
px_md_reset(md);
|
||||
|
||||
if (preload)
|
||||
{
|
||||
memset(buf, 0, preload);
|
||||
px_md_update(md, buf, preload);
|
||||
}
|
||||
preload++;
|
||||
|
||||
px_md_update(md, s2k->salt, PGP_S2K_SALT);
|
||||
px_md_update(md, key, key_len);
|
||||
curcnt = PGP_S2K_SALT + key_len;
|
||||
|
||||
while (curcnt < count)
|
||||
{
|
||||
if (curcnt + PGP_S2K_SALT < count)
|
||||
c = PGP_S2K_SALT;
|
||||
else
|
||||
c = count - curcnt;
|
||||
px_md_update(md, s2k->salt, c);
|
||||
curcnt += c;
|
||||
|
||||
if (curcnt + key_len < count)
|
||||
c = key_len;
|
||||
else if (curcnt < count)
|
||||
c = count - curcnt;
|
||||
else
|
||||
break;
|
||||
px_md_update(md, key, c);
|
||||
curcnt += c;
|
||||
}
|
||||
px_md_finish(md, buf);
|
||||
|
||||
if (remain > md_rlen)
|
||||
{
|
||||
memcpy(dst, buf, md_rlen);
|
||||
remain -= md_rlen;
|
||||
dst += md_rlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(dst, buf, remain);
|
||||
remain = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decide S2K_ISALTED iteration count
|
||||
*
|
||||
* Too small: weak
|
||||
* Too big: slow
|
||||
* gpg defaults to 96 => 65536 iters
|
||||
* let it float a bit: 96 + 32 => 262144 iters
|
||||
*/
|
||||
static int
|
||||
decide_count(unsigned rand_byte)
|
||||
{
|
||||
return 96 + (rand_byte & 0x1F);
|
||||
}
|
||||
|
||||
int
|
||||
pgp_s2k_fill(PGP_S2K *s2k, int mode,int digest_algo)
|
||||
{
|
||||
int res = 0;
|
||||
uint8 tmp;
|
||||
|
||||
s2k->mode = mode;
|
||||
s2k->digest_algo = digest_algo;
|
||||
|
||||
switch (s2k->mode) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
|
||||
break;
|
||||
case 3:
|
||||
res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
|
||||
if (res < 0)
|
||||
break;
|
||||
res = px_get_random_bytes(&tmp, 1);
|
||||
if (res < 0)
|
||||
break;
|
||||
s2k->iter = decide_count(tmp);
|
||||
break;
|
||||
default:
|
||||
res = PXE_PGP_BAD_S2K_MODE;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
GETBYTE(src, s2k->mode);
|
||||
GETBYTE(src, s2k->digest_algo);
|
||||
switch (s2k->mode) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
res = pullf_read_fixed(src, 8, s2k->salt);
|
||||
break;
|
||||
case 3:
|
||||
res = pullf_read_fixed(src, 8, s2k->salt);
|
||||
if (res < 0)
|
||||
break;
|
||||
GETBYTE(src, s2k->iter);
|
||||
break;
|
||||
default:
|
||||
res = PXE_PGP_BAD_S2K_MODE;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
|
||||
{
|
||||
int res;
|
||||
PX_MD *md;
|
||||
|
||||
s2k->key_len = pgp_get_cipher_key_size(cipher);
|
||||
if (s2k->key_len <= 0)
|
||||
return PXE_PGP_UNSUPPORTED_CIPHER;
|
||||
|
||||
res = pgp_load_digest(s2k->digest_algo, &md);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
switch (s2k->mode) {
|
||||
case 0:
|
||||
res = calc_s2k_simple(s2k, md, key, key_len);
|
||||
break;
|
||||
case 1:
|
||||
res = calc_s2k_salted(s2k, md, key, key_len);
|
||||
break;
|
||||
case 3:
|
||||
res = calc_s2k_iter_salted(s2k, md, key, key_len);
|
||||
break;
|
||||
default:
|
||||
res = PXE_PGP_BAD_S2K_MODE;
|
||||
}
|
||||
px_md_free(md);
|
||||
return res;
|
||||
}
|
||||
|
351
contrib/pgcrypto/pgp.c
Normal file
351
contrib/pgcrypto/pgp.c
Normal file
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* pgp.c
|
||||
* Various utility stuff.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp.c,v 1.1 2005/07/10 13:46:29 momjian Exp $
|
||||
*/
|
||||
|
||||
#include <postgres.h>
|
||||
|
||||
#include "px.h"
|
||||
#include "mbuf.h"
|
||||
#include "pgp.h"
|
||||
|
||||
/*
|
||||
* Defaults.
|
||||
*/
|
||||
static int def_cipher_algo = PGP_SYM_AES_128;
|
||||
static int def_s2k_cipher_algo = -1;
|
||||
static int def_s2k_mode = PGP_S2K_ISALTED;
|
||||
static int def_s2k_digest_algo = PGP_DIGEST_SHA1;
|
||||
static int def_compress_algo = PGP_COMPR_NONE;
|
||||
static int def_compress_level = 6;
|
||||
static int def_disable_mdc = 0;
|
||||
static int def_use_sess_key = 0;
|
||||
static int def_text_mode = 0;
|
||||
static int def_unicode_mode = 0;
|
||||
static int def_convert_crlf = 0;
|
||||
|
||||
struct digest_info
|
||||
{
|
||||
const char *name;
|
||||
int code;
|
||||
const char *int_name;
|
||||
};
|
||||
|
||||
struct cipher_info
|
||||
{
|
||||
const char *name;
|
||||
int code;
|
||||
const char *int_name;
|
||||
int key_len;
|
||||
int block_len;
|
||||
};
|
||||
|
||||
static const struct digest_info digest_list[] = {
|
||||
{"md5", PGP_DIGEST_MD5},
|
||||
{"sha1", PGP_DIGEST_SHA1},
|
||||
{"sha-1", PGP_DIGEST_SHA1},
|
||||
{"ripemd160", PGP_DIGEST_RIPEMD160},
|
||||
{"sha256", PGP_DIGEST_SHA256},
|
||||
{"sha384", PGP_DIGEST_SHA384},
|
||||
{"sha512", PGP_DIGEST_SHA512},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static const struct cipher_info cipher_list[] = {
|
||||
{"3des", PGP_SYM_DES3, "3des-ecb", 192/8, 64/8},
|
||||
{"cast5", PGP_SYM_CAST5, "cast5-ecb", 128/8, 64/8},
|
||||
{"bf", PGP_SYM_BLOWFISH, "bf-ecb", 128/8, 64/8},
|
||||
{"blowfish", PGP_SYM_BLOWFISH, "bf-ecb", 128/8, 64/8},
|
||||
{"aes", PGP_SYM_AES_128, "aes-ecb", 128/8, 128/8},
|
||||
{"aes128", PGP_SYM_AES_128, "aes-ecb", 128/8, 128/8},
|
||||
{"aes192", PGP_SYM_AES_192, "aes-ecb", 192/8, 128/8},
|
||||
{"aes256", PGP_SYM_AES_256, "aes-ecb", 256/8, 128/8},
|
||||
{"twofish", PGP_SYM_TWOFISH, "twofish-ecb", 256/8, 128/8},
|
||||
{NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static const struct cipher_info *
|
||||
get_cipher_info(int code)
|
||||
{
|
||||
const struct cipher_info *i;
|
||||
for (i = cipher_list; i->name; i++)
|
||||
if (i->code == code)
|
||||
return i;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_get_digest_code(const char *name)
|
||||
{
|
||||
const struct digest_info *i;
|
||||
for (i = digest_list; i->name; i++)
|
||||
if (pg_strcasecmp(i->name, name) == 0)
|
||||
return i->code;
|
||||
return PXE_PGP_UNSUPPORTED_HASH;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_get_cipher_code(const char *name)
|
||||
{
|
||||
const struct cipher_info *i;
|
||||
for (i = cipher_list; i->name; i++)
|
||||
if (pg_strcasecmp(i->name, name) == 0)
|
||||
return i->code;
|
||||
return PXE_PGP_UNSUPPORTED_CIPHER;
|
||||
}
|
||||
|
||||
const char *
|
||||
pgp_get_digest_name(int code)
|
||||
{
|
||||
const struct digest_info *i;
|
||||
for (i = digest_list; i->name; i++)
|
||||
if (i->code == code)
|
||||
return i->name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
pgp_get_cipher_name(int code)
|
||||
{
|
||||
const struct cipher_info *i = get_cipher_info(code);
|
||||
if (i != NULL)
|
||||
return i->name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_get_cipher_key_size(int code)
|
||||
{
|
||||
const struct cipher_info *i = get_cipher_info(code);
|
||||
if (i != NULL)
|
||||
return i->key_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_get_cipher_block_size(int code)
|
||||
{
|
||||
const struct cipher_info *i = get_cipher_info(code);
|
||||
if (i != NULL)
|
||||
return i->block_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_load_cipher(int code, PX_Cipher ** res)
|
||||
{
|
||||
int err;
|
||||
const struct cipher_info *i = get_cipher_info(code);
|
||||
|
||||
if (i == NULL)
|
||||
return PXE_PGP_CORRUPT_DATA;
|
||||
|
||||
err = px_find_cipher(i->int_name, res);
|
||||
if (err == 0)
|
||||
return 0;
|
||||
|
||||
return PXE_PGP_UNSUPPORTED_CIPHER;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_load_digest(int code, PX_MD ** res)
|
||||
{
|
||||
int err;
|
||||
const char *name = pgp_get_digest_name(code);
|
||||
|
||||
if (name == NULL)
|
||||
return PXE_PGP_CORRUPT_DATA;
|
||||
|
||||
err = px_find_digest(name, res);
|
||||
if (err == 0)
|
||||
return 0;
|
||||
|
||||
return PXE_PGP_UNSUPPORTED_HASH;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_init(PGP_Context ** ctx_p)
|
||||
{
|
||||
PGP_Context *ctx;
|
||||
|
||||
ctx = px_alloc(sizeof *ctx);
|
||||
memset(ctx, 0, sizeof *ctx);
|
||||
|
||||
ctx->cipher_algo = def_cipher_algo;
|
||||
ctx->s2k_cipher_algo = def_s2k_cipher_algo;
|
||||
ctx->s2k_mode = def_s2k_mode;
|
||||
ctx->s2k_digest_algo = def_s2k_digest_algo;
|
||||
ctx->compress_algo = def_compress_algo;
|
||||
ctx->compress_level = def_compress_level;
|
||||
ctx->disable_mdc = def_disable_mdc;
|
||||
ctx->use_sess_key = def_use_sess_key;
|
||||
ctx->unicode_mode = def_unicode_mode;
|
||||
ctx->convert_crlf = def_convert_crlf;
|
||||
ctx->text_mode = def_text_mode;
|
||||
|
||||
*ctx_p = ctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_free(PGP_Context * ctx)
|
||||
{
|
||||
if (ctx->pub_key)
|
||||
pgp_key_free(ctx->pub_key);
|
||||
memset(ctx, 0, sizeof *ctx);
|
||||
px_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_disable_mdc(PGP_Context * ctx, int disable)
|
||||
{
|
||||
ctx->disable_mdc = disable ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_sess_key(PGP_Context * ctx, int use)
|
||||
{
|
||||
ctx->use_sess_key = use ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_convert_crlf(PGP_Context * ctx, int doit)
|
||||
{
|
||||
ctx->convert_crlf = doit ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_s2k_mode(PGP_Context * ctx, int mode)
|
||||
{
|
||||
int err = PXE_OK;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case PGP_S2K_SIMPLE:
|
||||
case PGP_S2K_SALTED:
|
||||
case PGP_S2K_ISALTED:
|
||||
ctx->s2k_mode = mode;
|
||||
break;
|
||||
default:
|
||||
err = PXE_ARGUMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_compress_algo(PGP_Context * ctx, int algo)
|
||||
{
|
||||
switch (algo)
|
||||
{
|
||||
case PGP_COMPR_NONE:
|
||||
case PGP_COMPR_ZIP:
|
||||
case PGP_COMPR_ZLIB:
|
||||
case PGP_COMPR_BZIP2:
|
||||
ctx->compress_algo = algo;
|
||||
return 0;
|
||||
}
|
||||
return PXE_ARGUMENT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_compress_level(PGP_Context * ctx, int level)
|
||||
{
|
||||
if (level >= 0 && level <= 9)
|
||||
{
|
||||
ctx->compress_level = level;
|
||||
return 0;
|
||||
}
|
||||
return PXE_ARGUMENT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_text_mode(PGP_Context * ctx, int mode)
|
||||
{
|
||||
ctx->text_mode = mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_cipher_algo(PGP_Context * ctx, const char *name)
|
||||
{
|
||||
int code = pgp_get_cipher_code(name);
|
||||
if (code < 0)
|
||||
return code;
|
||||
ctx->cipher_algo = code;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_s2k_cipher_algo(PGP_Context * ctx, const char *name)
|
||||
{
|
||||
int code = pgp_get_cipher_code(name);
|
||||
if (code < 0)
|
||||
return code;
|
||||
ctx->s2k_cipher_algo = code;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_s2k_digest_algo(PGP_Context * ctx, const char *name)
|
||||
{
|
||||
int code = pgp_get_digest_code(name);
|
||||
if (code < 0)
|
||||
return code;
|
||||
ctx->s2k_digest_algo = code;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_get_unicode_mode(PGP_Context *ctx)
|
||||
{
|
||||
return ctx->unicode_mode;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_unicode_mode(PGP_Context *ctx, int mode)
|
||||
{
|
||||
ctx->unicode_mode = mode ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int len)
|
||||
{
|
||||
if (key == NULL || len < 1)
|
||||
return PXE_ARGUMENT_ERROR;
|
||||
ctx->sym_key = key;
|
||||
ctx->sym_key_len = len;
|
||||
return 0;
|
||||
}
|
||||
|
273
contrib/pgcrypto/pgp.h
Normal file
273
contrib/pgcrypto/pgp.h
Normal file
@ -0,0 +1,273 @@
|
||||
/*
|
||||
* pgp.h
|
||||
* OpenPGP implementation.
|
||||
*
|
||||
* Copyright (c) 2005 Marko Kreen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp.h,v 1.1 2005/07/10 13:46:29 momjian Exp $
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
PGP_S2K_SIMPLE = 0,
|
||||
PGP_S2K_SALTED = 1,
|
||||
PGP_S2K_ISALTED = 3
|
||||
} PGP_S2K_TYPE;
|
||||
|
||||
enum
|
||||
{
|
||||
PGP_PKT_RESERVED = 0,
|
||||
PGP_PKT_PUBENCRYPTED_SESSKEY = 1,
|
||||
PGP_PKT_SIGNATURE = 2,
|
||||
PGP_PKT_SYMENCRYPTED_SESSKEY = 3,
|
||||
PGP_PKT_SECRET_KEY = 5,
|
||||
PGP_PKT_PUBLIC_KEY = 6,
|
||||
PGP_PKT_SECRET_SUBKEY = 7,
|
||||
PGP_PKT_COMPRESSED_DATA = 8,
|
||||
PGP_PKT_SYMENCRYPTED_DATA = 9,
|
||||
PGP_PKT_MARKER = 10,
|
||||
PGP_PKT_LITERAL_DATA = 11,
|
||||
PGP_PKT_TRUST = 12,
|
||||
PGP_PKT_USER_ID = 13,
|
||||
PGP_PKT_PUBLIC_SUBKEY = 14,
|
||||
PGP_PKT_USER_ATTR = 17,
|
||||
PGP_PKT_SYMENCRYPTED_DATA_MDC = 18,
|
||||
PGP_PKT_MDC = 19,
|
||||
PGP_PKT_PRIV_61 = 61 /* occurs in gpg secring */
|
||||
} PGP_PKT_TYPE;
|
||||
|
||||
enum
|
||||
{
|
||||
PGP_PUB_RSA_ENCRYPT_SIGN = 1,
|
||||
PGP_PUB_RSA_ENCRYPT = 2,
|
||||
PGP_PUB_RSA_SIGN = 3,
|
||||
PGP_PUB_ELG_ENCRYPT = 16,
|
||||
PGP_PUB_DSA_SIGN = 17
|
||||
} PGP_PUB_ALGO_TYPE;
|
||||
|
||||
enum
|
||||
{
|
||||
PGP_SYM_PLAIN = 0, /* ?? */
|
||||
PGP_SYM_IDEA = 1, /* obsolete, PGP 2.6 compat */
|
||||
PGP_SYM_DES3 = 2, /* must */
|
||||
PGP_SYM_CAST5 = 3, /* should */
|
||||
PGP_SYM_BLOWFISH = 4,
|
||||
PGP_SYM_SAFER_SK128 = 5, /* obsolete */
|
||||
PGP_SYM_DES_SK = 6, /* obsolete */
|
||||
PGP_SYM_AES_128 = 7, /* should */
|
||||
PGP_SYM_AES_192 = 8,
|
||||
PGP_SYM_AES_256 = 9,
|
||||
PGP_SYM_TWOFISH = 10
|
||||
} PGP_SYMENC_TYPE;
|
||||
|
||||
enum
|
||||
{
|
||||
PGP_COMPR_NONE = 0, /* must */
|
||||
PGP_COMPR_ZIP = 1, /* should */
|
||||
PGP_COMPR_ZLIB = 2,
|
||||
PGP_COMPR_BZIP2 = 3
|
||||
} PGP_COMPR_TYPE;
|
||||
|
||||
enum
|
||||
{
|
||||
PGP_DIGEST_MD5 = 1, /* should, deprecated */
|
||||
PGP_DIGEST_SHA1 = 2, /* must */
|
||||
PGP_DIGEST_RIPEMD160 = 3,
|
||||
PGP_DIGEST_XSHA = 4, /* obsolete */
|
||||
PGP_DIGEST_MD2 = 5, /* obsolete */
|
||||
PGP_DIGEST_TIGER192 = 6, /* obsolete */
|
||||
PGP_DIGEST_HAVAL5_160 = 7, /* obsolete */
|
||||
PGP_DIGEST_SHA256 = 8,
|
||||
PGP_DIGEST_SHA384 = 9,
|
||||
PGP_DIGEST_SHA512 = 10
|
||||
} PGP_DIGEST_TYPE;
|
||||
|
||||
#define PGP_MAX_KEY (256/8)
|
||||
#define PGP_MAX_BLOCK (256/8)
|
||||
#define PGP_MAX_DIGEST (512/8)
|
||||
#define PGP_S2K_SALT 8
|
||||
|
||||
typedef struct PGP_MPI PGP_MPI;
|
||||
typedef struct PGP_PubKey PGP_PubKey;
|
||||
typedef struct PGP_Context PGP_Context;
|
||||
typedef struct PGP_S2K PGP_S2K;
|
||||
|
||||
struct PGP_S2K {
|
||||
uint8 mode;
|
||||
uint8 digest_algo;
|
||||
uint8 salt[8];
|
||||
uint8 iter;
|
||||
/* calculated: */
|
||||
uint8 key[PGP_MAX_KEY];
|
||||
uint8 key_len;
|
||||
};
|
||||
|
||||
|
||||
struct PGP_Context
|
||||
{
|
||||
/*
|
||||
* parameters
|
||||
*/
|
||||
PGP_S2K s2k;
|
||||
int s2k_mode;
|
||||
int s2k_digest_algo;
|
||||
int s2k_cipher_algo;
|
||||
int cipher_algo;
|
||||
int compress_algo;
|
||||
int compress_level;
|
||||
int disable_mdc;
|
||||
int use_sess_key;
|
||||
int text_mode;
|
||||
int convert_crlf;
|
||||
int unicode_mode;
|
||||
|
||||
/*
|
||||
* internal variables
|
||||
*/
|
||||
int mdc_checked;
|
||||
int corrupt_prefix;
|
||||
int in_mdc_pkt;
|
||||
int use_mdcbuf_filter;
|
||||
PX_MD *mdc_ctx;
|
||||
|
||||
PGP_PubKey *pub_key; /* ctx owns it*/
|
||||
const uint8 *sym_key; /* ctx does not own it */
|
||||
int sym_key_len;
|
||||
|
||||
/*
|
||||
* read or generated data
|
||||
*/
|
||||
uint8 sess_key[PGP_MAX_KEY];
|
||||
unsigned sess_key_len;
|
||||
};
|
||||
|
||||
struct PGP_MPI {
|
||||
uint8 *data;
|
||||
int bits;
|
||||
int bytes;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
uint8 key_id[8];
|
||||
};
|
||||
|
||||
int pgp_init(PGP_Context ** ctx);
|
||||
int pgp_encrypt(PGP_Context * ctx, MBuf * src, MBuf * dst);
|
||||
int pgp_decrypt(PGP_Context * ctx, MBuf * src, MBuf * dst);
|
||||
int pgp_free(PGP_Context * ctx);
|
||||
|
||||
int pgp_get_digest_code(const char *name);
|
||||
int pgp_get_cipher_code(const char *name);
|
||||
const char *pgp_get_digest_name(int code);
|
||||
const char *pgp_get_cipher_name(int code);
|
||||
|
||||
int pgp_set_cipher_algo(PGP_Context * ctx, const char *name);
|
||||
int pgp_set_s2k_mode(PGP_Context * ctx, int type);
|
||||
int pgp_set_s2k_cipher_algo(PGP_Context * ctx, const char *name);
|
||||
int pgp_set_s2k_digest_algo(PGP_Context * ctx, const char *name);
|
||||
int pgp_set_convert_crlf(PGP_Context * ctx, int doit);
|
||||
int pgp_disable_mdc(PGP_Context * ctx, int disable);
|
||||
int pgp_set_sess_key(PGP_Context * ctx, int use);
|
||||
int pgp_set_compress_algo(PGP_Context * ctx, int algo);
|
||||
int pgp_set_compress_level(PGP_Context * ctx, int level);
|
||||
int pgp_set_text_mode(PGP_Context * ctx, int mode);
|
||||
int pgp_set_unicode_mode(PGP_Context * ctx, int mode);
|
||||
int pgp_get_unicode_mode(PGP_Context * ctx);
|
||||
|
||||
int pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int klen);
|
||||
int pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt,
|
||||
const uint8 *key, int klen, int pubtype);
|
||||
|
||||
int pgp_get_keyid(MBuf *pgp_data, char *dst);
|
||||
|
||||
/* internal functions */
|
||||
|
||||
int pgp_load_digest(int c, PX_MD ** res);
|
||||
int pgp_load_cipher(int c, PX_Cipher ** res);
|
||||
int pgp_get_cipher_key_size(int c);
|
||||
int pgp_get_cipher_block_size(int c);
|
||||
|
||||
int pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo);
|
||||
int pgp_s2k_read(PullFilter *src, PGP_S2K *s2k);
|
||||
int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int klen);
|
||||
|
||||
typedef struct PGP_CFB PGP_CFB;
|
||||
int pgp_cfb_create(PGP_CFB **ctx_p, int algo,
|
||||
const uint8 *key, int key_len, int recync, uint8 *iv);
|
||||
void pgp_cfb_free(PGP_CFB *ctx);
|
||||
int pgp_cfb_encrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst);
|
||||
int pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst);
|
||||
|
||||
int pgp_armor_encode(const uint8 *src, unsigned len, uint8 *dst);
|
||||
int pgp_armor_decode(const uint8 *src, unsigned len, uint8 *dst);
|
||||
unsigned pgp_armor_enc_len(unsigned len);
|
||||
unsigned pgp_armor_dec_len(unsigned len);
|
||||
|
||||
int pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst);
|
||||
int pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src);
|
||||
|
||||
extern void (*pgp_packet_debug) (int tag, uint8 *buf, int len);
|
||||
|
||||
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_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt);
|
||||
int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
|
||||
int pkttype, PGP_Context *ctx);
|
||||
int pgp_parse_pkt_hdr(PullFilter * src, uint8 *tag, int *len_p,
|
||||
int allow_ctx);
|
||||
|
||||
int pgp_skip_packet(PullFilter *pkt);
|
||||
int pgp_expect_packet_end(PullFilter *pkt);
|
||||
|
||||
int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst);
|
||||
int pgp_create_pkt_writer(PushFilter *dst, int tag, PushFilter **res_p);
|
||||
|
||||
int pgp_mpi_alloc(int bits, PGP_MPI **mpi);
|
||||
int pgp_mpi_create(uint8 *data, int bits, PGP_MPI **mpi);
|
||||
int pgp_mpi_free(PGP_MPI *mpi);
|
||||
int pgp_mpi_read(PullFilter *src, PGP_MPI **mpi);
|
||||
int pgp_mpi_write(PushFilter *dst, PGP_MPI *n);
|
||||
int pgp_mpi_hash(PX_MD *md, PGP_MPI *n);
|
||||
unsigned pgp_mpi_cksum(unsigned cksum, PGP_MPI *n);
|
||||
|
||||
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);
|
||||
|
||||
extern struct PullFilterOps pgp_decrypt_filter;
|
||||
|
895
contrib/pgcrypto/sha2.c
Normal file
895
contrib/pgcrypto/sha2.c
Normal file
@ -0,0 +1,895 @@
|
||||
/* $PostgreSQL: pgsql/contrib/pgcrypto/sha2.c,v 1.1 2005/07/10 13:46:29 momjian Exp $ */
|
||||
/* $OpenBSD: sha2.c,v 1.6 2004/05/03 02:57:36 millert Exp $ */
|
||||
|
||||
/*
|
||||
* FILE: sha2.c
|
||||
* AUTHOR: Aaron D. Gifford <me@aarongifford.com>
|
||||
*
|
||||
* Copyright (c) 2000-2001, Aaron D. Gifford
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
|
||||
*/
|
||||
|
||||
#include <postgres.h>
|
||||
|
||||
#include "sha2.h"
|
||||
|
||||
#undef bcopy
|
||||
#undef bzero
|
||||
#define bcopy(src, dst, len) memcpy((dst), (src), (len))
|
||||
#define bzero(ptr, len) memset((ptr), 0, (len))
|
||||
|
||||
/*
|
||||
* UNROLLED TRANSFORM LOOP NOTE:
|
||||
* You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
|
||||
* loop version for the hash transform rounds (defined using macros
|
||||
* later in this file). Either define on the command line, for example:
|
||||
*
|
||||
* cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
|
||||
*
|
||||
* or define below:
|
||||
*
|
||||
* #define SHA2_UNROLL_TRANSFORM
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*** SHA-256/384/512 Machine Architecture Definitions *****************/
|
||||
/*
|
||||
* BYTE_ORDER NOTE:
|
||||
*
|
||||
* Please make sure that your system defines BYTE_ORDER. If your
|
||||
* architecture is little-endian, make sure it also defines
|
||||
* LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
|
||||
* equivilent.
|
||||
*
|
||||
* If your system does not define the above, then you can do so by
|
||||
* hand like this:
|
||||
*
|
||||
* #define LITTLE_ENDIAN 1234
|
||||
* #define BIG_ENDIAN 4321
|
||||
*
|
||||
* And for little-endian machines, add:
|
||||
*
|
||||
* #define BYTE_ORDER LITTLE_ENDIAN
|
||||
*
|
||||
* Or for big-endian machines:
|
||||
*
|
||||
* #define BYTE_ORDER BIG_ENDIAN
|
||||
*
|
||||
* The FreeBSD machine this was written on defines BYTE_ORDER
|
||||
* appropriately by including <sys/types.h> (which in turn includes
|
||||
* <machine/endian.h> where the appropriate definitions are actually
|
||||
* made).
|
||||
*/
|
||||
#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
|
||||
#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
|
||||
/*** SHA-256/384/512 Various Length Definitions ***********************/
|
||||
/* NOTE: Most of these are in sha2.h */
|
||||
#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
|
||||
#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
|
||||
#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
|
||||
|
||||
|
||||
/*** ENDIAN REVERSAL MACROS *******************************************/
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define REVERSE32(w,x) { \
|
||||
uint32 tmp = (w); \
|
||||
tmp = (tmp >> 16) | (tmp << 16); \
|
||||
(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
|
||||
}
|
||||
#define REVERSE64(w,x) { \
|
||||
uint64 tmp = (w); \
|
||||
tmp = (tmp >> 32) | (tmp << 32); \
|
||||
tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
|
||||
((tmp & 0x00ff00ff00ff00ffULL) << 8); \
|
||||
(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
|
||||
((tmp & 0x0000ffff0000ffffULL) << 16); \
|
||||
}
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
|
||||
/*
|
||||
* Macro for incrementally adding the unsigned 64-bit integer n to the
|
||||
* unsigned 128-bit integer (represented using a two-element array of
|
||||
* 64-bit words):
|
||||
*/
|
||||
#define ADDINC128(w,n) { \
|
||||
(w)[0] += (uint64)(n); \
|
||||
if ((w)[0] < (n)) { \
|
||||
(w)[1]++; \
|
||||
} \
|
||||
}
|
||||
|
||||
/*** THE SIX LOGICAL FUNCTIONS ****************************************/
|
||||
/*
|
||||
* Bit shifting and rotation (used by the six SHA-XYZ logical functions:
|
||||
*
|
||||
* NOTE: The naming of R and S appears backwards here (R is a SHIFT and
|
||||
* S is a ROTATION) because the SHA-256/384/512 description document
|
||||
* (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
|
||||
* same "backwards" definition.
|
||||
*/
|
||||
/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
|
||||
#define R(b,x) ((x) >> (b))
|
||||
/* 32-bit Rotate-right (used in SHA-256): */
|
||||
#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
|
||||
/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
|
||||
#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
|
||||
|
||||
/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
|
||||
#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
|
||||
#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
/* Four of six logical functions used in SHA-256: */
|
||||
#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
|
||||
#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
|
||||
#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
|
||||
#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
|
||||
|
||||
/* Four of six logical functions used in SHA-384 and SHA-512: */
|
||||
#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
|
||||
#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
|
||||
#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
|
||||
#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
|
||||
|
||||
/*** INTERNAL FUNCTION PROTOTYPES *************************************/
|
||||
/* NOTE: These should not be accessed directly from outside this
|
||||
* library -- they are intended for private internal visibility/use
|
||||
* only.
|
||||
*/
|
||||
void SHA512_Last(SHA512_CTX *);
|
||||
void SHA256_Transform(SHA256_CTX *, const uint8 *);
|
||||
void SHA512_Transform(SHA512_CTX *, const uint8 *);
|
||||
|
||||
|
||||
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
|
||||
/* Hash constant words K for SHA-256: */
|
||||
const static uint32 K256[64] = {
|
||||
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
|
||||
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
|
||||
0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
|
||||
0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
|
||||
0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
|
||||
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
|
||||
0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
|
||||
0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
|
||||
0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
|
||||
0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
|
||||
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
|
||||
0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
|
||||
0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
|
||||
0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
|
||||
0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
|
||||
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
|
||||
};
|
||||
|
||||
/* Initial hash value H for SHA-256: */
|
||||
const static uint32 sha256_initial_hash_value[8] = {
|
||||
0x6a09e667UL,
|
||||
0xbb67ae85UL,
|
||||
0x3c6ef372UL,
|
||||
0xa54ff53aUL,
|
||||
0x510e527fUL,
|
||||
0x9b05688cUL,
|
||||
0x1f83d9abUL,
|
||||
0x5be0cd19UL
|
||||
};
|
||||
|
||||
/* Hash constant words K for SHA-384 and SHA-512: */
|
||||
const static uint64 K512[80] = {
|
||||
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
|
||||
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
|
||||
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
|
||||
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
|
||||
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
|
||||
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
||||
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
|
||||
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
|
||||
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
|
||||
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
|
||||
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
|
||||
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
||||
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
|
||||
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
|
||||
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
|
||||
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
|
||||
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
|
||||
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
|
||||
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
|
||||
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
|
||||
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
|
||||
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
|
||||
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
||||
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
|
||||
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
|
||||
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
|
||||
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
|
||||
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
|
||||
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
||||
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
|
||||
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
|
||||
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
|
||||
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
|
||||
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
|
||||
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
|
||||
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
|
||||
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
|
||||
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
|
||||
};
|
||||
|
||||
/* Initial hash value H for SHA-384 */
|
||||
const static uint64 sha384_initial_hash_value[8] = {
|
||||
0xcbbb9d5dc1059ed8ULL,
|
||||
0x629a292a367cd507ULL,
|
||||
0x9159015a3070dd17ULL,
|
||||
0x152fecd8f70e5939ULL,
|
||||
0x67332667ffc00b31ULL,
|
||||
0x8eb44a8768581511ULL,
|
||||
0xdb0c2e0d64f98fa7ULL,
|
||||
0x47b5481dbefa4fa4ULL
|
||||
};
|
||||
|
||||
/* Initial hash value H for SHA-512 */
|
||||
const static uint64 sha512_initial_hash_value[8] = {
|
||||
0x6a09e667f3bcc908ULL,
|
||||
0xbb67ae8584caa73bULL,
|
||||
0x3c6ef372fe94f82bULL,
|
||||
0xa54ff53a5f1d36f1ULL,
|
||||
0x510e527fade682d1ULL,
|
||||
0x9b05688c2b3e6c1fULL,
|
||||
0x1f83d9abfb41bd6bULL,
|
||||
0x5be0cd19137e2179ULL
|
||||
};
|
||||
|
||||
|
||||
/*** SHA-256: *********************************************************/
|
||||
void
|
||||
SHA256_Init(SHA256_CTX *context)
|
||||
{
|
||||
if (context == NULL)
|
||||
return;
|
||||
bcopy(sha256_initial_hash_value, context->state, SHA256_DIGEST_LENGTH);
|
||||
bzero(context->buffer, SHA256_BLOCK_LENGTH);
|
||||
context->bitcount = 0;
|
||||
}
|
||||
|
||||
#ifdef SHA2_UNROLL_TRANSFORM
|
||||
|
||||
/* Unrolled SHA-256 round macros: */
|
||||
|
||||
#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do { \
|
||||
W256[j] = (uint32)data[3] | ((uint32)data[2] << 8) | \
|
||||
((uint32)data[1] << 16) | ((uint32)data[0] << 24); \
|
||||
data += 4; \
|
||||
T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \
|
||||
(d) += T1; \
|
||||
(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \
|
||||
j++; \
|
||||
} while(0)
|
||||
|
||||
#define ROUND256(a,b,c,d,e,f,g,h) do { \
|
||||
s0 = W256[(j+1)&0x0f]; \
|
||||
s0 = sigma0_256(s0); \
|
||||
s1 = W256[(j+14)&0x0f]; \
|
||||
s1 = sigma1_256(s1); \
|
||||
T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + \
|
||||
(W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
|
||||
(d) += T1; \
|
||||
(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \
|
||||
j++; \
|
||||
} while(0)
|
||||
|
||||
void
|
||||
SHA256_Transform(SHA256_CTX *context, const uint8 *data)
|
||||
{
|
||||
uint32 a, b, c, d, e, f, g, h, s0, s1;
|
||||
uint32 T1, *W256;
|
||||
int j;
|
||||
|
||||
W256 = (uint32 *)context->buffer;
|
||||
|
||||
/* Initialize registers with the prev. intermediate value */
|
||||
a = context->state[0];
|
||||
b = context->state[1];
|
||||
c = context->state[2];
|
||||
d = context->state[3];
|
||||
e = context->state[4];
|
||||
f = context->state[5];
|
||||
g = context->state[6];
|
||||
h = context->state[7];
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
/* Rounds 0 to 15 (unrolled): */
|
||||
ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
|
||||
ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
|
||||
ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
|
||||
ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
|
||||
ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
|
||||
ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
|
||||
ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
|
||||
ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
|
||||
} while (j < 16);
|
||||
|
||||
/* Now for the remaining rounds to 64: */
|
||||
do {
|
||||
ROUND256(a,b,c,d,e,f,g,h);
|
||||
ROUND256(h,a,b,c,d,e,f,g);
|
||||
ROUND256(g,h,a,b,c,d,e,f);
|
||||
ROUND256(f,g,h,a,b,c,d,e);
|
||||
ROUND256(e,f,g,h,a,b,c,d);
|
||||
ROUND256(d,e,f,g,h,a,b,c);
|
||||
ROUND256(c,d,e,f,g,h,a,b);
|
||||
ROUND256(b,c,d,e,f,g,h,a);
|
||||
} while (j < 64);
|
||||
|
||||
/* Compute the current intermediate hash value */
|
||||
context->state[0] += a;
|
||||
context->state[1] += b;
|
||||
context->state[2] += c;
|
||||
context->state[3] += d;
|
||||
context->state[4] += e;
|
||||
context->state[5] += f;
|
||||
context->state[6] += g;
|
||||
context->state[7] += h;
|
||||
|
||||
/* Clean up */
|
||||
a = b = c = d = e = f = g = h = T1 = 0;
|
||||
}
|
||||
|
||||
#else /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void
|
||||
SHA256_Transform(SHA256_CTX *context, const uint8 *data)
|
||||
{
|
||||
uint32 a, b, c, d, e, f, g, h, s0, s1;
|
||||
uint32 T1, T2, *W256;
|
||||
int j;
|
||||
|
||||
W256 = (uint32 *)context->buffer;
|
||||
|
||||
/* Initialize registers with the prev. intermediate value */
|
||||
a = context->state[0];
|
||||
b = context->state[1];
|
||||
c = context->state[2];
|
||||
d = context->state[3];
|
||||
e = context->state[4];
|
||||
f = context->state[5];
|
||||
g = context->state[6];
|
||||
h = context->state[7];
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
W256[j] = (uint32)data[3] | ((uint32)data[2] << 8) |
|
||||
((uint32)data[1] << 16) | ((uint32)data[0] << 24);
|
||||
data += 4;
|
||||
/* Apply the SHA-256 compression function to update a..h */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
|
||||
T2 = Sigma0_256(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 16);
|
||||
|
||||
do {
|
||||
/* Part of the message block expansion: */
|
||||
s0 = W256[(j+1)&0x0f];
|
||||
s0 = sigma0_256(s0);
|
||||
s1 = W256[(j+14)&0x0f];
|
||||
s1 = sigma1_256(s1);
|
||||
|
||||
/* Apply the SHA-256 compression function to update a..h */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
|
||||
(W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
|
||||
T2 = Sigma0_256(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 64);
|
||||
|
||||
/* Compute the current intermediate hash value */
|
||||
context->state[0] += a;
|
||||
context->state[1] += b;
|
||||
context->state[2] += c;
|
||||
context->state[3] += d;
|
||||
context->state[4] += e;
|
||||
context->state[5] += f;
|
||||
context->state[6] += g;
|
||||
context->state[7] += h;
|
||||
|
||||
/* Clean up */
|
||||
a = b = c = d = e = f = g = h = T1 = T2 = 0;
|
||||
}
|
||||
|
||||
#endif /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void
|
||||
SHA256_Update(SHA256_CTX *context, const uint8 *data, size_t len)
|
||||
{
|
||||
size_t freespace, usedspace;
|
||||
|
||||
/* Calling with no data is valid (we do nothing) */
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
||||
if (usedspace > 0) {
|
||||
/* Calculate how much free space is available in the buffer */
|
||||
freespace = SHA256_BLOCK_LENGTH - usedspace;
|
||||
|
||||
if (len >= freespace) {
|
||||
/* Fill the buffer completely and process it */
|
||||
bcopy(data, &context->buffer[usedspace], freespace);
|
||||
context->bitcount += freespace << 3;
|
||||
len -= freespace;
|
||||
data += freespace;
|
||||
SHA256_Transform(context, context->buffer);
|
||||
} else {
|
||||
/* The buffer is not yet full */
|
||||
bcopy(data, &context->buffer[usedspace], len);
|
||||
context->bitcount += len << 3;
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (len >= SHA256_BLOCK_LENGTH) {
|
||||
/* Process as many complete blocks as we can */
|
||||
SHA256_Transform(context, data);
|
||||
context->bitcount += SHA256_BLOCK_LENGTH << 3;
|
||||
len -= SHA256_BLOCK_LENGTH;
|
||||
data += SHA256_BLOCK_LENGTH;
|
||||
}
|
||||
if (len > 0) {
|
||||
/* There's left-overs, so save 'em */
|
||||
bcopy(data, context->buffer, len);
|
||||
context->bitcount += len << 3;
|
||||
}
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SHA256_Final(uint8 digest[], SHA256_CTX *context)
|
||||
{
|
||||
uint32 *d = (uint32 *)digest;
|
||||
unsigned int usedspace;
|
||||
|
||||
/* If no digest buffer is passed, we don't bother doing this: */
|
||||
if (digest != NULL) {
|
||||
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
/* Convert FROM host byte order */
|
||||
REVERSE64(context->bitcount,context->bitcount);
|
||||
#endif
|
||||
if (usedspace > 0) {
|
||||
/* Begin padding with a 1 bit: */
|
||||
context->buffer[usedspace++] = 0x80;
|
||||
|
||||
if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
|
||||
/* Set-up for the last transform: */
|
||||
bzero(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
|
||||
} else {
|
||||
if (usedspace < SHA256_BLOCK_LENGTH) {
|
||||
bzero(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
|
||||
}
|
||||
/* Do second-to-last transform: */
|
||||
SHA256_Transform(context, context->buffer);
|
||||
|
||||
/* And set-up for the last transform: */
|
||||
bzero(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
|
||||
}
|
||||
} else {
|
||||
/* Set-up for the last transform: */
|
||||
bzero(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
|
||||
|
||||
/* Begin padding with a 1 bit: */
|
||||
*context->buffer = 0x80;
|
||||
}
|
||||
/* Set the bit count: */
|
||||
*(uint64 *)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
|
||||
|
||||
/* Final transform: */
|
||||
SHA256_Transform(context, context->buffer);
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
{
|
||||
/* Convert TO host byte order */
|
||||
int j;
|
||||
for (j = 0; j < 8; j++) {
|
||||
REVERSE32(context->state[j],context->state[j]);
|
||||
*d++ = context->state[j];
|
||||
}
|
||||
}
|
||||
#else
|
||||
bcopy(context->state, d, SHA256_DIGEST_LENGTH);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Clean up state data: */
|
||||
bzero(context, sizeof(*context));
|
||||
usedspace = 0;
|
||||
}
|
||||
|
||||
|
||||
/*** SHA-512: *********************************************************/
|
||||
void
|
||||
SHA512_Init(SHA512_CTX *context)
|
||||
{
|
||||
if (context == NULL)
|
||||
return;
|
||||
bcopy(sha512_initial_hash_value, context->state, SHA512_DIGEST_LENGTH);
|
||||
bzero(context->buffer, SHA512_BLOCK_LENGTH);
|
||||
context->bitcount[0] = context->bitcount[1] = 0;
|
||||
}
|
||||
|
||||
#ifdef SHA2_UNROLL_TRANSFORM
|
||||
|
||||
/* Unrolled SHA-512 round macros: */
|
||||
|
||||
#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do { \
|
||||
W512[j] = (uint64)data[7] | ((uint64)data[6] << 8) | \
|
||||
((uint64)data[5] << 16) | ((uint64)data[4] << 24) | \
|
||||
((uint64)data[3] << 32) | ((uint64)data[2] << 40) | \
|
||||
((uint64)data[1] << 48) | ((uint64)data[0] << 56); \
|
||||
data += 8; \
|
||||
T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \
|
||||
(d) += T1; \
|
||||
(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \
|
||||
j++; \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define ROUND512(a,b,c,d,e,f,g,h) do { \
|
||||
s0 = W512[(j+1)&0x0f]; \
|
||||
s0 = sigma0_512(s0); \
|
||||
s1 = W512[(j+14)&0x0f]; \
|
||||
s1 = sigma1_512(s1); \
|
||||
T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + \
|
||||
(W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
|
||||
(d) += T1; \
|
||||
(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \
|
||||
j++; \
|
||||
} while(0)
|
||||
|
||||
void
|
||||
SHA512_Transform(SHA512_CTX *context, const uint8 *data)
|
||||
{
|
||||
uint64 a, b, c, d, e, f, g, h, s0, s1;
|
||||
uint64 T1, *W512 = (uint64 *)context->buffer;
|
||||
int j;
|
||||
|
||||
/* Initialize registers with the prev. intermediate value */
|
||||
a = context->state[0];
|
||||
b = context->state[1];
|
||||
c = context->state[2];
|
||||
d = context->state[3];
|
||||
e = context->state[4];
|
||||
f = context->state[5];
|
||||
g = context->state[6];
|
||||
h = context->state[7];
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
|
||||
ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
|
||||
ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
|
||||
ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
|
||||
ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
|
||||
ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
|
||||
ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
|
||||
ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
|
||||
} while (j < 16);
|
||||
|
||||
/* Now for the remaining rounds up to 79: */
|
||||
do {
|
||||
ROUND512(a,b,c,d,e,f,g,h);
|
||||
ROUND512(h,a,b,c,d,e,f,g);
|
||||
ROUND512(g,h,a,b,c,d,e,f);
|
||||
ROUND512(f,g,h,a,b,c,d,e);
|
||||
ROUND512(e,f,g,h,a,b,c,d);
|
||||
ROUND512(d,e,f,g,h,a,b,c);
|
||||
ROUND512(c,d,e,f,g,h,a,b);
|
||||
ROUND512(b,c,d,e,f,g,h,a);
|
||||
} while (j < 80);
|
||||
|
||||
/* Compute the current intermediate hash value */
|
||||
context->state[0] += a;
|
||||
context->state[1] += b;
|
||||
context->state[2] += c;
|
||||
context->state[3] += d;
|
||||
context->state[4] += e;
|
||||
context->state[5] += f;
|
||||
context->state[6] += g;
|
||||
context->state[7] += h;
|
||||
|
||||
/* Clean up */
|
||||
a = b = c = d = e = f = g = h = T1 = 0;
|
||||
}
|
||||
|
||||
#else /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void
|
||||
SHA512_Transform(SHA512_CTX *context, const uint8 *data)
|
||||
{
|
||||
uint64 a, b, c, d, e, f, g, h, s0, s1;
|
||||
uint64 T1, T2, *W512 = (uint64 *)context->buffer;
|
||||
int j;
|
||||
|
||||
/* Initialize registers with the prev. intermediate value */
|
||||
a = context->state[0];
|
||||
b = context->state[1];
|
||||
c = context->state[2];
|
||||
d = context->state[3];
|
||||
e = context->state[4];
|
||||
f = context->state[5];
|
||||
g = context->state[6];
|
||||
h = context->state[7];
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
W512[j] = (uint64)data[7] | ((uint64)data[6] << 8) |
|
||||
((uint64)data[5] << 16) | ((uint64)data[4] << 24) |
|
||||
((uint64)data[3] << 32) | ((uint64)data[2] << 40) |
|
||||
((uint64)data[1] << 48) | ((uint64)data[0] << 56);
|
||||
data += 8;
|
||||
/* Apply the SHA-512 compression function to update a..h */
|
||||
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
|
||||
T2 = Sigma0_512(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 16);
|
||||
|
||||
do {
|
||||
/* Part of the message block expansion: */
|
||||
s0 = W512[(j+1)&0x0f];
|
||||
s0 = sigma0_512(s0);
|
||||
s1 = W512[(j+14)&0x0f];
|
||||
s1 = sigma1_512(s1);
|
||||
|
||||
/* Apply the SHA-512 compression function to update a..h */
|
||||
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
|
||||
(W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
|
||||
T2 = Sigma0_512(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 80);
|
||||
|
||||
/* Compute the current intermediate hash value */
|
||||
context->state[0] += a;
|
||||
context->state[1] += b;
|
||||
context->state[2] += c;
|
||||
context->state[3] += d;
|
||||
context->state[4] += e;
|
||||
context->state[5] += f;
|
||||
context->state[6] += g;
|
||||
context->state[7] += h;
|
||||
|
||||
/* Clean up */
|
||||
a = b = c = d = e = f = g = h = T1 = T2 = 0;
|
||||
}
|
||||
|
||||
#endif /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void
|
||||
SHA512_Update(SHA512_CTX *context, const uint8 *data, size_t len)
|
||||
{
|
||||
size_t freespace, usedspace;
|
||||
|
||||
/* Calling with no data is valid (we do nothing) */
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
||||
if (usedspace > 0) {
|
||||
/* Calculate how much free space is available in the buffer */
|
||||
freespace = SHA512_BLOCK_LENGTH - usedspace;
|
||||
|
||||
if (len >= freespace) {
|
||||
/* Fill the buffer completely and process it */
|
||||
bcopy(data, &context->buffer[usedspace], freespace);
|
||||
ADDINC128(context->bitcount, freespace << 3);
|
||||
len -= freespace;
|
||||
data += freespace;
|
||||
SHA512_Transform(context, context->buffer);
|
||||
} else {
|
||||
/* The buffer is not yet full */
|
||||
bcopy(data, &context->buffer[usedspace], len);
|
||||
ADDINC128(context->bitcount, len << 3);
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (len >= SHA512_BLOCK_LENGTH) {
|
||||
/* Process as many complete blocks as we can */
|
||||
SHA512_Transform(context, data);
|
||||
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
|
||||
len -= SHA512_BLOCK_LENGTH;
|
||||
data += SHA512_BLOCK_LENGTH;
|
||||
}
|
||||
if (len > 0) {
|
||||
/* There's left-overs, so save 'em */
|
||||
bcopy(data, context->buffer, len);
|
||||
ADDINC128(context->bitcount, len << 3);
|
||||
}
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SHA512_Last(SHA512_CTX *context)
|
||||
{
|
||||
unsigned int usedspace;
|
||||
|
||||
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
/* Convert FROM host byte order */
|
||||
REVERSE64(context->bitcount[0],context->bitcount[0]);
|
||||
REVERSE64(context->bitcount[1],context->bitcount[1]);
|
||||
#endif
|
||||
if (usedspace > 0) {
|
||||
/* Begin padding with a 1 bit: */
|
||||
context->buffer[usedspace++] = 0x80;
|
||||
|
||||
if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
|
||||
/* Set-up for the last transform: */
|
||||
bzero(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
|
||||
} else {
|
||||
if (usedspace < SHA512_BLOCK_LENGTH) {
|
||||
bzero(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
|
||||
}
|
||||
/* Do second-to-last transform: */
|
||||
SHA512_Transform(context, context->buffer);
|
||||
|
||||
/* And set-up for the last transform: */
|
||||
bzero(context->buffer, SHA512_BLOCK_LENGTH - 2);
|
||||
}
|
||||
} else {
|
||||
/* Prepare for final transform: */
|
||||
bzero(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
|
||||
|
||||
/* Begin padding with a 1 bit: */
|
||||
*context->buffer = 0x80;
|
||||
}
|
||||
/* Store the length of input data (in bits): */
|
||||
*(uint64 *)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
|
||||
*(uint64 *)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
|
||||
|
||||
/* Final transform: */
|
||||
SHA512_Transform(context, context->buffer);
|
||||
}
|
||||
|
||||
void
|
||||
SHA512_Final(uint8 digest[], SHA512_CTX *context)
|
||||
{
|
||||
uint64 *d = (uint64 *)digest;
|
||||
|
||||
/* If no digest buffer is passed, we don't bother doing this: */
|
||||
if (digest != NULL) {
|
||||
SHA512_Last(context);
|
||||
|
||||
/* Save the hash data for output: */
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
{
|
||||
/* Convert TO host byte order */
|
||||
int j;
|
||||
for (j = 0; j < 8; j++) {
|
||||
REVERSE64(context->state[j],context->state[j]);
|
||||
*d++ = context->state[j];
|
||||
}
|
||||
}
|
||||
#else
|
||||
bcopy(context->state, d, SHA512_DIGEST_LENGTH);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Zero out state data */
|
||||
bzero(context, sizeof(*context));
|
||||
}
|
||||
|
||||
|
||||
/*** SHA-384: *********************************************************/
|
||||
void
|
||||
SHA384_Init(SHA384_CTX *context)
|
||||
{
|
||||
if (context == NULL)
|
||||
return;
|
||||
bcopy(sha384_initial_hash_value, context->state, SHA512_DIGEST_LENGTH);
|
||||
bzero(context->buffer, SHA384_BLOCK_LENGTH);
|
||||
context->bitcount[0] = context->bitcount[1] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SHA384_Update(SHA384_CTX *context, const uint8 *data, size_t len)
|
||||
{
|
||||
SHA512_Update((SHA512_CTX *)context, data, len);
|
||||
}
|
||||
|
||||
void
|
||||
SHA384_Final(uint8 digest[], SHA384_CTX *context)
|
||||
{
|
||||
uint64 *d = (uint64 *)digest;
|
||||
|
||||
/* If no digest buffer is passed, we don't bother doing this: */
|
||||
if (digest != NULL) {
|
||||
SHA512_Last((SHA512_CTX *)context);
|
||||
|
||||
/* Save the hash data for output: */
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
{
|
||||
/* Convert TO host byte order */
|
||||
int j;
|
||||
for (j = 0; j < 6; j++) {
|
||||
REVERSE64(context->state[j],context->state[j]);
|
||||
*d++ = context->state[j];
|
||||
}
|
||||
}
|
||||
#else
|
||||
bcopy(context->state, d, SHA384_DIGEST_LENGTH);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Zero out state data */
|
||||
bzero(context, sizeof(*context));
|
||||
}
|
80
contrib/pgcrypto/sha2.h
Normal file
80
contrib/pgcrypto/sha2.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* $PostgreSQL: pgsql/contrib/pgcrypto/sha2.h,v 1.1 2005/07/10 13:46:29 momjian Exp $ */
|
||||
/* $OpenBSD: sha2.h,v 1.2 2004/04/28 23:11:57 millert Exp $ */
|
||||
|
||||
/*
|
||||
* FILE: sha2.h
|
||||
* AUTHOR: Aaron D. Gifford <me@aarongifford.com>
|
||||
*
|
||||
* Copyright (c) 2000-2001, Aaron D. Gifford
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $From: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
|
||||
*/
|
||||
|
||||
#ifndef _SHA2_H
|
||||
#define _SHA2_H
|
||||
|
||||
|
||||
/*** SHA-256/384/512 Various Length Definitions ***********************/
|
||||
#define SHA256_BLOCK_LENGTH 64
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
|
||||
#define SHA384_BLOCK_LENGTH 128
|
||||
#define SHA384_DIGEST_LENGTH 48
|
||||
#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
|
||||
#define SHA512_BLOCK_LENGTH 128
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
|
||||
|
||||
|
||||
/*** SHA-256/384/512 Context Structures *******************************/
|
||||
typedef struct _SHA256_CTX {
|
||||
uint32 state[8];
|
||||
uint64 bitcount;
|
||||
uint8 buffer[SHA256_BLOCK_LENGTH];
|
||||
} SHA256_CTX;
|
||||
typedef struct _SHA512_CTX {
|
||||
uint64 state[8];
|
||||
uint64 bitcount[2];
|
||||
uint8 buffer[SHA512_BLOCK_LENGTH];
|
||||
} SHA512_CTX;
|
||||
|
||||
typedef SHA512_CTX SHA384_CTX;
|
||||
|
||||
void SHA256_Init(SHA256_CTX *);
|
||||
void SHA256_Update(SHA256_CTX *, const uint8 *, size_t);
|
||||
void SHA256_Final(uint8[SHA256_DIGEST_LENGTH], SHA256_CTX *);
|
||||
|
||||
void SHA384_Init(SHA384_CTX *);
|
||||
void SHA384_Update(SHA384_CTX *, const uint8 *, size_t);
|
||||
void SHA384_Final(uint8[SHA384_DIGEST_LENGTH], SHA384_CTX *);
|
||||
|
||||
void SHA512_Init(SHA512_CTX *);
|
||||
void SHA512_Update(SHA512_CTX *, const uint8 *, size_t);
|
||||
void SHA512_Final(uint8[SHA512_DIGEST_LENGTH], SHA512_CTX *);
|
||||
|
||||
#endif /* _SHA2_H */
|
56
contrib/pgcrypto/sql/pgp-armor.sql
Normal file
56
contrib/pgcrypto/sql/pgp-armor.sql
Normal file
@ -0,0 +1,56 @@
|
||||
--
|
||||
-- PGP Armor
|
||||
--
|
||||
|
||||
select armor('');
|
||||
select armor('test');
|
||||
select dearmor(armor(''));
|
||||
select dearmor(armor('zooka'));
|
||||
|
||||
select armor('0123456789abcdef0123456789abcdef0123456789abcdef
|
||||
0123456789abcdef0123456789abcdef0123456789abcdef');
|
||||
|
||||
-- lots formatting
|
||||
select dearmor(' a pgp msg:
|
||||
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: Some junk
|
||||
|
||||
em9va2E=
|
||||
|
||||
=D5cR
|
||||
|
||||
-----END PGP MESSAGE-----');
|
||||
|
||||
-- lots messages
|
||||
select dearmor('
|
||||
wrong packet:
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
d3Jvbmc=
|
||||
=vCYP
|
||||
-----END PGP MESSAGE-----
|
||||
|
||||
right packet:
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
cmlnaHQ=
|
||||
=nbpj
|
||||
-----END PGP MESSAGE-----
|
||||
|
||||
use only first packet
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
d3Jvbmc=
|
||||
=vCYP
|
||||
-----END PGP MESSAGE-----
|
||||
');
|
||||
|
||||
-- bad crc
|
||||
select dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
em9va2E=
|
||||
=ZZZZ
|
||||
-----END PGP MESSAGE-----
|
||||
');
|
31
contrib/pgcrypto/sql/pgp-compression.sql
Normal file
31
contrib/pgcrypto/sql/pgp-compression.sql
Normal file
@ -0,0 +1,31 @@
|
||||
--
|
||||
-- PGP compression support
|
||||
--
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
ww0ECQMCsci6AdHnELlh0kQB4jFcVwHMJg0Bulop7m3Mi36s15TAhBo0AnzIrRFrdLVCkKohsS6+
|
||||
DMcmR53SXfLoDJOv/M8uKj3QSq7oWNIp95pxfA==
|
||||
=tbSn
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'key', 'expect-compress-algo=1');
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret message', 'key', 'compress-algo=0'),
|
||||
'key', 'expect-compress-algo=0');
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret message', 'key', 'compress-algo=1'),
|
||||
'key', 'expect-compress-algo=1');
|
||||
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret message', 'key', 'compress-algo=2'),
|
||||
'key', 'expect-compress-algo=2');
|
||||
|
||||
-- level=0 should turn compression off
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret message', 'key',
|
||||
'compress-algo=2, compress-level=0'),
|
||||
'key', 'expect-compress-algo=0');
|
||||
|
266
contrib/pgcrypto/sql/pgp-decrypt.sql
Normal file
266
contrib/pgcrypto/sql/pgp-decrypt.sql
Normal file
@ -0,0 +1,266 @@
|
||||
--
|
||||
-- pgp_descrypt tests
|
||||
--
|
||||
|
||||
-- Checking ciphers
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.blowfish.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBAMCfFNwxnvodX9g0jwB4n4s26/g5VmKzVab1bX1SmwY7gvgvlWdF3jKisvS
|
||||
yA6Ce1QTMK3KdL2MPfamsTUSAML8huCJMwYQFfE=
|
||||
=JcP+
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCci97v0Q6Z0Zg0kQBsVf5Oe3iC+FBzUmuMV9KxmAyOMyjCc/5i8f1Eest
|
||||
UTAsG35A1vYs02VARKzGz6xI2UHwFUirP+brPBg3Ee7muOx8pA==
|
||||
=XtrP
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes192.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0ECAMCI7YQpWqp3D1g0kQBCjB7GlX7+SQeXNleXeXQ78ZAPNliquGDq9u378zI
|
||||
5FPTqAhIB2/2fjY8QEIs1ai00qphjX2NitxV/3Wn+6dufB4Q4g==
|
||||
=rCZt
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes256.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0ECQMC4f/5djqCC1Rg0kQBTHEPsD+Sw7biBsM2er3vKyGPAQkuTBGKC5ie7hT/
|
||||
lceMfQdbAg6oTFyJpk/wH18GzRDphCofg0X8uLgkAKMrpcmgog==
|
||||
=fB6S
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
-- Checking MDC modes
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.nomdc.s2k3.z0
|
||||
|
||||
jA0EBwMCnv07rlXqWctgyS2Dm2JfOKCRL4sLSLJUC8RS2cH7cIhKSuLitOtyquB+
|
||||
u9YkgfJfsuRJmgQ9tmo=
|
||||
=60ui
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCEeP3idNjQ1Bg0kQBf4G0wX+2QNzLh2YNwYkQgQkfYhn/hLXjV4nK9nsE
|
||||
8Ex1Dsdt5UPvOz8W8VKQRS6loOfOe+yyXil8W3IYFwUpdDUi+Q==
|
||||
=moGf
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
-- Checking hashes
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.md5.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMClrXXtOXetohg0kQBn0Kl1ymevQZRHkdoYRHgzCwSQEiss7zYff2UNzgO
|
||||
KyRrHf7zEBuZiZ2AG34jNVMOLToj1jJUg5zTSdecUzQVCykWTA==
|
||||
=NyLk
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCApbdlrURoWJg0kQBzHM/E0o7djY82bNuspjxjAcPFrrtp0uvDdMQ4z2m
|
||||
/PM8jhgI5vxFYfNQjLl8y3fHYIomk9YflN9K/Q13iq8A8sjeTw==
|
||||
=FxbQ
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
-- Checking S2K modes
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k0.z0
|
||||
|
||||
jAQEBwAC0kQBKTaLAKE3xzps+QIZowqRNb2eAdzBw2LxEW2YD5PgNlbhJdGg+dvw
|
||||
Ah9GXjGS1TVALzTImJbz1uHUZRfhJlFbc5yGQw==
|
||||
=YvkV
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k1.z0
|
||||
|
||||
jAwEBwEC/QTByBLI3b/SRAHPxKzI6SZBo5lAEOD+EsvKQWO4adL9tDY+++Iqy1xK
|
||||
4IaWXVKEj9R2Lr2xntWWMGZtcKtjD2lFFRXXd9dZp1ZThNDz
|
||||
=dbXm
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCEq4Su3ZqNEJg0kQB4QG5jBTKF0i04xtH+avzmLhstBNRxvV3nsmB3cwl
|
||||
z+9ZaA/XdSx5ZiFnMym8P6r8uY9rLjjNptvvRHlxIReF+p9MNg==
|
||||
=VJKg
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes192.sha1.mdc.s2k0.z0
|
||||
|
||||
jAQECAAC0kQBBDnQWkgsx9YFaqDfWmpsiyAJ6y2xG/sBvap1dySYEMuZ+wJTXQ9E
|
||||
Cr3i2M7TgVZ0M4jp4QL0adG1lpN5iK7aQeOwMw==
|
||||
=cg+i
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes192.sha1.mdc.s2k1.z0
|
||||
|
||||
jAwECAECruOfyNDFiTnSRAEVoGXm4A9UZKkWljdzjEO/iaE7mIraltIpQMkiqCh9
|
||||
7h8uZ2u9uRBOv222fZodGvc6bvq/4R4hAa/6qSHtm8mdmvGt
|
||||
=aHmC
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes192.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0ECAMCjFn6SRi3SONg0kQBqtSHPaD0m7rXfDAhCWU/ypAsI93GuHGRyM99cvMv
|
||||
q6eF6859ZVnli3BFSDSk3a4e/pXhglxmDYCfjAXkozKNYLo6yw==
|
||||
=K0LS
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes256.sha1.mdc.s2k0.z0
|
||||
|
||||
jAQECQAC0kQB4L1eMbani07XF2ZYiXNK9LW3v8w41oUPl7dStmrJPQFwsdxmrDHu
|
||||
rQr3WbdKdY9ufjOE5+mXI+EFkSPrF9rL9NCq6w==
|
||||
=RGts
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes256.sha1.mdc.s2k1.z0
|
||||
|
||||
jAwECQECKHhrou7ZOIXSRAHWIVP+xjVQcjAVBTt+qh9SNzYe248xFTwozkwev3mO
|
||||
+KVJW0qhk0An+Y2KF99/bYFl9cL5D3Tl43fC8fXGl3x3m7pR
|
||||
=SUrU
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes256.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0ECQMCjc8lwZu8Fz1g0kQBkEzjImi21liep5jj+3dAJ2aZFfUkohi8b3n9z+7+
|
||||
4+NRzL7cMW2RLAFnJbiqXDlRHMwleeuLN1up2WIxsxtYYuaBjA==
|
||||
=XZrG
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'foobar');
|
||||
|
||||
-- Checking longer passwords
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCx6dBiuqrYNRg0kQBEo63AvA1SCslxP7ayanLf1H0/hlk2nONVhTwVEWi
|
||||
tTGup1mMz6Cfh1uDRErUuXpx9A0gdMu7zX0o5XjrL7WGDAZdSw==
|
||||
=XKKG
|
||||
-----END PGP MESSAGE-----
|
||||
'), '0123456789abcdefghij');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCBDvYuS990iFg0kQBW31UK5OiCjWf5x6KJ8qNNT2HZWQCjCBZMU0XsOC6
|
||||
CMxFKadf144H/vpoV9GA0f22keQgCl0EsTE4V4lweVOPTKCMJg==
|
||||
=gWDh
|
||||
-----END PGP MESSAGE-----
|
||||
'), '0123456789abcdefghij2jk4h5g2j54khg23h54g2kh54g2khj54g23hj54');
|
||||
|
||||
select pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCqXbFafC+ofVg0kQBejyiPqH0QMERVGfmPOjtAxvyG5KDIJPYojTgVSDt
|
||||
FwsDabdQUz5O7bgNSnxfmyw1OifGF+W2bIn/8W+0rDf8u3+O+Q==
|
||||
=OxOF
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'x');
|
||||
|
||||
-- Checking various data
|
||||
select encode(digest(pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat1.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCGJ+SpuOysINg0kQBJfSjzsW0x4OVcAyr17O7FBvMTwIGeGcJd99oTQU8
|
||||
Xtx3kDqnhUq9Z1fS3qPbi5iNP2A9NxOBxPWz2JzxhydANlgbxg==
|
||||
=W/ik
|
||||
-----END PGP MESSAGE-----
|
||||
'), '0123456789abcdefghij'), 'sha1'), 'hex');
|
||||
-- expected: 0225e3ede6f2587b076d021a189ff60aad67e066
|
||||
|
||||
select encode(digest(pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat2.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCvdpDvidNzMxg0jUBvj8eS2+1t/9/zgemxvhtc0fvdKGGbjH7dleaTJRB
|
||||
SaV9L04ky1qECNDx3XjnoKLC+H7IOQ==
|
||||
=Fxen
|
||||
-----END PGP MESSAGE-----
|
||||
'), '0123456789abcdefghij'), 'sha1'), 'hex');
|
||||
-- expected: da39a3ee5e6b4b0d3255bfef95601890afd80709
|
||||
|
||||
select encode(digest(pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: dat3.aes.sha1.mdc.s2k3.z0
|
||||
|
||||
jA0EBwMCxQvxJZ3G/HRg0lgBeYmTa7/uDAjPyFwSX4CYBgpZWVn/JS8JzILrcWF8
|
||||
gFnkUKIE0PSaYFp+Yi1VlRfUtRQ/X/LYNGa7tWZS+4VQajz2Xtz4vUeAEiYFYPXk
|
||||
73Hb8m1yRhQK
|
||||
=ivrD
|
||||
-----END PGP MESSAGE-----
|
||||
'), '0123456789abcdefghij'), 'sha1'), 'hex');
|
||||
-- expected: 5e5c135efc0dd00633efc6dfd6e731ea408a5b4c
|
||||
|
||||
-- Checking CRLF
|
||||
select encode(digest(pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: crlf mess
|
||||
|
||||
ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms
|
||||
a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs
|
||||
=mBP9
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'key', 'convert-crlf=0'), 'sha1'), 'hex');
|
||||
-- expected: 9353062be7720f1446d30b9e75573a4833886784
|
||||
|
||||
select encode(digest(pgp_sym_decrypt(dearmor('
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Comment: crlf mess
|
||||
|
||||
ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms
|
||||
a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs
|
||||
=mBP9
|
||||
-----END PGP MESSAGE-----
|
||||
'), 'key', 'convert-crlf=1'), 'sha1'), 'hex');
|
||||
-- expected: 7efefcab38467f7484d6fa43dc86cf5281bd78e2
|
3
contrib/pgcrypto/sql/pgp-encrypt-DISABLED.sql
Normal file
3
contrib/pgcrypto/sql/pgp-encrypt-DISABLED.sql
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
-- no random source
|
||||
|
96
contrib/pgcrypto/sql/pgp-encrypt.sql
Normal file
96
contrib/pgcrypto/sql/pgp-encrypt.sql
Normal file
@ -0,0 +1,96 @@
|
||||
--
|
||||
-- PGP encrypt
|
||||
--
|
||||
|
||||
select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), 'key');
|
||||
|
||||
-- check whether the defaults are ok
|
||||
select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'),
|
||||
'key', 'expect-cipher-algo=aes128,
|
||||
expect-disable-mdc=0,
|
||||
expect-sess-key=0,
|
||||
expect-s2k-mode=3,
|
||||
expect-s2k-digest-algo=sha1,
|
||||
expect-compress-algo=0
|
||||
');
|
||||
|
||||
-- maybe the expect- stuff simply does not work
|
||||
select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'),
|
||||
'key', 'expect-cipher-algo=bf,
|
||||
expect-disable-mdc=1,
|
||||
expect-sess-key=1,
|
||||
expect-s2k-mode=0,
|
||||
expect-s2k-digest-algo=md5,
|
||||
expect-compress-algo=1
|
||||
');
|
||||
|
||||
-- bytea as text
|
||||
select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz');
|
||||
|
||||
-- text as bytea
|
||||
select pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz');
|
||||
|
||||
|
||||
-- algorithm change
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=bf'),
|
||||
'key', 'expect-cipher-algo=bf');
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes'),
|
||||
'key', 'expect-cipher-algo=aes128');
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes192'),
|
||||
'key', 'expect-cipher-algo=aes192');
|
||||
|
||||
-- s2k change
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 's2k-mode=0'),
|
||||
'key', 'expect-s2k-mode=0');
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 's2k-mode=1'),
|
||||
'key', 'expect-s2k-mode=1');
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 's2k-mode=3'),
|
||||
'key', 'expect-s2k-mode=3');
|
||||
|
||||
-- s2k digest change
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
|
||||
'key', 'expect-s2k-digest-algo=md5');
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=sha1'),
|
||||
'key', 'expect-s2k-digest-algo=sha1');
|
||||
|
||||
-- sess key
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'sess-key=0'),
|
||||
'key', 'expect-sess-key=0');
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'sess-key=1'),
|
||||
'key', 'expect-sess-key=1');
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=bf'),
|
||||
'key', 'expect-sess-key=1, expect-cipher-algo=bf');
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes192'),
|
||||
'key', 'expect-sess-key=1, expect-cipher-algo=aes192');
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes256'),
|
||||
'key', 'expect-sess-key=1, expect-cipher-algo=aes256');
|
||||
|
||||
-- no mdc
|
||||
select pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('Secret.', 'key', 'disable-mdc=1'),
|
||||
'key', 'expect-disable-mdc=1');
|
||||
|
||||
-- crlf
|
||||
select encode(pgp_sym_decrypt_bytea(
|
||||
pgp_sym_encrypt('1\n2\n3\r\n', 'key', 'convert-crlf=1'),
|
||||
'key'), 'hex');
|
||||
|
||||
-- conversion should be lossless
|
||||
select encode(digest(pgp_sym_decrypt(
|
||||
pgp_sym_encrypt('\r\n0\n1\r\r\n\n2\r', 'key', 'convert-crlf=1'),
|
||||
'key', 'convert-crlf=1'), 'sha1'), 'hex') as result,
|
||||
encode(digest('\r\n0\n1\r\r\n\n2\r', 'sha1'), 'hex') as expect;
|
||||
|
21
contrib/pgcrypto/sql/pgp-info.sql
Normal file
21
contrib/pgcrypto/sql/pgp-info.sql
Normal file
@ -0,0 +1,21 @@
|
||||
--
|
||||
-- PGP info functions
|
||||
--
|
||||
|
||||
-- pgp_key_id
|
||||
|
||||
select pgp_key_id(dearmor(pubkey)) from keytbl where id=1;
|
||||
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(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(data)) as data_key_id
|
||||
from encdata order by id;
|
||||
|
3
contrib/pgcrypto/sql/pgp-pubkey-DISABLED.sql
Normal file
3
contrib/pgcrypto/sql/pgp-pubkey-DISABLED.sql
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
-- no bignum support
|
||||
|
437
contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql
Normal file
437
contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql
Normal file
@ -0,0 +1,437 @@
|
||||
--
|
||||
-- PGP Public Key Encryption
|
||||
--
|
||||
|
||||
-- As most of the low-level stuff is tested in symmetric key
|
||||
-- tests, here's only public-key specific tests
|
||||
|
||||
create table keytbl (
|
||||
id int4,
|
||||
name text,
|
||||
pubkey text,
|
||||
seckey text
|
||||
);
|
||||
create table encdata (
|
||||
id int4,
|
||||
data text
|
||||
);
|
||||
|
||||
insert into keytbl (id, name, pubkey, seckey)
|
||||
values (1, 'elg1024', '
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
|
||||
tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
|
||||
xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
|
||||
klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
|
||||
YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
|
||||
PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
|
||||
jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
|
||||
saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
|
||||
IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx
|
||||
MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV
|
||||
AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc
|
||||
AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd
|
||||
ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P
|
||||
sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI
|
||||
+h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9
|
||||
6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF
|
||||
k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v
|
||||
iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F
|
||||
ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80
|
||||
=RWci
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
', '
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
lQG7BELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
|
||||
tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
|
||||
xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
|
||||
klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
|
||||
YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
|
||||
PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
|
||||
jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
|
||||
saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
|
||||
IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQAAAnj4i4st+s+C6
|
||||
WKTIDcL1Iy0Saq8lCp60H0VsZ2FtYWwgMTAyNCA8dGVzdEBleGFtcGxlLm9yZz6I
|
||||
XgQTEQIAHgUCQsghSAIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRAcKbwNGBdz
|
||||
ZDrbAJ9cp6AsjOhiLxwznsMJheGf4xkH8wCfUPjMCLm4tAEnyYn2hDNt7CB8B6Kd
|
||||
ATEEQsghShAEAIeUjW2yTALCfrEG3FhM3ZLvAHWAec2O0Mn/RDr59IN/W8wDYcZp
|
||||
m+oG0ZUDdIqMppQ8K2kylAH7gmYDXIP9D7MRRm/Zw3L4yFfKnVaZ6tT7szBbgW5h
|
||||
iOsHoOz49NXZT4jtMLdZS1/krm5Lam2MSPod9XN0Q2asY/igIMUfGDRjAAMGA/sE
|
||||
LNh3tWefqeDkoDBEYjcxdGnGVGJnNHvv/eoHy9H7dyD/kkhaOoRAa5ClYWSqD0kk
|
||||
a+SqTWhKG4XcbJyo1GsP6sqGhXDTM2+LBZPMKuVJQpEfoe9ruob/BbpXglfEiVE9
|
||||
VNiY7ZVyUdj3svYn4fK2X7ue1G3cHR2tL4lnOA4pYQAA9030E4u2ZKOfJBpUM+EM
|
||||
m9VmsGjaQZV4teB0R/q3W8sRIYhJBBgRAgAJBQJCyCFKAhsMAAoJEBwpvA0YF3Nk
|
||||
7a8AniFFotw1x2X+oryu3Q3nNtmxoKHpAJ9HU7jw7ydg33dI9J8gVkrmsSZ2/w==
|
||||
=nvqq
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
');
|
||||
|
||||
insert into keytbl (id, name, pubkey, seckey)
|
||||
values (2, 'elg2048', '
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
mQGiBELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n
|
||||
vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke
|
||||
5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO
|
||||
RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij
|
||||
8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl
|
||||
Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt
|
||||
J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/
|
||||
T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5
|
||||
0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6a7QjRWxnYW1hbCAy
|
||||
MDQ4IDx0ZXN0MjA0OEBleGFtcGxlLm9yZz6IXgQTEQIAHgUCQsgiCgIbAwYLCQgH
|
||||
AwIDFQIDAxYCAQIeAQIXgAAKCRBI6c1W/qZo29PDAKCG724enIxRog1j+aeCp/uq
|
||||
or6mbwCePuKy2/1kD1FvnhkZ/R5fpm+pdm25Ag0EQsgiIhAIAJI3Gb2Ehtz1taQ9
|
||||
AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMX
|
||||
MhoWyw8ZF5Zs1mLIjFGVorePrm94N3MNPWM7x9M36bHUjx0vCZKFIhcGY1g+htE/
|
||||
QweaJzNVeA5z4qZmik41FbQyQSyHa3bOkTZu++/U6ghP+iDp5UDBjMTkVyqITUVN
|
||||
gC+MR+da/I60irBVhue7younh4ovF+CrVDQJC06HZl6CAJJyA81SmRfi+dmKbbjZ
|
||||
LF6rhz0norPjISJvkIqvdtM4VPBKI5wpgwCzpEqjuiKrAVujRT68zvBvJ4aVqb11
|
||||
k5QdJscAAwUH/jVJh0HbWAoiFTe+NvohfrA8vPcD0rtU3Y+siiqrabotnxJd2NuC
|
||||
bxghJYGfNtnx0KDjFbCRKJVeTFok4UnuVYhXdH/c6i0/rCTNdeW2D6pmR4GfBozR
|
||||
Pw/ARf+jONawGLyUj7uq13iquwMSE7VyNuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0R
|
||||
QsetMq/iNBWraayKZnWUd+eQqNzE+NUo7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiF
|
||||
Z1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qunfGW00ZMMTCWabg0ZgxPzMfMeIcm6525A
|
||||
Yn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/RdWaISQQYEQIACQUCQsgiIgIbDAAKCRBI
|
||||
6c1W/qZo25ZSAJ98WTrtl2HiX8ZqZq95v1+9cHtZPQCfZDoWQPybkNescLmXC7q5
|
||||
1kNTmEU=
|
||||
=8QM5
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
', '
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
lQG7BELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n
|
||||
vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke
|
||||
5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO
|
||||
RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij
|
||||
8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl
|
||||
Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt
|
||||
J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/
|
||||
T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5
|
||||
0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6awAAn2F+iNBElfJS
|
||||
8azqO/kEiIfpqu6/DQG0I0VsZ2FtYWwgMjA0OCA8dGVzdDIwNDhAZXhhbXBsZS5v
|
||||
cmc+iF0EExECAB4FAkLIIgoCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQSOnN
|
||||
Vv6maNvTwwCYkpcJmpl3aHCQdGomz7dFohDgjgCgiThZt2xTEi6GhBB1vuhk+f55
|
||||
n3+dAj0EQsgiIhAIAJI3Gb2Ehtz1taQ9AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D
|
||||
29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMXMhoWyw8ZF5Zs1mLIjFGVorePrm94N3MN
|
||||
PWM7x9M36bHUjx0vCZKFIhcGY1g+htE/QweaJzNVeA5z4qZmik41FbQyQSyHa3bO
|
||||
kTZu++/U6ghP+iDp5UDBjMTkVyqITUVNgC+MR+da/I60irBVhue7younh4ovF+Cr
|
||||
VDQJC06HZl6CAJJyA81SmRfi+dmKbbjZLF6rhz0norPjISJvkIqvdtM4VPBKI5wp
|
||||
gwCzpEqjuiKrAVujRT68zvBvJ4aVqb11k5QdJscAAwUH/jVJh0HbWAoiFTe+Nvoh
|
||||
frA8vPcD0rtU3Y+siiqrabotnxJd2NuCbxghJYGfNtnx0KDjFbCRKJVeTFok4Unu
|
||||
VYhXdH/c6i0/rCTNdeW2D6pmR4GfBozRPw/ARf+jONawGLyUj7uq13iquwMSE7Vy
|
||||
NuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0RQsetMq/iNBWraayKZnWUd+eQqNzE+NUo
|
||||
7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiFZ1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qun
|
||||
fGW00ZMMTCWabg0ZgxPzMfMeIcm6525AYn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/R
|
||||
dWYAAVQKFPXbRaxbdArwRVXMzSD3qj/+VwwhwEDt8zmBGnlBfwVdkjQQrDUMmV1S
|
||||
EwyISQQYEQIACQUCQsgiIgIbDAAKCRBI6c1W/qZo25ZSAJ4sgUfHTVsG/x3p3fcM
|
||||
3b5R86qKEACggYKSwPWCs0YVRHOWqZY0pnHtLH8=
|
||||
=3Dgk
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
');
|
||||
|
||||
insert into keytbl (id, name, pubkey, seckey)
|
||||
values (3, 'elg4096', '
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
mQGiBELII7wRBACFuaAvb11cIvjJK9LkZr4cYuYhLWh3DJdojNNnLNiym5OEksvY
|
||||
05cw8OgqKtPzICU7o/mHXTWhzJYUt3i50/AeYygI8Q0uATS6RnDAKNlES1EMoHKz
|
||||
2a5iFbYs4bm4IwlkvYd8uWjcu+U0YLbxir39u+anIc6eT+q3WiH/q3zDRwCgkT98
|
||||
cnIG8iO8PdwDSP8G4Lt6TYED/R45GvCzJ4onQALLE92KkLUz8aFWSl05r84kczEN
|
||||
SxiP9Ss6m465RmwWHfwYAu4b+c4GeNyU8fIU2EM8cezchC+edEi3xu1s+pCV0Dk4
|
||||
18DGC8WKCICO30vBynuNmYg7W/7Zd4wtjss454fMW7+idVDNM701mmXBtI1nsBtG
|
||||
7Z4tA/9FxjFbJK9jh24RewfjHpLYqcfCo2SsUjOwsnMZ5yg2yv9KyVVQhRqwmrqt
|
||||
q8MRyjGmfoD9PPdCgvqgzy0hHvAHUtTm2zUczGTG+0g4hNIklxC/Mv6J4KE+NWTh
|
||||
uB4acqofHyaw2WnKOuRUsoDi6rG5AyjNMyAK/vVcEGj7J1tk27QjRWxnYW1hbCA0
|
||||
MDk2IDx0ZXN0NDA5NkBleGFtcGxlLm9yZz6IXgQTEQIAHgUCQsgjvAIbAwYLCQgH
|
||||
AwIDFQIDAxYCAQIeAQIXgAAKCRBj+HX2P2d0oAEDAJ9lI+CNmb42z3+a6TnVusM6
|
||||
FI7oLwCfUwA1zEcRdsT3nIkoYh0iKxFSDFW5BA0EQsgkdhAQAJQbLXlgcJ/jq+Xh
|
||||
Eujb77/eeftFJObNIRYD9fmJ7HFIXbUcknEpbs+cRH/nrj5dGSY3OT3jCXOUtvec
|
||||
sCoX/CpZWL0oqDjAiZtNSFiulw5Gav4gHYkWKgKdSo+2rkavEPqKIVHvMeXaJtGT
|
||||
d7v/AmL/P8T7gls93o5WFBOLtPbDvWqaKRy2U5TAhl1laiM0vGALRVjvSCgnGw9g
|
||||
FpSnXbO3AfenUSjDzZujfGLHtU44ixHSS/D4DepiF3YaYLsN4CBqZRv6FbMZD5W3
|
||||
DnJY4kS1kH0MzdcF19TlcZ3itTCcGIt1tMKf84mccPoqdMzH7vumBGTeFEly5Afp
|
||||
9berJcirqh2fzlunN0GS02z6SGWnjTbDlkNDxuxPSBbpcpNyD3jpYAUqSwRsZ/+5
|
||||
zkzcbGtDmvy9sJ5lAXkxGoIoQ1tEVX/LOHnh2NQHK8ourVOnr7MS0nozssITZJ5E
|
||||
XqtHiREjiYEuPyZiVZKJHLWuYYaF+n40znnz3sJuXFRreHhHbbvRdlYUU5mJV+XZ
|
||||
BLgKuS33NdpGeMIngnCc/9IQ6OZb6ixc94kbkd3w2PVr8CbKlu/IHTjWOO2mAo+D
|
||||
+OydlYl23FiM3KOyMP1HcEOJMB/nwkMtrvd+522Lu9n77ktKfot9IPrQDIQTyXjR
|
||||
3pCOFtCOBnk2tJHMPoG9jn9ah/LHAAMHEACDZ5I/MHGfmiKg2hrmqBu2J2j/deC8
|
||||
CpwcyDH1ovQ0gHvb9ESa+CVRU2Wdy2CD7Q9SmtMverB5eneL418iPVRcQdwRmQ2y
|
||||
IH4udlBa6ce9HTUCaecAZ4/tYBnaC0Av/9l9tz14eYcwRMDpB+bnkhgF+PZ1KAfD
|
||||
9wcY2aHbtsf3lZBc5h4owPJkxpe/BNzuJxW3q4VpSbLsZhwnCZ2wg7DRwP44wFIk
|
||||
00ptmoBY59gsU6I40XtzrF8JDr0cA57xND5RY21Z8lnnYRE1Tc8h5REps9ZIxW3/
|
||||
yl91404bPLqxczpUHQAMSTAmBaStPYX1nS51uofOhLs5SKPCUmxfGKIOhsD0oLUn
|
||||
78DnkONVGeXzBibSwwtbgfMzee4G8wSUfJ7w8WXz1TyanaGLnJ+DuKASSOrFoBCD
|
||||
HEDuWZWgSL74NOQupFRk0gxOPmqU94Y8HziQWma/cETbmD83q8rxN+GM2oBxQkQG
|
||||
xcbqMTHE7aVhV3tymbSWVaYhww3oIwsZS9oUIi1DnPEowS6CpVRrwdvLjLJnJzzV
|
||||
O3AFPn9eZ1Q7R1tNx+zZ4OOfhvI/OlRJ3HBx2L53embkbdY9gFYCCdTjPyjKoDIx
|
||||
kALgCajjCYMNUsAKNSd6mMCQ8TtvukSzkZS1RGKP27ohsdnzIVsiEAbxDMMcI4k1
|
||||
ul0LExUTCXSjeIhJBBgRAgAJBQJCyCR2AhsMAAoJEGP4dfY/Z3Sg19sAn0NDS8pb
|
||||
qrMpQAxSb7zRTmcXEFd9AJ435H0ttP/NhLHXC9ezgbCMmpXMOQ==
|
||||
=kRxT
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
', '
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
lQG7BELII7wRBACFuaAvb11cIvjJK9LkZr4cYuYhLWh3DJdojNNnLNiym5OEksvY
|
||||
05cw8OgqKtPzICU7o/mHXTWhzJYUt3i50/AeYygI8Q0uATS6RnDAKNlES1EMoHKz
|
||||
2a5iFbYs4bm4IwlkvYd8uWjcu+U0YLbxir39u+anIc6eT+q3WiH/q3zDRwCgkT98
|
||||
cnIG8iO8PdwDSP8G4Lt6TYED/R45GvCzJ4onQALLE92KkLUz8aFWSl05r84kczEN
|
||||
SxiP9Ss6m465RmwWHfwYAu4b+c4GeNyU8fIU2EM8cezchC+edEi3xu1s+pCV0Dk4
|
||||
18DGC8WKCICO30vBynuNmYg7W/7Zd4wtjss454fMW7+idVDNM701mmXBtI1nsBtG
|
||||
7Z4tA/9FxjFbJK9jh24RewfjHpLYqcfCo2SsUjOwsnMZ5yg2yv9KyVVQhRqwmrqt
|
||||
q8MRyjGmfoD9PPdCgvqgzy0hHvAHUtTm2zUczGTG+0g4hNIklxC/Mv6J4KE+NWTh
|
||||
uB4acqofHyaw2WnKOuRUsoDi6rG5AyjNMyAK/vVcEGj7J1tk2wAAoJCUNy6awTkw
|
||||
XfbLbpqh0fvDst7jDLa0I0VsZ2FtYWwgNDA5NiA8dGVzdDQwOTZAZXhhbXBsZS5v
|
||||
cmc+iF4EExECAB4FAkLII7wCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQY/h1
|
||||
9j9ndKABAwCeNEOVK87EzXYbtxYBsnjrUI948NIAn2+f3BXiBFDV5NvqPwIZ0m77
|
||||
Fwy4nQRMBELIJHYQEACUGy15YHCf46vl4RLo2++/3nn7RSTmzSEWA/X5iexxSF21
|
||||
HJJxKW7PnER/564+XRkmNzk94wlzlLb3nLAqF/wqWVi9KKg4wImbTUhYrpcORmr+
|
||||
IB2JFioCnUqPtq5GrxD6iiFR7zHl2ibRk3e7/wJi/z/E+4JbPd6OVhQTi7T2w71q
|
||||
mikctlOUwIZdZWojNLxgC0VY70goJxsPYBaUp12ztwH3p1Eow82bo3xix7VOOIsR
|
||||
0kvw+A3qYhd2GmC7DeAgamUb+hWzGQ+Vtw5yWOJEtZB9DM3XBdfU5XGd4rUwnBiL
|
||||
dbTCn/OJnHD6KnTMx+77pgRk3hRJcuQH6fW3qyXIq6odn85bpzdBktNs+khlp402
|
||||
w5ZDQ8bsT0gW6XKTcg946WAFKksEbGf/uc5M3GxrQ5r8vbCeZQF5MRqCKENbRFV/
|
||||
yzh54djUByvKLq1Tp6+zEtJ6M7LCE2SeRF6rR4kRI4mBLj8mYlWSiRy1rmGGhfp+
|
||||
NM55897CblxUa3h4R2270XZWFFOZiVfl2QS4Crkt9zXaRnjCJ4JwnP/SEOjmW+os
|
||||
XPeJG5Hd8Nj1a/AmypbvyB041jjtpgKPg/jsnZWJdtxYjNyjsjD9R3BDiTAf58JD
|
||||
La73fudti7vZ++5LSn6LfSD60AyEE8l40d6QjhbQjgZ5NrSRzD6BvY5/WofyxwAD
|
||||
BxAAg2eSPzBxn5oioNoa5qgbtido/3XgvAqcHMgx9aL0NIB72/REmvglUVNlnctg
|
||||
g+0PUprTL3qweXp3i+NfIj1UXEHcEZkNsiB+LnZQWunHvR01AmnnAGeP7WAZ2gtA
|
||||
L//Zfbc9eHmHMETA6Qfm55IYBfj2dSgHw/cHGNmh27bH95WQXOYeKMDyZMaXvwTc
|
||||
7icVt6uFaUmy7GYcJwmdsIOw0cD+OMBSJNNKbZqAWOfYLFOiONF7c6xfCQ69HAOe
|
||||
8TQ+UWNtWfJZ52ERNU3PIeURKbPWSMVt/8pfdeNOGzy6sXM6VB0ADEkwJgWkrT2F
|
||||
9Z0udbqHzoS7OUijwlJsXxiiDobA9KC1J+/A55DjVRnl8wYm0sMLW4HzM3nuBvME
|
||||
lHye8PFl89U8mp2hi5yfg7igEkjqxaAQgxxA7lmVoEi++DTkLqRUZNIMTj5qlPeG
|
||||
PB84kFpmv3BE25g/N6vK8TfhjNqAcUJEBsXG6jExxO2lYVd7cpm0llWmIcMN6CML
|
||||
GUvaFCItQ5zxKMEugqVUa8Hby4yyZyc81TtwBT5/XmdUO0dbTcfs2eDjn4byPzpU
|
||||
Sdxwcdi+d3pm5G3WPYBWAgnU4z8oyqAyMZAC4Amo4wmDDVLACjUnepjAkPE7b7pE
|
||||
s5GUtURij9u6IbHZ8yFbIhAG8QzDHCOJNbpdCxMVEwl0o3gAAckBdfKuasiNUn5G
|
||||
L5XRnSvaOFzftr8zteOlZChCSNvzH5k+i1j7RJbWq06OeKRywPzjfjgM2MvRzI43
|
||||
ICeISQQYEQIACQUCQsgkdgIbDAAKCRBj+HX2P2d0oNfbAJ9+G3SeXrk+dWwo9EGi
|
||||
hqMi2GVTsgCfeoQJPsc8FLYUgfymc/3xqAVLUtg=
|
||||
=Gjq6
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
');
|
||||
|
||||
insert into keytbl (id, name, pubkey, seckey)
|
||||
values (4, 'rsa2048', '
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
mQELBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP
|
||||
ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2
|
||||
55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx
|
||||
5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K
|
||||
MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz
|
||||
R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYptB5SU0EgMjA0OCA8cnNhMjA0
|
||||
OEBleGFtcGxlLm9yZz6JATQEEwECAB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgEC
|
||||
HgECF4AACgkQnc+OnJvTHyQqHwf8DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liR
|
||||
nrLuVlLBpdO6CWmMUzfKRvyZlx54GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzw
|
||||
bLZyM5Gb3lsE/FEmE7Dxw/0Utf59uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDP
|
||||
D3dnU4uzKPhMcjnSN00pzjusP7C9NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv
|
||||
9bgGWopumlOkt8Zu5YG6+CtTbJXprPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhv
|
||||
S3NZKoJ/1DrGgoDAu1mGkM4KvLAxfDs/qQ9dZhtEmDbKPLTVEA==
|
||||
=lR4n
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
', '
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
lQOWBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP
|
||||
ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2
|
||||
55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx
|
||||
5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K
|
||||
MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz
|
||||
R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYpAAf/QZsrrz0c7dgWwGqMIpw6
|
||||
fP+/lLa74+fa2CFRWtYowEiKsfDg/wN7Ua07036dNhPa8aZPsU6SRzm5PybKOURe
|
||||
D9pNt0FxJkX0j5pCWfjSJgTbc1rCdqZ/oyBk/U6pQtf//zfw3PbDl7I8TC6GOt2w
|
||||
5NgcXdsWHP7LAmPctOVUyzFsenevR0MFTHkMbmKI1HpFm8XN/e1Fl+qIAD+OagTF
|
||||
5B32VvpoJtkh5nxnIuToNJsa9Iy7F9MM2CeFOyTMihMcjXKBBUaAYoF115irBvqu
|
||||
7N/qWmzqLg8yxBZ56mh6meCF3+67VA2y7fL8rhw2QuqgLg1JFlKAVL+9crCSrn//
|
||||
GQQA1kT7FytW6BNOffblFYZkrJer3icoRDqa/ljgH/yVaWoVT1igy0E9XzYO7MwP
|
||||
2usj/resLy0NC1qCthk51cZ/wthooMl88e5Wb4l5FYwBEac7muSBTo4W8cAH1hFj
|
||||
TWL6XAGvEzGX3Mt9pn8uYGlQLZAhJoNCAU2EOCbN1PchDvsEAOWNKYesuUVk8+sQ
|
||||
St0NDNhd9BWtTWTHkCZb1dKC3JTfr9PqkTBLrWFbYjkOtvdPAW7FDaXXXZfdH1jH
|
||||
WfwP3Q+I6sqgSaWpCS4dBAns3/RVtO7czVgyIwma04iIvJqderYrfvkUq95KfwP2
|
||||
V8wXkhrPPPxyrg5y3wQlpY2jb5RBBAC17SK1ms+DBtck4vpdjp3SJ32SbyC/DU30
|
||||
89Q12j74S7Zdu1qZlKnvy3kWPYX/hMuSzGZ+mLVJNFEqH2X01aFzppYz0hdI9PGB
|
||||
9tTFEqZWQL9ZkXfjc79Cgnt12pNukRbtw0N/kyutOdIFHVT79wVAd+powqziXJsC
|
||||
Kc+4xjwSCkZitB5SU0EgMjA0OCA8cnNhMjA0OEBleGFtcGxlLm9yZz6JATQEEwEC
|
||||
AB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQnc+OnJvTHyQqHwf8
|
||||
DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liRnrLuVlLBpdO6CWmMUzfKRvyZlx54
|
||||
GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzwbLZyM5Gb3lsE/FEmE7Dxw/0Utf59
|
||||
uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDPD3dnU4uzKPhMcjnSN00pzjusP7C9
|
||||
NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv9bgGWopumlOkt8Zu5YG6+CtTbJXp
|
||||
rPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhvS3NZKoJ/1DrGgoDAu1mGkM4KvLAx
|
||||
fDs/qQ9dZhtEmDbKPLTVEA==
|
||||
=WKAv
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
');
|
||||
|
||||
insert into keytbl (id, name, pubkey, seckey)
|
||||
values (5, 'psw-elg1024', '
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
|
||||
tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
|
||||
xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
|
||||
klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
|
||||
YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
|
||||
PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
|
||||
jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
|
||||
saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
|
||||
IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx
|
||||
MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV
|
||||
AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc
|
||||
AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd
|
||||
ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P
|
||||
sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI
|
||||
+h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9
|
||||
6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF
|
||||
k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v
|
||||
iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F
|
||||
ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80
|
||||
=RWci
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
', '
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
lQHhBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
|
||||
tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
|
||||
xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
|
||||
klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
|
||||
YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
|
||||
PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
|
||||
jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
|
||||
saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
|
||||
IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQP4DAwL3TCgrYdj6
|
||||
+GAnoSqGa87twi8a6QRRYIlEx3ddUCDCjzkJmRfF+LFtvX3OtWWK0+Syi3kj2IK9
|
||||
YT7pF7QfRWxnYW1hbCAxMDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJC
|
||||
yCFIAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAn1ynoCyM
|
||||
6GIvHDOewwmF4Z/jGQfzAJ9Q+MwIubi0ASfJifaEM23sIHwHop0BVwRCyCFKEAQA
|
||||
h5SNbbJMAsJ+sQbcWEzdku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioym
|
||||
lDwraTKUAfuCZgNcg/0PsxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlP
|
||||
iO0wt1lLX+SubktqbYxI+h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSg
|
||||
MERiNzF0acZUYmc0e+/96gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxs
|
||||
nKjUaw/qyoaFcNMzb4sFk8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey
|
||||
9ifh8rZfu57UbdwdHa0viWc4Dilh/gMDAvdMKCth2Pr4YCCPsELdgJuzhGfDNRSg
|
||||
nKMRWBWHSJRk6JmCjM1iJQNHc4mMhR8gvi2TeqYLOhYjcF7nr/LA+JvLV+adj/mI
|
||||
SQQYEQIACQUCQsghSgIbDAAKCRAcKbwNGBdzZO2vAJ4hRaLcNcdl/qK8rt0N5zbZ
|
||||
saCh6QCfR1O48O8nYN93SPSfIFZK5rEmdv8=
|
||||
=Y6Qv
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
');
|
||||
|
||||
|
||||
-- elg1024 / aes128
|
||||
insert into encdata (id, data) values (1, '
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
hQEOA9k2z2S7c/RmEAQAgVWW0DeLrZ+1thWJGBPp2WRFL9HeNqqWHbKJCXJbz1Uy
|
||||
faUY7yxVvG5Eutmo+JMiY3mg23/DgVVXHQZsTWpGvGM6djgUNGKUjZDbW6Nog7Mr
|
||||
e78IywattCOmgUP9vIwwg3OVjuDCN/nVirGQFnXpJBc8DzWqDMWRWDy1M0ZsK7AD
|
||||
/2JTosSFxUdpON0DKtIY3GLzmh6Nk3iV0g8VgJKUBT1rhCXuMDj3snm//EMm7hTY
|
||||
PlnObq4mIhgz8NqprmhooxnU0Kapofb3P3wCHPpU14zxhXY8iKO/3JhBq2uFcx4X
|
||||
uBMwkW4AdNxY/mzJZELteTL8Tr0s7PISk+owb4URpG3n0jsBc0CVULxrjh5Ejkdw
|
||||
wCM195J6+KbQxOOFQ0b3uOVvv4dEgd/hRERCOq5EPaFhlHegyYJ7YO842vnSDA==
|
||||
=PABx
|
||||
-----END PGP MESSAGE-----
|
||||
');
|
||||
|
||||
-- elg2048 / blowfish
|
||||
insert into encdata (id, data) values (2, '
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
hQIOAywibh/+XMfUEAf+OINhBngEsw4a/IJIeJvUgv1gTQzBwOdQEuc/runr4Oa8
|
||||
Skw/Bj0X/zgABVZLem1a35NHaNwaQaCFwMQ41YyWCu+jTdsiyX/Nw0w8LKKz0rNC
|
||||
vVpG6YuV7Turtsf8a5lXy1K0SHkLlgxQ6c76GS4gtSl5+bsL2+5R1gSRJ9NXqCQP
|
||||
OHRipEiYwBPqr5R21ZG0FXXNKGOGkj6jt/M/wh3WVtAhYuBI+HPKRfAEjd/Pu/eD
|
||||
e1zYtkH1dKKFmp44+nF0tTI274xpuso7ShfKYrOK3saFWrl0DWiWteUinjSA1YBY
|
||||
m7dG7NZ8PW+g1SZWhEoPjEEEHz3kWMvlKheMRDudnQf/dDyX6kZVIAQF/5B012hq
|
||||
QyVewgTGysowFIDn01uIewoEA9cASw699jw9IoJp+k5WZXnU+INllBLzQxniQCSu
|
||||
iEcr0x3fYqNtj9QBfbIqyRcY6HTWcmzyOUeGaSyX76j+tRAvtVtXpraFFFnaHB70
|
||||
YpXTjLkp8EBafzMghFaKDeXlr2TG/T7rbwcwWrFIwPqEAUKWN5m97Q3eyo8/ioMd
|
||||
YoFD64J9ovSsgbuU5IpIGAsjxK+NKzg/2STH7zZFEVCtgcIXsTHTZfiwS98/+1H9
|
||||
p1DIDaXIcUFV2ztmcKxh9gt2sXRz1W+x6D8O0k3nanU5yGG4miLKaq18fbcA0BD1
|
||||
+NIzAfelq6nvvxYKcGcamBMgLo5JkZOBHvyr6RsAKIT5QYc0QTjysTk9l0Am3gYc
|
||||
G2pAE+3k
|
||||
=TBHV
|
||||
-----END PGP MESSAGE-----
|
||||
');
|
||||
|
||||
-- elg4096 / aes256
|
||||
insert into encdata (id, data) values (3, '
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1.4.1 (GNU/Linux)
|
||||
|
||||
hQQOA7aFBP0Sjh/5EA/+JCgncc8IZmmRjPStWnGf9tVJhgHTn+smIclibGzs0deS
|
||||
SPSCitzpblwbUDvu964+/5e5Q1l7rRuNN+AgETlEd4eppv7Swn2ChdgOXxRwukcT
|
||||
Nh3G+PTFvD4ayi7w1db3qvXIt0MwN4Alt436wJmK1oz2Ka9IcyO+wHWrDy1nSGSx
|
||||
z5x7YEj+EZPgWc/YAvudqE8Jpzd/OT5zSHN09UFkIAk6NxisKaIstbEGFgpqtoDZ
|
||||
1SJM84XAdL2IcaJ3YY7k/yzwlawhsakKd4GSd5vWmAwvyzzbSiBMfKsDE16ePLNU
|
||||
ZBF7CzmlCBPZ7YrFAHLpXBXXkCQvzD2BEYOjse50ZEfJ036T7950Ozcdy1EQbGon
|
||||
nyQ4Gh0PBpnMcBuiXOceWuYzhlzFOzDtlVKdNTxFRDcbEyW2jo9xQYvCCLnYy8EH
|
||||
2M7S8jCtVYJBbn63a82ELv+3+kWYcsvBJv2ZVBh4ncrBu9o0P+OYS7ApoOU+j6p2
|
||||
+t0RXHksqXS1YiUwYF5KSw09EbYMgNZ9G04Px/PxLU6fSC9iDrGX7Xt3kOUP0mku
|
||||
C518fPckT0zzRXqfFruJNRzDytW50KxkOQZzU1/Az1YlYN9QzWeU4EtLPb2fftZo
|
||||
D0qH/ln+f9Op5t6sD2fcxZVECU1b/bFtZsxvwH406YL+UQ7hU/XnZrzVVzODal8P
|
||||
/j1hg7v7BdJqu1DTp9nFWUuwMFcYAczuXn29IG183NZ7Ts4whDeYEhS8eNoLPX4j
|
||||
txY12ILD/w/3Q4LoW/hPa6OdfEzsn0U5GLf1WiGmJE1H6ft2U/xUnerc/u0kt+FU
|
||||
WAisArd4MuKtf7B5Vu/VF3kUdrR0hTniUKUivmC4o1jSId31Dufxj4aadVyldXAr
|
||||
6TNBcdyragZjxEZ6hsBCYzA0Rd1a8atd6OaQoIEEfAzCu5Ks29pydHErStYGjWJ1
|
||||
KA5KPLVvjbHpDmRhlCcm8vgpYQsBYEB5gE9fx5yCTlsVhCB6y23h7hfdMqerDqkO
|
||||
ZOPsO5h+tiHCdIrQ36sMjuINy1/K2rYcXd+Crh2iHcfidpU9fvDz2ihTRNQlhjuT
|
||||
0cQZM5JhctEx4VXF4LDctRhit7Hn0iqsk604woQfJVvP8O673xSXT/kBY0A/v9C0
|
||||
3C4YoFNeSaKwbfZQ/4u1ZFPJxK2IIJa8UGpyAUewLMlzGVVagljybv/f4Z9ERAhy
|
||||
huq5sMmw8UPsrJF2TUGHz5WSIwoh0J/qovoQI09I9sdEnFczDvRavMO2Mldy3E5i
|
||||
exz9oewtel6GOmsZQSYWT/vJzbYMmvHNmNpVwwoKrLV6oI3kyQ80GHBwI1WlwHoK
|
||||
2iRB0w8q4VVvJeYAz8ZIp380cqC3pfO0uZsrOx4g3k4X0jsB5y7rF5xXcZfnVbvG
|
||||
DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglTVTfYmi1ToZDDipkALBhndQ==
|
||||
=L/M/
|
||||
-----END PGP MESSAGE-----
|
||||
');
|
||||
|
||||
-- successful decrypt
|
||||
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
|
||||
from keytbl, encdata where keytbl.id=1 and encdata.id=1;
|
||||
|
||||
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
|
||||
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;
|
||||
|
||||
-- wrong key
|
||||
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
|
||||
from keytbl, encdata where keytbl.id=2 and encdata.id=1;
|
||||
|
||||
-- sign-only key
|
||||
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
|
||||
from keytbl, encdata where keytbl.id=4 and encdata.id=1;
|
||||
|
||||
-- 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;
|
||||
|
||||
-- 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;
|
||||
|
||||
-- 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;
|
||||
|
45
contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql
Normal file
45
contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql
Normal file
@ -0,0 +1,45 @@
|
||||
--
|
||||
-- PGP Public Key Encryption
|
||||
--
|
||||
|
||||
-- successful encrypt/decrypt
|
||||
select pgp_pub_decrypt(
|
||||
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
|
||||
dearmor(seckey))
|
||||
from keytbl where keytbl.id=1;
|
||||
|
||||
select pgp_pub_decrypt(
|
||||
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
|
||||
dearmor(seckey))
|
||||
from keytbl where keytbl.id=2;
|
||||
|
||||
select pgp_pub_decrypt(
|
||||
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
|
||||
dearmor(seckey))
|
||||
from keytbl where keytbl.id=3;
|
||||
|
||||
-- try with rsa-sign only
|
||||
select pgp_pub_decrypt(
|
||||
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
|
||||
dearmor(seckey))
|
||||
from keytbl where keytbl.id=4;
|
||||
|
||||
-- try with secret key
|
||||
select pgp_pub_decrypt(
|
||||
pgp_pub_encrypt('Secret msg', dearmor(seckey)),
|
||||
dearmor(seckey))
|
||||
from keytbl where keytbl.id=1;
|
||||
|
||||
-- does text-to-bytea works
|
||||
select pgp_pub_decrypt_bytea(
|
||||
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
|
||||
dearmor(seckey))
|
||||
from keytbl where keytbl.id=1;
|
||||
|
||||
-- and bytea-to-text?
|
||||
select pgp_pub_decrypt(
|
||||
pgp_pub_encrypt_bytea('Secret msg', dearmor(pubkey)),
|
||||
dearmor(seckey))
|
||||
from keytbl where keytbl.id=1;
|
||||
|
||||
|
3
contrib/pgcrypto/sql/pgp-zlib-DISABLED.sql
Normal file
3
contrib/pgcrypto/sql/pgp-zlib-DISABLED.sql
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
-- zlib is disabled
|
||||
|
28
contrib/pgcrypto/sql/sha2.sql
Normal file
28
contrib/pgcrypto/sql/sha2.sql
Normal file
@ -0,0 +1,28 @@
|
||||
--
|
||||
-- SHA2 family
|
||||
--
|
||||
|
||||
-- SHA256
|
||||
SELECT encode(digest('', 'sha256'), 'hex');
|
||||
SELECT encode(digest('a', 'sha256'), 'hex');
|
||||
SELECT encode(digest('abc', 'sha256'), 'hex');
|
||||
SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha256'), 'hex');
|
||||
SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha256'), 'hex');
|
||||
|
||||
-- SHA384
|
||||
SELECT encode(digest('', 'sha384'), 'hex');
|
||||
SELECT encode(digest('a', 'sha384'), 'hex');
|
||||
SELECT encode(digest('abc', 'sha384'), 'hex');
|
||||
SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha384'), 'hex');
|
||||
SELECT encode(digest('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu', 'sha384'), 'hex');
|
||||
SELECT encode(digest('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz', 'sha384'), 'hex');
|
||||
|
||||
-- SHA512
|
||||
SELECT encode(digest('', 'sha512'), 'hex');
|
||||
SELECT encode(digest('a', 'sha512'), 'hex');
|
||||
SELECT encode(digest('abc', 'sha512'), 'hex');
|
||||
SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha512'), 'hex');
|
||||
SELECT encode(digest('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu', 'sha512'), 'hex');
|
||||
SELECT encode(digest('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz', 'sha512'), 'hex');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user