OpenSSL 0.9.6x. The DES functions use the older 'des_'
API, but the newer 3DES functions use the 0.9.7x-only
'DES_' API.
I think I just used /usr/include/openssl/des.h for reference
when implementing them, and had upgraded OpenSSL in the
meantime.
Following patch converts DES also to newer API and provides
compatibility functions for OpenSSL < 0.9.7.
I chose this route because:
- openssl.c uses few DES functions.
- compatibility for old 'des_' API is going away at some point
of time from OpenSSL.
- as seen from macros, new API is saner
- Thus pgcrypto supports any OpenSSL version from 0.9.5 to 1.0
Tested with OpenSSL 0.9.6c and 0.9.7e.
Marko Kreen
of password-based encryption from RFC2440 (OpenPGP).
The goal of this code is to be more featureful encryption solution
than current encrypt(), which only functionality is running cipher
over data.
Compared to encrypt(), pgp_encrypt() does following:
* It uses the equvialent of random Inital Vector to get cipher
into random state before it processes user data
* Stores SHA-1 of the data into result so any modification
will be detected.
* Remembers if data was text or binary - thus it can decrypt
to/from text data. This was a major nuisance for encrypt().
* Stores info about used algorithms with result, so user needs
not remember them - more user friendly!
* Uses String2Key algorithms (similar to crypt()) with random salt
to generate full-length binary key to be used for encrypting.
* Uses standard format for data - you can feed it to GnuPG, if needed.
Optional features (off by default):
* Can use separate session key - user data will be encrypted
with totally random key, which will be encrypted with S2K
generated key and attached to result.
* Data compression with zlib.
* Can convert between CRLF<->LF line-endings - to get fully
RFC2440-compliant behaviour. This is off by default as
pgcrypto does not know the line-endings of user data.
Interface is simple:
pgp_encrypt(data text, key text) returns bytea
pgp_decrypt(data text, key text) returns text
pgp_encrypt_bytea(data bytea, key text) returns bytea
pgp_decrypt_bytea(data bytea, key text) returns bytea
To change parameters (cipher, compression, mdc):
pgp_encrypt(data text, key text, parms text) returns bytea
pgp_decrypt(data text, key text, parms text) returns text
pgp_encrypt_bytea(data bytea, key text, parms text) returns bytea
pgp_decrypt_bytea(data bytea, key text, parms text) returns bytea
Parameter names I lifted from gpg:
pgp_encrypt('message', 'key', 'compress-algo=1,cipher-algo=aes256')
For text data, pgp_encrypt simply encrypts the PostgreSQL internal data.
This maps to RFC2440 data type 't' - 'extenally specified encoding'.
But this may cause problems if data is dumped and reloaded into database
which as different internal encoding. My next goal is to implement data
type 'u' - which means data is in UTF-8 encoding by converting internal
encoding to UTF-8 and back. And there wont be any compatibility
problems with current code, I think its ok to submit this without UTF-8
encoding by converting internal encoding to UTF-8 and back. And there
wont be any compatibility problems with current code, I think its ok to
submit this without UTF-8 support.
Here is v4 of PGP encrypt. This depends on previously sent
Fortuna-patch, as it uses the px_add_entropy function.
- New function: pgp_key_id() for finding key id's.
- Add SHA1 of user data and key into RNG pools. We need to get
randomness from somewhere, and it is in user best interests
to contribute.
- Regenerate pgp-armor test for SQL_ASCII database.
- Cleanup the key handling so that the pubkey support is less
hackish.
Marko Kreen
- Move openssl random provider to openssl.c and builtin provider
to internal.c
- Make px_random_bytes use Fortuna, instead of giving error.
- Retarget random.c to aquiring system randomness, for initial seeding
of Fortuna. There is ATM 2 functions for Windows,
reader from /dev/urandom and the regular time()/getpid() silliness.
Marko Kreen
functions as STRICT, and all functions except gen_salt() as IMMUTABLE.
gen_salt() is VOLATILE.
Although the functions are now STRICT, I left their PG_ARGISNULL()
checks in place as a protective measure for users who install the
new code but use old (non-STRICT) catalog entries (e.g., restored
from a dump). Per recent discussion in pgsql-hackers.
Patch from Michael Fuhr.
to make. We ship the table file in the tarball and so this dependency
just opens file timestamp skew problems without doing anything useful.
(Not that it should hurt, either ... except for cross-compile builds.)
(currently in beta) when cryptolib = openssl. According to the
following checkin message from several years ago, OpenSSL application
developers should no longer rely on <openssl/evp.h> to include
everything they need:
http://cvs.openssl.org/chngview?cn=9888
This patch adds the necessary header files. It doesn't appear to
break anything when building against OpenSSL 0.9.7.
BTW, core appears to build and work fine with OpenSSL 0.9.8. I've
built 7.3 through HEAD against 0.9.8-beta6 without noticing any
problems.
Michael Fuhr
* test error handling
* add tests for des, 3des, cast5
* add some tests to blowfish, rijndael
* Makefile: ability to specify different tests for different crypto
libraries, so we can skip des, 3des and cast5 for builtin.
Marko Kreen
Reserve px_get_random_bytes() for strong randomness,
add new function px_get_pseudo_random_bytes() for
weak randomness and use it in gen_salt().
On openssl case, use RAND_pseudo_bytes() for
px_get_pseudo_random_bytes().
Final result is that is user has not configured random
souce but kept the 'silly' one, gen_salt() keeps
working, but pgp_encrypt() will throw error.
Marko Kreen
* openssl.c: Add 3des and AES support
* README.pgcrypto: list only supported ciphers for openssl
OpenSSL has pre-processor symbol OPENSSL_NO_AES, which
isn't that helpful for detecting if it _does_ exist.
Thus the hack with AES_ENCRYPT.
Marko Kreen
* Use error codes instead of -1
* px_strerror for new error codes
* calling convention change for px_gen_salt - return error code
* use px_strerror in pgcrypto.c
Marko Kreen
It was a bad style to begin with, and now several loops can be clearer.
* pgcrypto.c: Fix function comments
* crypt-gensalt.c, crypt-blowfish.c: stop messing with errno
* openssl.c: use px_free instead pfree
* px.h: make redefining px_alloc/px_realloc/px_free easier
Marko Kreen
libmcrypt seems to dead, maintainer address bounces,
and cast-128 fails on 2 of the 3 test vectors from RFC2144.
So I see no reason to keep around stuff I don't trust
anymore.
Support for several crypto libraries is probably only
confusing to users, although it was good for initial
developing - it helped to find hidden assumptions and
forced me to create regression tests for all functionality.
Marko Kreen
0.9.7x have EVP_DigestFinal function which which clears all of
EVP_MD_CTX. This makes pgcrypto crash in functions which
re-use one digest context several times: hmac() and crypt()
with md5 algorithm.
Following patch fixes it by carring the digest info around
EVP_DigestFinal and re-initializing cipher.
Marko Kreen.
>
> The patch adds missing the "libpgport.a" file to the installation under
> "install-all-headers". It is needed by some contribs. I install the
> library in "pkglibdir", but I was wondering whether it should be "libdir"?
> I was wondering also whether it would make sense to have a "libpgport.so"?
>
> It fixes various macros which are used by contrib makefiles, especially
> libpq_*dir and LDFLAGS when used under PGXS. It seems to me that they are
> needed to
>
> It adds the ability to test and use PGXS with contribs, with "make
> USE_PGXS=1". Without the macro, this is exactly as before, there should be
> no difference, esp. wrt the vpath feature that seemed broken by previous
> submission. So it should not harm anybody, and it is useful at least to me.
>
> It fixes some inconsistencies in various contrib makefiles
> (useless override, ":=" instead of "=").
Fabien COELHO
conversion of basic ASCII letters. Remove all uses of strcasecmp and
strncasecmp in favor of new functions pg_strcasecmp and pg_strncasecmp;
remove most but not all direct uses of toupper and tolower in favor of
pg_toupper and pg_tolower. These functions use the same notions of
case folding already developed for identifier case conversion. I left
the straight locale-based folding in place for situations where we are
just manipulating user data and not trying to match it to built-in
strings --- for example, the SQL upper() function is still locale
dependent. Perhaps this will prove not to be what's wanted, but at
the moment we can initdb and pass regression tests in Turkish locale.
only remnant of this failed experiment is that the server will take
SET AUTOCOMMIT TO ON. Still TODO: provide some client-side autocommit
logic in libpq.
is pgcrypto bug as it assumed too much about inner workings of OpenSSL.
Following patch stops pgcrypto using EVP* functions for ciphers and lets
it manage ciphers itself.
This patch supports Blowfish, DES and CAST5 algorithms.
Marko Kreen
Create objects in public schema.
Make spacing/capitalization consistent.
Remove transaction block use for object creation.
Remove unneeded function GRANTs.
o Change all current CVS messages of NOTICE to WARNING. We were going
to do this just before 7.3 beta but it has to be done now, as you will
see below.
o Change current INFO messages that should be controlled by
client_min_messages to NOTICE.
o Force remaining INFO messages, like from EXPLAIN, VACUUM VERBOSE, etc.
to always go to the client.
o Remove INFO from the client_min_messages options and add NOTICE.
Seems we do need three non-ERROR elog levels to handle the various
behaviors we need for these messages.
Regression passed.
Marko Kreen says:
This is so obvious that I would like to make it 'official'.
Seems like the theology around bytea<>text casting kept me from
seeing the simple :)
wrote:
> > > Just testing pgcrypto on freebsd/alpha. I get some warnings:
> > They should be harmless, although I should fix them.
>
> The actual code is:
>
> if ((dlen & 15) || (((unsigned) res) & 3))
> return -1;
> Hard to imagine how (uint *) & 3 makes any sense, unless res isn't
> always a (uint8 *). Is that true?
At some point it was casted to (uint32*) so I wanted to be sure its ok.
ATM its pointless. Please apply the following patch.
--
marko
produces garbage.
I learned the hard way that
#if UNDEFINED_1 == UNDEFINED_2
#error "gcc is idiot"
#endif
prints "gcc is idiot" ...
Affected are MD5/SHA1 in internal library, and also HMAC-MD5/HMAC-SHA1/
crypt-md5 which use them. Blowfish is ok, also Rijndael on at
least x86.
Big thanks to Daniel Holtzman who send me a build log which
contained warning:
md5.c:246: warning: `X' defined but not used
Yes, gcc is that helpful...
Please apply this.
--
marko
failures on FreeBSD. This patch replaces uint -> unsigned.
This was reported by Daniel Holtzman against 0.4pre3 standalone
package, but it needs fixing in contrib/pgcrypto too.
Marko Kreen
these macros fail in if/else cases:
#define X \
{ \
... \
}
{
if (...)
X;
else
...
}
with proper setup:
#define X \
do { \
... \
} while (0)
it works fine.
Converted pgcrypto one too.
* Changed default randomness source to libc random()
That way pgcrypto does not have any external dependencies
and should work everywhere.
* Re-enabled pgcrypto build in contrib/makefile
* contrib/README update - there is more stuff than
only 'hash functions'
* Noted the libc random fact in README.pgcrypto
Marko Kreen
salt generation code. He also urged using better random source
and making possible to choose using bcrypt and xdes rounds more
easily. So, here's patch:
* For all salt generation, use Solar Designer's own code. This
is mostly due fact that his code is more fit for get_random_bytes()
style interface.
* New function: gen_salt(type, rounds). This lets specify iteration
count for algorithm.
* random.c: px_get_random_bytes() function.
Supported randomness soure: /dev/urandom, OpenSSL PRNG, libc random()
Default: /dev/urandom.
* Draft description of C API for pgcrypto functions.
New files: API, crypt-gensalt.c, random.c
Marko Kreen
under libdir, for a cleaner separation in the installation layout
and compatibility with binary packaging standards. Point backend's
default search location there. The contrib modules are also
installed in the said location, giving them the benefit of the
default search path as well. No changes in user interface
nevertheless.
* remove support for encode() as it is in main tree now
* remove krb5.c
* new 'PX library' architecture
* remove BSD license from my code to let the general
PostgreSQL one to apply
* md5, sha1: ANSIfy, use const where appropriate
* various other formatting and clarity changes
* hmac()
* UN*X-like crypt() - system or internal crypt
* Internal crypt: DES, Extended DES, MD5, Blowfish
crypt-des.c, crypt-md5.c from FreeBSD
crypt-blowfish.c from Solar Designer
* gen_salt() for crypt() - Blowfish, MD5, DES, Extended DES
* encrypt(), decrypt(), encrypt_iv(), decrypt_iv()
* Cipher support in mhash.c, openssl.c
* internal: Blowfish, Rijndael-128 ciphers
* blf.[ch], rijndael.[ch] from OpenBSD
* there will be generated file rijndael-tbl.inc.
Marko Kreen
Cygwin with the possible exception of mSQL-interface. Since I don't
have mSQL installed, I skipped this tool.
Except for dealing with a missing getopt.h (oid2name) and HUGE (seg),
the bulk of the patch uses the standard PostgreSQL approach to deal with
Windows DLL issues.
I tested the build aspect of this patch under Cygwin and Linux without
any ill affects. Note that I did not actually attempt to test the code
for functionality.
The procedure to apply the patch is as follows:
$ # save the attachment as /tmp/contrib.patch
$ # change directory to the top of the PostgreSQL source tree
$ patch -p0 </tmp/contrib.patch
Jason
> Postgres 7.1.0), and I think I've found a bug.
>
> I compiled Pgcrypto with OpenSSL, using gcc 2.95.4 and
> OpenSSL 0.9.6a (the latest Debian 'unstable' packages).
> web=> select encode(digest('blah', 'sha1'), 'base64');
> FATAL 1: pg_encode: overflow, encode estimate too small
> pqReadData() -- backend closed the channel unexpectedly.
> This probably means the backend terminated abnormally
> before or while processing the request.
> The connection to the server was lost. Attempting reset: Succeeded.
> Is this a bug? Can it be fixed?
This is a bug alright. And a silly one :)
Marko Kreen
* reverse the change #include <> -> "" in krb.c.
It _must not_ include files in "."
* Makefile update. Inconsistent var usage and SHLIB was
not set.
Now it should work with all external libs.
arko Kreen
are now separate files "postgres.h" and "postgres_fe.h", which are meant
to be the primary include files for backend .c files and frontend .c files
respectively. By default, only include files meant for frontend use are
installed into the installation include directory. There is a new make
target 'make install-all-headers' that adds the whole content of the
src/include tree to the installed fileset, for use by people who want to
develop server-side code without keeping the complete source tree on hand.
Cleaned up a whole lot of crufty and inconsistent header inclusions.
timing, I know :)) At the moment the digest() function returns
hexadecimal coded hash, but I want it to return pure binary. I
have also included functions encode() and decode() which support
'base64' and 'hex' encodings, so if anyone needs digest() in hex
he can do encode(digest(...), 'hex').
Main reason for it is "to do one thing and do it well" :)
Another reason is if someone needs really lot of digesting, in
the end he wants to store the binary not the hexadecimal result.
It is really silly to convert it to hex then back to binary
again. As I said if someone needs hex he can get it.
Well, and the real reason that I am doing encrypt()/decrypt()
functions and _they_ return binary. For testing I like to see
it in hex occasionally, but it is really wrong to let them
return hex. Only now it caught my eye that hex-coding in
digest() is wrong. When doing digest() I thought about 'common
case' but hacking with psql is probably _not_ the common case :)
Marko Kreen
entry:
----------------------------
revision 1.2
date: 2000/12/04 01:20:38; author: tgl; state: Exp; lines:
+18 -18
Eliminate some of the more blatant platform-dependencies ... it
builds here now, anyway ...
----------------------------
Which basically changes u_int*_t -> uint*_t, so now it does not
compile neither under Debian 2.2 nor under NetBSD 1.5 which
is platform independent<B8> all right. Also it replaces $KAME$
with $Id$ which is Bad Thing. PostgreSQL Id should be added as a
separate line so the file history could be seen.
So here is patch:
* changes uint*_t -> uint*. I guess that was the original
intention
* adds uint64 type to include/c.h because its needed
[somebody should check if I did it right]
* adds back KAME Id, because KAME is the master repository
* removes stupid c++ comments in pgcrypto.c
* removes <sys/types.h> from the code, its not needed
--
marko
Marko Kreen
in pghackers list. Support for oldstyle internal functions is gone
(no longer needed, since conversion is complete) and pg_language entry
'internal' now implies newstyle call convention. pg_language entry
'newC' is gone; both old and newstyle dynamically loaded C functions
are now called language 'C'. A newstyle function must be identified
by an associated info routine. See src/backend/utils/fmgr/README.