OpenVAS Manager  7.0.3~git
lsc_crypt.c File Reference
#include <glib.h>
#include <glib/gstdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdint.h>
#include <openvas/base/gpgme_util.h>
#include "lsc_crypt.h"
Include dependency graph for lsc_crypt.c:

Go to the source code of this file.

Data Structures

struct  namelist_s
 A linked list to help caching results. More...
 
struct  lsc_crypt_ctx_s
 The context object for encryption operations. More...
 

Macros

#define G_LOG_DOMAIN   "md crypt"
 GLib log domain. More...
 
#define ENCRYPTION_KEY_UID   "OpenVAS Credential Encryption"
 The name of the encryption key. More...
 
#define MAX_VALUE_LENGTH   (128 * 1024)
 The maximum size of an encrypted value. More...
 
#define GPG_ERR_AMBIGUOUS   GPG_ERR_AMBIGUOUS_NAME
 

Functions

lsc_crypt_ctx_t lsc_crypt_new ()
 Return a new context for LSC encryption. More...
 
void lsc_crypt_release (lsc_crypt_ctx_t ctx)
 Release an LSC encryption context. More...
 
int lsc_crypt_create_key ()
 Create the standard credential encryption key. More...
 
void lsc_crypt_flush (lsc_crypt_ctx_t ctx)
 Flush an LSC encryption context. More...
 
char * lsc_crypt_encrypt (lsc_crypt_ctx_t ctx, const char *first_name,...)
 Encrypt a list of name/value pairs. More...
 
const char * lsc_crypt_decrypt (lsc_crypt_ctx_t ctx, const char *ciphertext, const char *name)
 Return an encrypted value in the clear. More...
 
const char * lsc_crypt_get_password (lsc_crypt_ctx_t ctx, const char *ciphertext)
 Return an encrypted password in the clear. More...
 
const char * lsc_crypt_get_private_key (lsc_crypt_ctx_t ctx, const char *ciphertext)
 Return an encrypted private key in the clear. More...
 

Macro Definition Documentation

◆ ENCRYPTION_KEY_UID

#define ENCRYPTION_KEY_UID   "OpenVAS Credential Encryption"

The name of the encryption key.

Note that the code will use the "=" prefix flag to indicate an exact search. Thus when creating the key it should not have a comment or email address part.

Definition at line 50 of file lsc_crypt.c.

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "md crypt"

GLib log domain.

Definition at line 41 of file lsc_crypt.c.

◆ GPG_ERR_AMBIGUOUS

#define GPG_ERR_AMBIGUOUS   GPG_ERR_AMBIGUOUS_NAME

Definition at line 63 of file lsc_crypt.c.

◆ MAX_VALUE_LENGTH

#define MAX_VALUE_LENGTH   (128 * 1024)

The maximum size of an encrypted value.

To avoid excessive memory allocations we put a limit on the size of values stored in a name/value pair.

Definition at line 58 of file lsc_crypt.c.

Function Documentation

◆ lsc_crypt_create_key()

int lsc_crypt_create_key ( )

Create the standard credential encryption key.

This function creates a standard encryption key if such a key does not yet exists. Note, that in general an encryption key is created on-the-fly.

Returns
0 on success, 1 if the key already exists, and -1 for other errors.

Definition at line 549 of file lsc_crypt.c.

550 {
551  int res = -1;
552  lsc_crypt_ctx_t ctx;
553  gpgme_key_t key;
554 
555  ctx = lsc_crypt_new ();
556  key = find_the_key (ctx, TRUE);
557  if (key)
558  {
559  gpgme_key_unref (key);
560  g_warning ("A credentials encryption key already exists - "
561  "not creating another one.");
562  res = 1;
563  }
564  else
565  {
566  if (!create_the_key (ctx))
567  res = 0;
568  }
569 
570  lsc_crypt_release (ctx);
571  return res;
572 }
lsc_crypt_ctx_t lsc_crypt_new()
Return a new context for LSC encryption.
Definition: lsc_crypt.c:507
The context object for encryption operations.
Definition: lsc_crypt.c:87
void lsc_crypt_release(lsc_crypt_ctx_t ctx)
Release an LSC encryption context.
Definition: lsc_crypt.c:528

References lsc_crypt_new().

Here is the call graph for this function:

◆ lsc_crypt_decrypt()

const char* lsc_crypt_decrypt ( lsc_crypt_ctx_t  ctx,
const char *  ciphertext,
const char *  name 
)

Return an encrypted value in the clear.

This function returns the encrypted value in the clear. The clear value may also be NULL , if no value is available. If a decryption has not yet been done, the passed ciphertext value is first decrypted. Thus a changed value of ciphertext may not have an effect. To force a decryption a call to lsc_crypt_flush is required.

Parameters
[in]ctxThe context
[in]ciphertextThe base64 encoded ciphertext.
[in]nameName of the value to get.
Returns
A const pointer to a string object. This pointer is valid as long as the context is valid and lsc_crypt_flush has not been called. If no value is available NULL is returned.

Definition at line 693 of file lsc_crypt.c.

695 {
696  size_t namelen;
697  const char *p;
698  size_t len;
699  uint32_t n;
700  int found;
701  struct namelist_s *nl;
702 
703  if (!ctx || !name || !*name)
704  return NULL;
706  {
707  static gboolean shown;
708  if (!shown)
709  {
710  shown = 1;
711  g_warning ("note that decryption of credentials has been disabled");
712  }
713  return NULL;
714  }
715 
716  if (!ctx->plaintext)
717  {
718  if (!ciphertext)
719  return NULL;
720  ctx->plaintext = do_decrypt (ctx, ciphertext, &ctx->plaintextlen);
721  if (!ctx->plaintext)
722  return NULL;
723  }
724 
725  /* Try to return it from the cache. */
726  for (nl = ctx->namelist; nl; nl = nl->next)
727  if (!strcmp (nl->name, name))
728  {
729  return (nl->value
730  ? nl->value
731  : (nl->valoff ? (ctx->plaintext + nl->valoff) : NULL));
732  }
733 
734  /* Cache miss: Parse the data, cache the result, and return it. */
735  /* Fixme: Cache a not found status. */
736  namelen = strlen (name);
737  p = ctx->plaintext;
738  len = ctx->plaintextlen;
739  found = 0;
740  while (len)
741  {
742  if (len < 4)
743  goto failed;
744  n = get32 (p); p += 4; len -= 4;
745  if (n > len)
746  goto failed;
747  if (n == namelen && !memcmp (p, name, namelen))
748  found = 1;
749  p += n; len -= n;
750  if (len < 4)
751  goto failed;
752  n = get32 (p); p += 4; len -= 4;
753  if (n > len)
754  goto failed;
755  if (found)
756  {
757  if (n > MAX_VALUE_LENGTH)
758  {
759  g_warning ("%s: value for '%s' larger than our limit (%d)",
760  G_STRFUNC, name, MAX_VALUE_LENGTH);
761  return NULL;
762  }
763  nl = g_malloc (sizeof *nl + namelen);
764 #if 0
765  strcpy (nl->name, name);
766 #else
767  /* The pointer arithmetic helps Clang see that nl is allocated
768  * bigger than the size of *nl. */
769  strcpy (((char *) nl) + (nl->name - (char *) nl), name);
770 #endif
771 
772  if (n + 1 < len && p[n] == 0)
773  {
774  /* The values is followed by another name and the first
775  byte of that name's length is 0. Thus we don't need
776  to take a copy because that length byte acts as the
777  string terminator. */
778  nl->valoff = (p - ctx->plaintext);
779  nl->value = NULL;
780  }
781  else
782  {
783  /* We need to take a copy of the value, so that we can
784  add the string terminator. */
785  nl->valoff = 0;
786  nl->value = g_malloc (n + 1);
787  memcpy (nl->value, p, n);
788  nl->value[n] = 0;
789  }
790  nl->next = ctx->namelist;
791  ctx->namelist = nl;
792  return nl->value? nl->value : (ctx->plaintext + nl->valoff);
793  }
794  p += n; len -= n;
795  }
796  if (!len)
797  goto not_found;
798 
799  failed:
800  g_warning ("%s: decrypted credential data block is inconsistent;"
801  " %zu bytes remaining at offset %zu",
802  G_STRFUNC, len, (size_t)(p - ctx->plaintext));
803  not_found:
804  /* Cache a NULL value. */
805  nl = g_malloc (sizeof *nl + namelen);
806 #if 0
807  strcpy (nl->name, name);
808 #else
809  /* The pointer arithmetic helps Clang see that nl is allocated
810  * bigger than the size of *nl. */
811  strcpy (((char *) nl) + (nl->name - (char *) nl), name);
812 #endif
813  nl->valoff = 0;
814  nl->value = NULL;
815  nl->next = ctx->namelist;
816  ctx->namelist = nl;
817  return NULL;
818 }
char * plaintext
Definition: lsc_crypt.c:91
struct namelist_s * next
Definition: lsc_crypt.c:71
#define MAX_VALUE_LENGTH
The maximum size of an encrypted value.
Definition: lsc_crypt.c:58
A linked list to help caching results.
Definition: lsc_crypt.c:69
int disable_encrypted_credentials
Flag indicating that encrypted credentials are disabled.
Definition: openvasmd.c:275
size_t plaintextlen
Definition: lsc_crypt.c:92
struct namelist_s * namelist
Definition: lsc_crypt.c:93
char * value
Definition: lsc_crypt.c:77
char name[1]
Definition: lsc_crypt.c:78
size_t valoff
Definition: lsc_crypt.c:72

References disable_encrypted_credentials, namelist_s::name, and lsc_crypt_ctx_s::plaintext.

Referenced by lsc_crypt_get_password(), and lsc_crypt_get_private_key().

Here is the caller graph for this function:

◆ lsc_crypt_encrypt()

char* lsc_crypt_encrypt ( lsc_crypt_ctx_t  ctx,
const char *  first_name,
  ... 
)

Encrypt a list of name/value pairs.

Parameters
[in]ctxThe context
[in]first_nameThe name of the first name/value pair. This must be followed by a string value and optionaly followed by more name and value pairs. This list is terminated by a single NULL instead of a name.
Returns
A pointer to a freshly allocated string in base64 encoding. Caller must free. On error NULL is returned.

Definition at line 616 of file lsc_crypt.c.

617 {
618  va_list arg_ptr;
619  GString *stringbuf;
620  char *plaintext;
621  size_t plaintextlen;
622  char *ciphertext;
623  const char *name, *value;
624  size_t len;
625 
626  if (!ctx || !first_name)
627  return NULL;
628 
629  /* Assuming a 2048 bit RSA ssh private key in PEM encoding, a buffer
630  with an initial size of 2k should be large enough. */
631  stringbuf = g_string_sized_new (2048);
632 
633  name = first_name;
634  va_start (arg_ptr, first_name);
635  do
636  {
637  value = va_arg (arg_ptr, const char *);
638  if (!value)
639  value = "";
640  len = strlen (name);
641  if (len) /* We skip pairs with an empty name. */
642  {
643  put32 (stringbuf, len);
644  g_string_append (stringbuf, name);
645  len = strlen (value);
646  if (len > MAX_VALUE_LENGTH)
647  {
648  g_warning ("%s: value for '%s' larger than our limit (%d)",
649  G_STRFUNC, name, MAX_VALUE_LENGTH);
650  g_string_free (stringbuf, TRUE);
651  va_end (arg_ptr);
652  return NULL;
653  }
654  put32 (stringbuf, len);
655  g_string_append (stringbuf, value);
656  }
657  }
658  while ((name = va_arg (arg_ptr, const char *)))
659  ;
660  va_end (arg_ptr);
661  plaintext = stringbuf->str;
662  plaintextlen = stringbuf->len;
663  g_string_free (stringbuf, FALSE);
664  g_assert (plaintextlen);
665 
666  ciphertext = do_encrypt (ctx, plaintext, plaintextlen);
667  g_free (plaintext);
668 
669  return ciphertext;
670 }
#define MAX_VALUE_LENGTH
The maximum size of an encrypted value.
Definition: lsc_crypt.c:58
char * value
Definition: lsc_crypt.c:77
char name[1]
Definition: lsc_crypt.c:78

References namelist_s::name, and namelist_s::value.

Referenced by migrate_156_to_157(), migrate_158_to_159(), migrate_160_to_161(), and migrate_165_to_166().

Here is the caller graph for this function:

◆ lsc_crypt_flush()

void lsc_crypt_flush ( lsc_crypt_ctx_t  ctx)

Flush an LSC encryption context.

This function is used to flush the context. The flushing invalidates returned strings and internal caches. Basically this is the same as releasing and creating the context but it is optimized to keep some internal state.

Parameters
[in]ctxThe context or NULL

Definition at line 586 of file lsc_crypt.c.

587 {
588  if (!ctx)
589  return;
590  while (ctx->namelist)
591  {
592  struct namelist_s *nl = ctx->namelist->next;
593  g_free (ctx->namelist->value);
594  g_free (ctx->namelist);
595  ctx->namelist = nl;
596  }
597  g_free (ctx->plaintext);
598  ctx->plaintext = NULL;
599 }
char * plaintext
Definition: lsc_crypt.c:91
struct namelist_s * next
Definition: lsc_crypt.c:71
A linked list to help caching results.
Definition: lsc_crypt.c:69
struct namelist_s * namelist
Definition: lsc_crypt.c:93
char * value
Definition: lsc_crypt.c:77

References lsc_crypt_ctx_s::namelist, namelist_s::next, lsc_crypt_ctx_s::plaintext, and namelist_s::value.

Referenced by lsc_crypt_release(), and next().

Here is the caller graph for this function:

◆ lsc_crypt_get_password()

const char* lsc_crypt_get_password ( lsc_crypt_ctx_t  ctx,
const char *  ciphertext 
)

Return an encrypted password in the clear.

This function returns the encrypted password in the clear. The clear value may also be NULL , if no password is available. If a decryption has not yet been done, the passed ciphertext value is first decrypted. Thus a changed value of ciphertext may not have an effect. To force a decryption a call to lsc_crypt_flush is required.

Parameters
[in]ctxThe context
[in]ciphertextThe base64 encoded ciphertext.
Returns
A const pointer to a string object. This pointer is valid as long as the context is valid and lsc_crypt_flush has not been called. If no password is available NULL is returned.

Definition at line 840 of file lsc_crypt.c.

841 {
842  return lsc_crypt_decrypt (ctx, ciphertext, "password");
843 }
const char * lsc_crypt_decrypt(lsc_crypt_ctx_t ctx, const char *ciphertext, const char *name)
Return an encrypted value in the clear.
Definition: lsc_crypt.c:693

References lsc_crypt_decrypt().

Referenced by migrate_160_to_161().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ lsc_crypt_get_private_key()

const char* lsc_crypt_get_private_key ( lsc_crypt_ctx_t  ctx,
const char *  ciphertext 
)

Return an encrypted private key in the clear.

This function returns the encrypted private key in the clear. The clear value may also be NULL , if no private key is available. If a decryption has not yet been done, the passed ciphertext value is first decrypted. Thus a changed value of ciphertext may not have an effect. To force a decryption a call to lsc_crypt_flush is required.

Parameters
[in]ctxThe context
[in]ciphertextThe base64 encoded ciphertext.
Returns
A const pointer to a string object. This pointer is valid as long as the context is valid and lsc_crypt_flush has not been called. If no private key is available NULL is returned.

Definition at line 864 of file lsc_crypt.c.

865 {
866  return lsc_crypt_decrypt (ctx, ciphertext, "private_key");
867 }
const char * lsc_crypt_decrypt(lsc_crypt_ctx_t ctx, const char *ciphertext, const char *name)
Return an encrypted value in the clear.
Definition: lsc_crypt.c:693

References lsc_crypt_decrypt().

Referenced by migrate_153_to_154().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ lsc_crypt_new()

lsc_crypt_ctx_t lsc_crypt_new ( )

Return a new context for LSC encryption.

Returns
A new context object to be released with lsc_crypt_release.

Definition at line 507 of file lsc_crypt.c.

508 {
509  lsc_crypt_ctx_t ctx;
510 
511  ctx = g_malloc0 (sizeof *ctx);
512  ctx->encctx = openvas_init_gpgme_ctx ("openvasmd");
513  if (!ctx->encctx)
514  {
515  g_critical ("%s: can't continue w/o a gpgme context\n", G_STRFUNC);
516  exit (EXIT_FAILURE);
517  }
518 
519  return ctx;
520 }
gpgme_ctx_t encctx
Definition: lsc_crypt.c:89
The context object for encryption operations.
Definition: lsc_crypt.c:87

References lsc_crypt_ctx_s::encctx.

Referenced by lsc_crypt_create_key(), migrate_153_to_154(), migrate_156_to_157(), migrate_158_to_159(), migrate_160_to_161(), and migrate_165_to_166().

Here is the caller graph for this function:

◆ lsc_crypt_release()

void lsc_crypt_release ( lsc_crypt_ctx_t  ctx)

Release an LSC encryption context.

Parameters
[in]ctxThe context or NULL

Definition at line 528 of file lsc_crypt.c.

529 {
530  if (!ctx)
531  return;
532  lsc_crypt_flush (ctx);
533  if (ctx->encctx) /* Check required for gpgme < 1.3.1 */
534  gpgme_release (ctx->encctx);
535  g_free (ctx);
536 }
void lsc_crypt_flush(lsc_crypt_ctx_t ctx)
Flush an LSC encryption context.
Definition: lsc_crypt.c:586
gpgme_ctx_t encctx
Definition: lsc_crypt.c:89

References lsc_crypt_ctx_s::encctx, and lsc_crypt_flush().

Referenced by cleanup_iterator(), and migrate_160_to_161().

Here is the call graph for this function:
Here is the caller graph for this function: