PostgreSQL Source Code  git master
hmac_openssl.c File Reference
#include "postgres.h"
#include <openssl/err.h>
#include <openssl/hmac.h>
#include "common/hmac.h"
#include "common/md5.h"
#include "common/sha1.h"
#include "common/sha2.h"
#include "utils/memutils.h"
#include "utils/resowner.h"
Include dependency graph for hmac_openssl.c:

Go to the source code of this file.

Data Structures

struct  pg_hmac_ctx
 

Macros

#define ALLOC(size)   palloc(size)
 
#define FREE(ptr)   pfree(ptr)
 

Typedefs

typedef enum pg_hmac_errno pg_hmac_errno
 

Enumerations

enum  pg_hmac_errno {
  PG_HMAC_ERROR_NONE = 0 , PG_HMAC_ERROR_OOM , PG_HMAC_ERROR_INTERNAL , PG_HMAC_ERROR_NONE = 0 ,
  PG_HMAC_ERROR_DEST_LEN , PG_HMAC_ERROR_OPENSSL
}
 

Functions

static void ResOwnerReleaseHMAC (Datum res)
 
static void ResourceOwnerRememberHMAC (ResourceOwner owner, pg_hmac_ctx *ctx)
 
static void ResourceOwnerForgetHMAC (ResourceOwner owner, pg_hmac_ctx *ctx)
 
static const char * SSLerrmessage (unsigned long ecode)
 
pg_hmac_ctxpg_hmac_create (pg_cryptohash_type type)
 
int pg_hmac_init (pg_hmac_ctx *ctx, const uint8 *key, size_t len)
 
int pg_hmac_update (pg_hmac_ctx *ctx, const uint8 *data, size_t len)
 
int pg_hmac_final (pg_hmac_ctx *ctx, uint8 *dest, size_t len)
 
void pg_hmac_free (pg_hmac_ctx *ctx)
 
const char * pg_hmac_error (pg_hmac_ctx *ctx)
 

Variables

static const ResourceOwnerDesc hmac_resowner_desc
 

Macro Definition Documentation

◆ ALLOC

#define ALLOC (   size)    palloc(size)

Definition at line 46 of file hmac_openssl.c.

◆ FREE

#define FREE (   ptr)    pfree(ptr)

Definition at line 48 of file hmac_openssl.c.

Typedef Documentation

◆ pg_hmac_errno

Enumeration Type Documentation

◆ pg_hmac_errno

Enumerator
PG_HMAC_ERROR_NONE 
PG_HMAC_ERROR_OOM 
PG_HMAC_ERROR_INTERNAL 
PG_HMAC_ERROR_NONE 
PG_HMAC_ERROR_DEST_LEN 
PG_HMAC_ERROR_OPENSSL 

Definition at line 55 of file hmac_openssl.c.

56 {
pg_hmac_errno
Definition: hmac_openssl.c:56
@ PG_HMAC_ERROR_OPENSSL
Definition: hmac_openssl.c:59
@ PG_HMAC_ERROR_DEST_LEN
Definition: hmac_openssl.c:58
@ PG_HMAC_ERROR_NONE
Definition: hmac_openssl.c:57

Function Documentation

◆ pg_hmac_create()

pg_hmac_ctx* pg_hmac_create ( pg_cryptohash_type  type)

Definition at line 121 of file hmac_openssl.c.

122 {
123  pg_hmac_ctx *ctx;
124 
125  ctx = ALLOC(sizeof(pg_hmac_ctx));
126  if (ctx == NULL)
127  return NULL;
128  memset(ctx, 0, sizeof(pg_hmac_ctx));
129 
130  ctx->type = type;
131  ctx->error = PG_HMAC_ERROR_NONE;
132  ctx->errreason = NULL;
133 
134 
135  /*
136  * Initialization takes care of assigning the correct type for OpenSSL.
137  * Also ensure that there aren't any unconsumed errors in the queue from
138  * previous runs.
139  */
140  ERR_clear_error();
141 #ifdef HAVE_HMAC_CTX_NEW
142 #ifndef FRONTEND
144 #endif
145  ctx->hmacctx = HMAC_CTX_new();
146 #else
147  ctx->hmacctx = ALLOC(sizeof(HMAC_CTX));
148 #endif
149 
150  if (ctx->hmacctx == NULL)
151  {
152  explicit_bzero(ctx, sizeof(pg_hmac_ctx));
153  FREE(ctx);
154 #ifndef FRONTEND
155  ereport(ERROR,
156  (errcode(ERRCODE_OUT_OF_MEMORY),
157  errmsg("out of memory")));
158 #endif
159  return NULL;
160  }
161 
162 #ifdef HAVE_HMAC_CTX_NEW
163 #ifndef FRONTEND
166 #endif
167 #else
168  memset(ctx->hmacctx, 0, sizeof(HMAC_CTX));
169 #endif /* HAVE_HMAC_CTX_NEW */
170 
171  return ctx;
172 }
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define FREE(ptr)
Definition: hmac_openssl.c:48
static void ResourceOwnerRememberHMAC(ResourceOwner owner, pg_hmac_ctx *ctx)
Definition: hmac_openssl.c:90
#define ALLOC(size)
Definition: hmac_openssl.c:46
void explicit_bzero(void *buf, size_t len)
ResourceOwner CurrentResourceOwner
Definition: resowner.c:164
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:448
const char * errreason
Definition: hmac.c:55
ResourceOwner resowner
Definition: hmac_openssl.c:71
HMAC_CTX * hmacctx
Definition: hmac_openssl.c:65
pg_cryptohash_type type
Definition: hmac.c:53
pg_hmac_errno error
Definition: hmac.c:54
const char * type

References ALLOC, CurrentResourceOwner, ereport, errcode(), errmsg(), pg_hmac_ctx::error, ERROR, pg_hmac_ctx::errreason, explicit_bzero(), FREE, pg_hmac_ctx::hmacctx, PG_HMAC_ERROR_NONE, ResourceOwnerEnlarge(), ResourceOwnerRememberHMAC(), pg_hmac_ctx::resowner, type, and pg_hmac_ctx::type.

◆ pg_hmac_error()

const char* pg_hmac_error ( pg_hmac_ctx ctx)

Definition at line 350 of file hmac_openssl.c.

351 {
352  if (ctx == NULL)
353  return _("out of memory");
354 
355  /*
356  * If a reason is provided, rely on it, else fallback to any error code
357  * set.
358  */
359  if (ctx->errreason)
360  return ctx->errreason;
361 
362  switch (ctx->error)
363  {
364  case PG_HMAC_ERROR_NONE:
365  return _("success");
367  return _("destination buffer too small");
369  return _("OpenSSL failure");
370  }
371 
372  Assert(false); /* cannot be reached */
373  return _("success");
374 }
#define _(x)
Definition: elog.c:91
Assert(fmt[strlen(fmt) - 1] !='\n')

References _, Assert(), pg_hmac_ctx::error, pg_hmac_ctx::errreason, PG_HMAC_ERROR_DEST_LEN, PG_HMAC_ERROR_NONE, and PG_HMAC_ERROR_OPENSSL.

◆ pg_hmac_final()

int pg_hmac_final ( pg_hmac_ctx ctx,
uint8 dest,
size_t  len 
)

Definition at line 251 of file hmac_openssl.c.

252 {
253  int status = 0;
254  uint32 outlen;
255 
256  if (ctx == NULL)
257  return -1;
258 
259  switch (ctx->type)
260  {
261  case PG_MD5:
262  if (len < MD5_DIGEST_LENGTH)
263  {
265  return -1;
266  }
267  break;
268  case PG_SHA1:
269  if (len < SHA1_DIGEST_LENGTH)
270  {
272  return -1;
273  }
274  break;
275  case PG_SHA224:
277  {
279  return -1;
280  }
281  break;
282  case PG_SHA256:
284  {
286  return -1;
287  }
288  break;
289  case PG_SHA384:
291  {
293  return -1;
294  }
295  break;
296  case PG_SHA512:
298  {
300  return -1;
301  }
302  break;
303  }
304 
305  status = HMAC_Final(ctx->hmacctx, dest, &outlen);
306 
307  /* OpenSSL internals return 1 on success, 0 on failure */
308  if (status <= 0)
309  {
310  ctx->errreason = SSLerrmessage(ERR_get_error());
312  return -1;
313  }
314  return 0;
315 }
unsigned int uint32
Definition: c.h:495
@ PG_SHA512
Definition: cryptohash.h:26
@ PG_SHA224
Definition: cryptohash.h:23
@ PG_SHA384
Definition: cryptohash.h:25
@ PG_SHA1
Definition: cryptohash.h:22
@ PG_SHA256
Definition: cryptohash.h:24
@ PG_MD5
Definition: cryptohash.h:21
static const char * SSLerrmessage(unsigned long ecode)
Definition: hmac_openssl.c:102
#define MD5_DIGEST_LENGTH
Definition: md5.h:20
const void size_t len
#define SHA1_DIGEST_LENGTH
Definition: sha1.h:17
#define PG_SHA256_DIGEST_LENGTH
Definition: sha2.h:23
#define PG_SHA384_DIGEST_LENGTH
Definition: sha2.h:26
#define PG_SHA512_DIGEST_LENGTH
Definition: sha2.h:29
#define PG_SHA224_DIGEST_LENGTH
Definition: sha2.h:20

References generate_unaccent_rules::dest, pg_hmac_ctx::error, pg_hmac_ctx::errreason, pg_hmac_ctx::hmacctx, len, MD5_DIGEST_LENGTH, PG_HMAC_ERROR_DEST_LEN, PG_HMAC_ERROR_OPENSSL, PG_MD5, PG_SHA1, PG_SHA224, PG_SHA224_DIGEST_LENGTH, PG_SHA256, PG_SHA256_DIGEST_LENGTH, PG_SHA384, PG_SHA384_DIGEST_LENGTH, PG_SHA512, PG_SHA512_DIGEST_LENGTH, SHA1_DIGEST_LENGTH, SSLerrmessage(), and pg_hmac_ctx::type.

◆ pg_hmac_free()

void pg_hmac_free ( pg_hmac_ctx ctx)

Definition at line 323 of file hmac_openssl.c.

324 {
325  if (ctx == NULL)
326  return;
327 
328 #ifdef HAVE_HMAC_CTX_FREE
329  HMAC_CTX_free(ctx->hmacctx);
330 #ifndef FRONTEND
331  if (ctx->resowner)
333 #endif
334 #else
335  explicit_bzero(ctx->hmacctx, sizeof(HMAC_CTX));
336  FREE(ctx->hmacctx);
337 #endif
338 
339  explicit_bzero(ctx, sizeof(pg_hmac_ctx));
340  FREE(ctx);
341 }
static void ResourceOwnerForgetHMAC(ResourceOwner owner, pg_hmac_ctx *ctx)
Definition: hmac_openssl.c:95

References explicit_bzero(), FREE, pg_hmac_ctx::hmacctx, ResourceOwnerForgetHMAC(), and pg_hmac_ctx::resowner.

Referenced by ResOwnerReleaseHMAC().

◆ pg_hmac_init()

int pg_hmac_init ( pg_hmac_ctx ctx,
const uint8 key,
size_t  len 
)

Definition at line 180 of file hmac_openssl.c.

181 {
182  int status = 0;
183 
184  if (ctx == NULL)
185  return -1;
186 
187  switch (ctx->type)
188  {
189  case PG_MD5:
190  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_md5(), NULL);
191  break;
192  case PG_SHA1:
193  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha1(), NULL);
194  break;
195  case PG_SHA224:
196  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha224(), NULL);
197  break;
198  case PG_SHA256:
199  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha256(), NULL);
200  break;
201  case PG_SHA384:
202  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha384(), NULL);
203  break;
204  case PG_SHA512:
205  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha512(), NULL);
206  break;
207  }
208 
209  /* OpenSSL internals return 1 on success, 0 on failure */
210  if (status <= 0)
211  {
212  ctx->errreason = SSLerrmessage(ERR_get_error());
214  return -1;
215  }
216 
217  return 0;
218 }

References pg_hmac_ctx::error, pg_hmac_ctx::errreason, pg_hmac_ctx::hmacctx, sort-test::key, len, PG_HMAC_ERROR_OPENSSL, PG_MD5, PG_SHA1, PG_SHA224, PG_SHA256, PG_SHA384, PG_SHA512, SSLerrmessage(), and pg_hmac_ctx::type.

◆ pg_hmac_update()

int pg_hmac_update ( pg_hmac_ctx ctx,
const uint8 data,
size_t  len 
)

Definition at line 226 of file hmac_openssl.c.

227 {
228  int status = 0;
229 
230  if (ctx == NULL)
231  return -1;
232 
233  status = HMAC_Update(ctx->hmacctx, data, len);
234 
235  /* OpenSSL internals return 1 on success, 0 on failure */
236  if (status <= 0)
237  {
238  ctx->errreason = SSLerrmessage(ERR_get_error());
240  return -1;
241  }
242  return 0;
243 }
const void * data

References data, pg_hmac_ctx::error, pg_hmac_ctx::errreason, pg_hmac_ctx::hmacctx, len, PG_HMAC_ERROR_OPENSSL, and SSLerrmessage().

◆ ResourceOwnerForgetHMAC()

static void ResourceOwnerForgetHMAC ( ResourceOwner  owner,
pg_hmac_ctx ctx 
)
inlinestatic

Definition at line 95 of file hmac_openssl.c.

96 {
98 }
static const ResourceOwnerDesc hmac_resowner_desc
Definition: hmac_openssl.c:79
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:555

References hmac_resowner_desc, PointerGetDatum(), and ResourceOwnerForget().

Referenced by pg_hmac_free().

◆ ResourceOwnerRememberHMAC()

static void ResourceOwnerRememberHMAC ( ResourceOwner  owner,
pg_hmac_ctx ctx 
)
inlinestatic

Definition at line 90 of file hmac_openssl.c.

91 {
93 }
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:520

References hmac_resowner_desc, PointerGetDatum(), and ResourceOwnerRemember().

Referenced by pg_hmac_create().

◆ ResOwnerReleaseHMAC()

static void ResOwnerReleaseHMAC ( Datum  res)
static

Definition at line 380 of file hmac_openssl.c.

381 {
383 
384  ctx->resowner = NULL;
385  pg_hmac_free(ctx);
386 }
void pg_hmac_free(pg_hmac_ctx *ctx)
Definition: hmac_openssl.c:323
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312

References DatumGetPointer(), pg_hmac_free(), res, and pg_hmac_ctx::resowner.

◆ SSLerrmessage()

static const char* SSLerrmessage ( unsigned long  ecode)
static

Definition at line 102 of file hmac_openssl.c.

103 {
104  if (ecode == 0)
105  return NULL;
106 
107  /*
108  * This may return NULL, but we would fall back to a default error path if
109  * that were the case.
110  */
111  return ERR_reason_error_string(ecode);
112 }

Referenced by pg_hmac_final(), pg_hmac_init(), and pg_hmac_update().

Variable Documentation

◆ hmac_resowner_desc

const ResourceOwnerDesc hmac_resowner_desc
static
Initial value:
=
{
.name = "OpenSSL HMAC context",
.release_priority = RELEASE_PRIO_HMAC_CONTEXTS,
.ReleaseResource = ResOwnerReleaseHMAC,
.DebugPrint = NULL
}
static void ResOwnerReleaseHMAC(Datum res)
Definition: hmac_openssl.c:380
#define RELEASE_PRIO_HMAC_CONTEXTS
Definition: resowner.h:68
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition: resowner.h:54

Definition at line 79 of file hmac_openssl.c.

Referenced by ResourceOwnerForgetHMAC(), and ResourceOwnerRememberHMAC().