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 "utils/resowner_private.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 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)
 

Macro Definition Documentation

◆ ALLOC

#define ALLOC (   size)    palloc(size)

Definition at line 47 of file hmac_openssl.c.

◆ FREE

#define FREE (   ptr)    pfree(ptr)

Definition at line 49 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 56 of file hmac_openssl.c.

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

Function Documentation

◆ pg_hmac_create()

pg_hmac_ctx* pg_hmac_create ( pg_cryptohash_type  type)

Definition at line 96 of file hmac_openssl.c.

97 {
98  pg_hmac_ctx *ctx;
99 
100  ctx = ALLOC(sizeof(pg_hmac_ctx));
101  if (ctx == NULL)
102  return NULL;
103  memset(ctx, 0, sizeof(pg_hmac_ctx));
104 
105  ctx->type = type;
106  ctx->error = PG_HMAC_ERROR_NONE;
107  ctx->errreason = NULL;
108 
109 
110  /*
111  * Initialization takes care of assigning the correct type for OpenSSL.
112  * Also ensure that there aren't any unconsumed errors in the queue from
113  * previous runs.
114  */
115  ERR_clear_error();
116 #ifdef HAVE_HMAC_CTX_NEW
117 #ifndef FRONTEND
119 #endif
120  ctx->hmacctx = HMAC_CTX_new();
121 #else
122  ctx->hmacctx = ALLOC(sizeof(HMAC_CTX));
123 #endif
124 
125  if (ctx->hmacctx == NULL)
126  {
127  explicit_bzero(ctx, sizeof(pg_hmac_ctx));
128  FREE(ctx);
129 #ifndef FRONTEND
130  ereport(ERROR,
131  (errcode(ERRCODE_OUT_OF_MEMORY),
132  errmsg("out of memory")));
133 #endif
134  return NULL;
135  }
136 
137 #ifdef HAVE_HMAC_CTX_NEW
138 #ifndef FRONTEND
141 #endif
142 #else
143  memset(ctx->hmacctx, 0, sizeof(HMAC_CTX));
144 #endif /* HAVE_HMAC_CTX_NEW */
145 
146  return ctx;
147 }
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:143
#define FREE(ptr)
Definition: hmac_openssl.c:49
#define ALLOC(size)
Definition: hmac_openssl.c:47
void explicit_bzero(void *buf, size_t len)
#define PointerGetDatum(X)
Definition: postgres.h:600
void ResourceOwnerEnlargeHMAC(ResourceOwner owner)
Definition: resowner.c:1455
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
void ResourceOwnerRememberHMAC(ResourceOwner owner, Datum handle)
Definition: resowner.c:1466
const char * errreason
Definition: hmac.c:55
ResourceOwner resowner
Definition: hmac_openssl.c:72
HMAC_CTX * hmacctx
Definition: hmac_openssl.c:66
pg_cryptohash_type type
Definition: hmac.c:53
pg_hmac_errno error
Definition: hmac.c:54

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, PointerGetDatum, ResourceOwnerEnlargeHMAC(), ResourceOwnerRememberHMAC(), pg_hmac_ctx::resowner, generate_unaccent_rules::type, and pg_hmac_ctx::type.

◆ pg_hmac_error()

const char* pg_hmac_error ( pg_hmac_ctx ctx)

Definition at line 324 of file hmac_openssl.c.

325 {
326  if (ctx == NULL)
327  return _("out of memory");
328 
329  /*
330  * If a reason is provided, rely on it, else fallback to any error code
331  * set.
332  */
333  if (ctx->errreason)
334  return ctx->errreason;
335 
336  switch (ctx->error)
337  {
338  case PG_HMAC_ERROR_NONE:
339  return _("success");
341  return _("destination buffer too small");
343  return _("OpenSSL failure");
344  }
345 
346  Assert(false); /* cannot be reached */
347  return _("success");
348 }
#define _(x)
Definition: elog.c:89
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 226 of file hmac_openssl.c.

227 {
228  int status = 0;
229  uint32 outlen;
230 
231  if (ctx == NULL)
232  return -1;
233 
234  switch (ctx->type)
235  {
236  case PG_MD5:
237  if (len < MD5_DIGEST_LENGTH)
238  {
240  return -1;
241  }
242  break;
243  case PG_SHA1:
244  if (len < SHA1_DIGEST_LENGTH)
245  {
247  return -1;
248  }
249  break;
250  case PG_SHA224:
252  {
254  return -1;
255  }
256  break;
257  case PG_SHA256:
259  {
261  return -1;
262  }
263  break;
264  case PG_SHA384:
266  {
268  return -1;
269  }
270  break;
271  case PG_SHA512:
273  {
275  return -1;
276  }
277  break;
278  }
279 
280  status = HMAC_Final(ctx->hmacctx, dest, &outlen);
281 
282  /* OpenSSL internals return 1 on success, 0 on failure */
283  if (status <= 0)
284  {
285  ctx->errreason = SSLerrmessage(ERR_get_error());
287  return -1;
288  }
289  return 0;
290 }
unsigned int uint32
Definition: c.h:441
@ 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:77
#define MD5_DIGEST_LENGTH
Definition: md5.h:20
const void size_t len
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:229
#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(), status(), and pg_hmac_ctx::type.

◆ pg_hmac_free()

void pg_hmac_free ( pg_hmac_ctx ctx)

Definition at line 298 of file hmac_openssl.c.

299 {
300  if (ctx == NULL)
301  return;
302 
303 #ifdef HAVE_HMAC_CTX_FREE
304  HMAC_CTX_free(ctx->hmacctx);
305 #ifndef FRONTEND
307 #endif
308 #else
309  explicit_bzero(ctx->hmacctx, sizeof(HMAC_CTX));
310  FREE(ctx->hmacctx);
311 #endif
312 
313  explicit_bzero(ctx, sizeof(pg_hmac_ctx));
314  FREE(ctx);
315 }
void ResourceOwnerForgetHMAC(ResourceOwner owner, Datum handle)
Definition: resowner.c:1475

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

◆ pg_hmac_init()

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

Definition at line 155 of file hmac_openssl.c.

156 {
157  int status = 0;
158 
159  if (ctx == NULL)
160  return -1;
161 
162  switch (ctx->type)
163  {
164  case PG_MD5:
165  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_md5(), NULL);
166  break;
167  case PG_SHA1:
168  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha1(), NULL);
169  break;
170  case PG_SHA224:
171  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha224(), NULL);
172  break;
173  case PG_SHA256:
174  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha256(), NULL);
175  break;
176  case PG_SHA384:
177  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha384(), NULL);
178  break;
179  case PG_SHA512:
180  status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha512(), NULL);
181  break;
182  }
183 
184  /* OpenSSL internals return 1 on success, 0 on failure */
185  if (status <= 0)
186  {
187  ctx->errreason = SSLerrmessage(ERR_get_error());
189  return -1;
190  }
191 
192  return 0;
193 }

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(), status(), 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 201 of file hmac_openssl.c.

202 {
203  int status = 0;
204 
205  if (ctx == NULL)
206  return -1;
207 
208  status = HMAC_Update(ctx->hmacctx, data, len);
209 
210  /* OpenSSL internals return 1 on success, 0 on failure */
211  if (status <= 0)
212  {
213  ctx->errreason = SSLerrmessage(ERR_get_error());
215  return -1;
216  }
217  return 0;
218 }
const void * data

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

◆ SSLerrmessage()

static const char* SSLerrmessage ( unsigned long  ecode)
static

Definition at line 77 of file hmac_openssl.c.

78 {
79  if (ecode == 0)
80  return NULL;
81 
82  /*
83  * This may return NULL, but we would fall back to a default error path if
84  * that were the case.
85  */
86  return ERR_reason_error_string(ecode);
87 }

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