Commit 0c0dde61 authored by Peter Eisentraut's avatar Peter Eisentraut

Hashing functions from Marko Kreen <marko@l-t.ee>

parent 73874a06
# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.8 2000/09/18 20:11:34 petere Exp $ # $Header: /cvsroot/pgsql/contrib/Makefile,v 1.9 2000/10/31 13:11:28 petere Exp $
subdir = contrib subdir = contrib
top_builddir = .. top_builddir = ..
...@@ -17,6 +17,7 @@ WANTED_DIRS = array \ ...@@ -17,6 +17,7 @@ WANTED_DIRS = array \
noupdate \ noupdate \
pg_dumplo \ pg_dumplo \
pgbench \ pgbench \
pgcrypto \
soundex \ soundex \
spi \ spi \
string \ string \
......
#
# $Header: /cvsroot/pgsql/contrib/pgcrypto/Makefile,v 1.1 2000/10/31 13:11:28 petere Exp $
#
subdir = contrib/pgcrypto
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
# either 'builtin', 'mhash', 'openssl', 'krb5'
cryptolib = builtin
##########################
ifeq ($(cryptolib), builtin)
SRCS= md5.c sha1.c internal.c
endif
ifeq ($(cryptolib), openssl)
cryptoinc := -I/usr/include/openssl
cryptolib := -lcrypto
SRCS = openssl.c
endif
ifeq ($(cryptolib), mhash)
cryptoinc=
cryptolib=-lmhash
SRCS=mhash.c
endif
ifeq ($(cryptolib), krb5)
cryptoinc=-I/usr/include
cryptolib=-ldes
SRCS=krb.c
endif
NAME := pgcrypto
SRCS += pgcrypto.c
OBJS := $(SRCS:.c=.o)
SO_MAJOR_VERSION = 0
SO_MINOR_VERSION = 1
override CPPFLAGS += -I$(srcdir) $(cryptoinc)
all: all-lib $(NAME).sql
include $(top_srcdir)/src/Makefile.shlib
$(NAME).sql: $(NAME).sql.in
sed 's,@MODULE_FILENAME@,$(libdir)/contrib/pgcrypto$(DLSUFFIX),g' $< >$@
install: all installdirs
$(INSTALL_SHLIB) $(shlib) $(DESTDIR)$(libdir)/contrib/pgcrypto$(DLSUFFIX)
$(INSTALL_DATA) $(NAME).sql $(DESTDIR)$(datadir)/contrib/$(NAME).sql
$(INSTALL_DATA) README.$(NAME) $(DESTDIR)$(docdir)/contrib/README.$(NAME)
installdirs:
$(mkinstalldirs) $(libdir)/contrib $(datadir)/contrib $(docdir)/contrib
uninstall: uninstall-lib
rm -f $(DESTDIR)$(libdir)/contrib/pgcrypto$(DLSUFFIX) $(datadir)/contrib/$(NAME).sql $(docdir)/contrib/README.$(NAME)
clean distclean maintainer-clean: clean-lib
rm -f $(OBJS) $(NAME).sql
DESCRIPTION
Here is a implementation of crypto hashes for PostgreSQL.
It exports 2 functions to SQL level:
digest(data::text, hash_name::text)
which returns hexadecimal coded hash over data by
specified algorithm. eg
> select digest('blah', 'sha1');
5bf1fd927dfb8679496a2e6cf00cbe50c1c87145
digest_exists(hash_name::text)::bool
which reports if particular hash type exists.
If any of arguments are NULL they return NULL.
HASHES
For choosing library you must edit Makefile.
standalone (default):
MD5, SHA1
(the code is from KAME project. Actually I hate code
duplication, but I also want to quarantee that MD5 and
SHA1 exist)
mhash (0.8.1):
MD5, SHA1, CRC32, CRC32B, GOST, TIGER, RIPEMD160,
HAVAL(256,224,192,160,128)
openssl:
MD5, SHA1, RIPEMD160, MD2
kerberos5 (heimdal):
MD5, SHA1
/*
* internal.c
* Wrapper for builtin functions
*
* Copyright (c) 2000 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.
*
* $Id: internal.c,v 1.1 2000/10/31 13:11:28 petere Exp $
*/
#include <postgres.h>
#include "pgcrypto.h"
#include "md5.h"
#include "sha1.h"
#ifndef MD5_DIGEST_LENGTH
#define MD5_DIGEST_LENGTH 16
#endif
#ifndef SHA1_DIGEST_LENGTH
#ifdef SHA1_RESULTLEN
#define SHA1_DIGEST_LENGTH SHA1_RESULTLEN
#else
#define SHA1_DIGEST_LENGTH 20
#endif
#endif
static uint
pg_md5_len(pg_digest *h);
static uint8 *
pg_md5_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf);
static uint
pg_sha1_len(pg_digest *h);
static uint8 *
pg_sha1_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf);
static pg_digest
int_digest_list [] = {
{ "md5", pg_md5_len, pg_md5_digest, {0}},
{ "sha1", pg_sha1_len, pg_sha1_digest, {0}},
{ NULL, NULL, NULL, {0}}
};
static uint
pg_md5_len(pg_digest *h) {
return MD5_DIGEST_LENGTH;
}
static uint8 *
pg_md5_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf)
{
MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx, src, len);
MD5Final(buf, &ctx);
return buf;
}
static uint
pg_sha1_len(pg_digest *h) {
return SHA1_DIGEST_LENGTH;
}
static uint8 *
pg_sha1_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf)
{
SHA1_CTX ctx;
SHA1Init(&ctx);
SHA1Update(&ctx, src, len);
SHA1Final(buf, &ctx);
return buf;
}
pg_digest *
pg_find_digest(pg_digest *h, char *name)
{
pg_digest *p;
for (p = int_digest_list; p->name; p++)
if (!strcasecmp(p->name, name))
return p;
return NULL;
}
/*
* krb.c
* Wrapper for Kerberos5 libdes SHA1/MD5.
*
* Copyright (c) 2000 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.
*
*
* NOTES
* It is possible that this works with other SHA1/MD5
* implementations too.
*
* $Id: krb.c,v 1.1 2000/10/31 13:11:28 petere Exp $
*/
#include <postgres.h>
#include "pgcrypto.h"
#include <md5.h>
#include <sha.h>
#ifndef MD5_DIGEST_LENGTH
#define MD5_DIGEST_LENGTH 16
#endif
#ifndef SHA1_DIGEST_LENGTH
#ifdef SHA1_RESULTLEN
#define SHA1_DIGEST_LENGTH SHA1_RESULTLEN
#else
#define SHA1_DIGEST_LENGTH 20
#endif
#endif
static uint
pg_md5_len(pg_digest *h);
static uint8 *
pg_md5_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf);
static uint
pg_sha1_len(pg_digest *h);
static uint8 *
pg_sha1_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf);
static pg_digest
int_digest_list [] = {
{ "md5", pg_md5_len, pg_md5_digest, {0}},
{ "sha1", pg_sha1_len, pg_sha1_digest, {0}},
{ NULL, NULL, NULL, {0}}
};
static uint
pg_md5_len(pg_digest *h) {
return MD5_DIGEST_LENGTH;
}
static uint8 *
pg_md5_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf)
{
MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx, src, len);
MD5Final(buf, &ctx);
return buf;
}
static uint
pg_sha1_len(pg_digest *h) {
return SHA1_DIGEST_LENGTH;
}
static uint8 *
pg_sha1_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf)
{
SHA1_CTX ctx;
SHA1Init(&ctx);
SHA1Update(&ctx, src, len);
SHA1Final(buf, &ctx);
return buf;
}
pg_digest *
pg_find_digest(pg_digest *h, char *name)
{
pg_digest *p;
for (p = int_digest_list; p->name; p++)
if (!strcasecmp(p->name, name))
return p;
return NULL;
}
This diff is collapsed.
/* $KAME: md5.h,v 1.3 2000/02/22 14:01:18 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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 project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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.
*/
#ifndef _NETINET6_MD5_H_
#define _NETINET6_MD5_H_
#define MD5_BUFLEN 64
typedef struct {
union {
u_int32_t md5_state32[4];
u_int8_t md5_state8[16];
} md5_st;
#define md5_sta md5_st.md5_state32[0]
#define md5_stb md5_st.md5_state32[1]
#define md5_stc md5_st.md5_state32[2]
#define md5_std md5_st.md5_state32[3]
#define md5_st8 md5_st.md5_state8
union {
u_int64_t md5_count64;
u_int8_t md5_count8[8];
} md5_count;
#define md5_n md5_count.md5_count64
#define md5_n8 md5_count.md5_count8
u_int md5_i;
u_int8_t md5_buf[MD5_BUFLEN];
} md5_ctxt;
extern void md5_init __P((md5_ctxt *));
extern void md5_loop __P((md5_ctxt *, u_int8_t *, u_int));
extern void md5_pad __P((md5_ctxt *));
extern void md5_result __P((u_int8_t *, md5_ctxt *));
/* compatibility */
#define MD5_CTX md5_ctxt
#define MD5Init(x) md5_init((x))
#define MD5Update(x, y, z) md5_loop((x), (y), (z))
#define MD5Final(x, y) \
do { \
md5_pad((y)); \
md5_result((x), (y)); \
} while (0)
#endif /* ! _NETINET6_MD5_H_*/
/*
* mhash.c
* Wrapper for mhash library.
*
* Copyright (c) 2000 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.
*
* $Id: mhash.c,v 1.1 2000/10/31 13:11:28 petere Exp $
*/
#include <postgres.h>
#include "pgcrypto.h"
#include <mhash.h>
static uint
pg_mhash_len(pg_digest *hash);
static uint8 *
pg_mhash_digest(pg_digest *hash, uint8 *src,
uint len, uint8 *buf);
static uint
pg_mhash_len(pg_digest *h) {
return mhash_get_block_size(h->misc.code);
}
static uint8 *
pg_mhash_digest(pg_digest *h, uint8 *src, uint len, uint8 *dst)
{
uint8 *res;
MHASH mh = mhash_init(h->misc.code);
mhash(mh, src, len);
res = mhash_end(mh);
memcpy(dst, res, mhash_get_block_size(h->misc.code));
mhash_free(res);
return dst;
}
pg_digest *
pg_find_digest(pg_digest *h, char *name)
{
size_t hnum, i, b;
char *mname;
hnum = mhash_count();
for (i = 0; i <= hnum; i++) {
mname = mhash_get_hash_name(i);
if (mname == NULL)
continue;
b = strcasecmp(name, mname);
free(mname);
if (!b) {
h->name = mhash_get_hash_name(i);
h->length = pg_mhash_len;
h->digest = pg_mhash_digest;
h->misc.code = i;
return h;
}
}
return NULL;
}
/*
* openssl.c
* Wrapper for OpenSSL library.
*
* Copyright (c) 2000 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.
*
* $Id: openssl.c,v 1.1 2000/10/31 13:11:28 petere Exp $
*/
#include <postgres.h>
#include "pgcrypto.h"
#include <evp.h>
static uint
pg_ossl_len(pg_digest *h);
static uint8 *
pg_ossl_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf);
static uint
pg_ossl_len(pg_digest *h) {
return EVP_MD_size((EVP_MD*)h->misc.ptr);
}
static uint8 *
pg_ossl_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf)
{
EVP_MD *md = (EVP_MD*)h->misc.ptr;
EVP_MD_CTX ctx;
EVP_DigestInit(&ctx, md);
EVP_DigestUpdate(&ctx, src, len);
EVP_DigestFinal(&ctx, buf, NULL);
return buf;
}
static int pg_openssl_initialized = 0;
pg_digest *
pg_find_digest(pg_digest *h, char *name)
{
const EVP_MD *md;
if (!pg_openssl_initialized) {
OpenSSL_add_all_digests();
pg_openssl_initialized = 1;
}
md = EVP_get_digestbyname(name);
if (md == NULL)
return NULL;
h->name = name;
h->length = pg_ossl_len;
h->digest = pg_ossl_digest;
h->misc.ptr = (void*)md;
return h;
}
/*
* pgcrypto.c
* Cryptographic digests for PostgreSQL.
*
* Copyright (c) 2000 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.
*
* $Id: pgcrypto.c,v 1.1 2000/10/31 13:11:28 petere Exp $
*/
#include <postgres.h>
#include <utils/builtins.h>
#include "pgcrypto.h"
/*
* maximum length of digest for internal buffers
*/
#define MAX_DIGEST_LENGTH 128
/*
* NAMEDATALEN is used for hash names
*/
#if NAMEDATALEN < 16
#error "NAMEDATALEN < 16: too small"
#endif
/* exported functions */
Datum digest(PG_FUNCTION_ARGS);
Datum digest_exists(PG_FUNCTION_ARGS);
/* private stuff */
static char *
to_hex(uint8 *src, uint len, char *dst);
static pg_digest *
find_digest(pg_digest *hbuf, text *name, int silent);
/* SQL function: hash(text, text) returns text */
Datum
digest(PG_FUNCTION_ARGS)
{
text *arg;
text *name;
uint8 *p, buf[MAX_DIGEST_LENGTH];
uint len, hlen;
pg_digest *h, _hbuf;
text *res;
if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
PG_RETURN_NULL();
name = PG_GETARG_TEXT_P(1);
h = find_digest(&_hbuf, name, 0); /* will give error if fails */
hlen = h->length(h);
if (hlen > MAX_DIGEST_LENGTH)
elog(ERROR, "Hash length overflow: %d", hlen);
res = (text *)palloc(hlen*2 + VARHDRSZ);
VARATT_SIZEP(res) = hlen*2 + VARHDRSZ;
arg = PG_GETARG_TEXT_P(0);
len = VARSIZE(arg) - VARHDRSZ;
p = h->digest(h, VARDATA(arg), len, buf);
to_hex(p, hlen, VARDATA(res));
PG_FREE_IF_COPY(arg, 0);
PG_FREE_IF_COPY(name, 0); // unnecessary i guess
PG_RETURN_TEXT_P(res);
}
/* check if given hash exists */
Datum
digest_exists(PG_FUNCTION_ARGS)
{
text *name;
pg_digest _hbuf, *res;
if (PG_ARGISNULL(0))
PG_RETURN_NULL();
name = PG_GETARG_TEXT_P(0);
res = find_digest(&_hbuf, name, 1);
PG_FREE_IF_COPY(name, 0); // unnecessary i guess
if (res != NULL)
PG_RETURN_BOOL(true);
PG_RETURN_BOOL(false);
}
static pg_digest *
find_digest(pg_digest *hbuf, text *name, int silent)
{
pg_digest *p;
char buf[NAMEDATALEN];
uint len;
len = VARSIZE(name) - VARHDRSZ;
if (len >= NAMEDATALEN) {
if (silent)
return NULL;
elog(ERROR, "Hash type does not exist (name too long)");
}
memcpy(buf, VARDATA(name), len);
buf[len] = 0;
p = pg_find_digest(hbuf, buf);
if (p == NULL && !silent)
elog(ERROR, "Hash type does not exist: '%s'", buf);
return p;
}
static unsigned char *hextbl = "0123456789abcdef";
/* dumps binary to hex... Note that it does not null-terminate */
static char *
to_hex(uint8 *buf, uint len, char *dst)
{
uint i;
for (i = 0; i < len; i++) {
dst[i*2] = hextbl[(buf[i] >> 4) & 0xF];
dst[i*2 + 1] = hextbl[buf[i] & 0xF];
}
return dst;
}
/*
* pgcrypto.h
* Header file for pgcrypto.
*
* Copyright (c) 2000 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.
*
* $Id: pgcrypto.h,v 1.1 2000/10/31 13:11:28 petere Exp $
*/
#ifndef _PG_CRYPTO_H
#define _PG_CRYPTO_H
#include <sys/types.h>
typedef struct _pg_digest pg_digest;
struct _pg_digest {
char *name;
uint (*length)(pg_digest *h);
uint8 *(*digest)(pg_digest *h, uint8 *data,
uint dlen, uint8 *buf);
/* private */
union {
uint code;
const void *ptr;
} misc;
};
extern pg_digest *pg_find_digest(pg_digest *hbuf, char *name);
#endif
-- drop function digest(text, text);
-- drop function digest_exists(text);
CREATE FUNCTION digest(text, text) RETURNS text
AS '@MODULE_FILENAME@',
'digest' LANGUAGE 'newC';
CREATE FUNCTION digest_exists(text) RETURNS bool
AS '@MODULE_FILENAME@',
'digest_exists' LANGUAGE 'newC';
/* $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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 project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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.
*/
/*
* FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
* based on: http://csrc.nist.gov/fips/fip180-1.txt
* implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
*/
#include <postgres.h>
#include "pgcrypto.h"
#include "sha1.h"
/* sanity check */
#if BYTE_ORDER != BIG_ENDIAN
# if BYTE_ORDER != LITTLE_ENDIAN
# define unsupported 1
# endif
#endif
#ifndef unsupported
/* constant table */
static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
#define K(t) _K[(t) / 20]
#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
#define F1(b, c, d) (((b) ^ (c)) ^ (d))
#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
#define F3(b, c, d) (((b) ^ (c)) ^ (d))
#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
#define H(n) (ctxt->h.b32[(n)])
#define COUNT (ctxt->count)
#define BCOUNT (ctxt->c.b64[0] / 8)
#define W(n) (ctxt->m.b32[(n)])
#define PUTBYTE(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
ctxt->c.b64[0] += 8; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
#define PUTPAD(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
static void sha1_step __P((struct sha1_ctxt *));
static void
sha1_step(ctxt)
struct sha1_ctxt *ctxt;
{
u_int32_t a, b, c, d, e;
size_t t, s;
u_int32_t tmp;
#if BYTE_ORDER == LITTLE_ENDIAN
struct sha1_ctxt tctxt;
bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
#endif
a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
for (t = 0; t < 20; t++) {
s = t & 0x0f;
if (t >= 16) {
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
}
tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 20; t < 40; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 40; t < 60; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 60; t < 80; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
H(0) = H(0) + a;
H(1) = H(1) + b;
H(2) = H(2) + c;
H(3) = H(3) + d;
H(4) = H(4) + e;
bzero(&ctxt->m.b8[0], 64);
}
/*------------------------------------------------------------*/
void
sha1_init(ctxt)
struct sha1_ctxt *ctxt;
{
bzero(ctxt, sizeof(struct sha1_ctxt));
H(0) = 0x67452301;
H(1) = 0xefcdab89;
H(2) = 0x98badcfe;
H(3) = 0x10325476;
H(4) = 0xc3d2e1f0;
}
void
sha1_pad(ctxt)
struct sha1_ctxt *ctxt;
{
size_t padlen; /*pad length in bytes*/
size_t padstart;
PUTPAD(0x80);
padstart = COUNT % 64;
padlen = 64 - padstart;
if (padlen < 8) {
bzero(&ctxt->m.b8[padstart], padlen);
COUNT += padlen;
COUNT %= 64;
sha1_step(ctxt);
padstart = COUNT % 64; /* should be 0 */
padlen = 64 - padstart; /* should be 64 */
}
bzero(&ctxt->m.b8[padstart], padlen - 8);
COUNT += (padlen - 8);
COUNT %= 64;
#if BYTE_ORDER == BIG_ENDIAN
PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
#else
PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
#endif
}
void
sha1_loop(ctxt, input0, len)
struct sha1_ctxt *ctxt;
const caddr_t input0;
size_t len;
{
const u_int8_t *input;
size_t gaplen;
size_t gapstart;
size_t off;
size_t copysiz;
input = (const u_int8_t *)input0;
off = 0;
while (off < len) {
gapstart = COUNT % 64;
gaplen = 64 - gapstart;
copysiz = (gaplen < len - off) ? gaplen : len - off;
bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
COUNT += copysiz;
COUNT %= 64;
ctxt->c.b64[0] += copysiz * 8;
if (COUNT % 64 == 0)
sha1_step(ctxt);
off += copysiz;
}
}
void
sha1_result(ctxt, digest0)
struct sha1_ctxt *ctxt;
caddr_t digest0;
{
u_int8_t *digest;
digest = (u_int8_t *)digest0;
sha1_pad(ctxt);
#if BYTE_ORDER == BIG_ENDIAN
bcopy(&ctxt->h.b8[0], digest, 20);
#else
digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
#endif
}
#endif /*unsupported*/
/* $KAME: sha1.h,v 1.4 2000/02/22 14:01:18 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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 project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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.
*/
/*
* FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
* based on: http://csrc.nist.gov/fips/fip180-1.txt
* implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
*/
#ifndef _NETINET6_SHA1_H_
#define _NETINET6_SHA1_H_
struct sha1_ctxt {
union {
u_int8_t b8[20];
u_int32_t b32[5];
} h;
union {
u_int8_t b8[8];
u_int64_t b64[1];
} c;
union {
u_int8_t b8[64];
u_int32_t b32[16];
} m;
u_int8_t count;
};
extern void sha1_init __P((struct sha1_ctxt *));
extern void sha1_pad __P((struct sha1_ctxt *));
extern void sha1_loop __P((struct sha1_ctxt *, const caddr_t, size_t));
extern void sha1_result __P((struct sha1_ctxt *, caddr_t));
/* compatibilty with other SHA1 source codes */
typedef struct sha1_ctxt SHA1_CTX;
#define SHA1Init(x) sha1_init((x))
#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
#define SHA1Final(x, y) sha1_result((y), (x))
#define SHA1_RESULTLEN (160/8)
#endif /*_NETINET6_SHA1_H_*/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment