27 #include <glib/gstdio.h> 33 #include <openvas/base/gpgme_util.h> 41 #define G_LOG_DOMAIN "md crypt" 50 #define ENCRYPTION_KEY_UID "OpenVAS Credential Encryption" 58 #define MAX_VALUE_LENGTH (128 * 1024) 62 #ifndef GPG_ERR_AMBIGUOUS 63 # define GPG_ERR_AMBIGUOUS GPG_ERR_AMBIGUOUS_NAME 107 static G_GNUC_CONST
const char *
108 nonnull (
const char *s)
110 return s? s :
"[none]";
124 put32 (GString *buffer, uint32_t
value)
126 unsigned char tmp[4];
127 tmp[0] = value >> 24;
128 tmp[1] = value >> 16;
131 g_string_append_len (buffer, (
char*)tmp, 4);
145 static G_GNUC_PURE uint32_t
146 get32 (
const void *buffer)
148 const unsigned char *s = buffer;
172 log_gpgme (GLogLevelFlags level, gpg_error_t err,
const char *fmt, ...)
177 va_start (arg_ptr, fmt);
178 msg = g_strdup_vprintf (fmt, arg_ptr);
180 if (err && gpg_err_source (err) != GPG_ERR_SOURCE_ANY)
182 msg, gpg_strerror (err), gpg_strsource (err));
185 msg, gpg_strerror (err));
211 "<GnupgKeyParms format=\"internal\">\n" 214 "Key-Usage: encrypt\n" 218 "%no-ask-passphrase\n" 219 "</GnupgKeyParms>\n";
222 log_gpgme (G_LOG_LEVEL_INFO, 0,
"starting key generation ...");
223 err = gpgme_op_genkey (ctx->
encctx, parms, NULL, NULL);
226 log_gpgme(G_LOG_LEVEL_WARNING, err,
"error creating OpenPGP key '%s'",
230 log_gpgme (G_LOG_LEVEL_INFO, 0,
251 int nfound, any_skipped;
252 gpgme_key_t found, key;
260 log_gpgme (G_LOG_LEVEL_WARNING, err,
261 "error starting search for OpenPGP key '%s'",
266 nfound = any_skipped = 0;
268 while (!(err = gpgme_op_keylist_next (ctx->
encctx, &key)))
270 if (!key->can_encrypt || key->revoked || key->expired
271 || key->disabled || key->invalid)
273 log_gpgme (G_LOG_LEVEL_MESSAGE, 0,
"skipping unusable OpenPGP key %s",
274 key->subkeys? nonnull (key->subkeys->keyid):
"?");
284 gpgme_key_unref (key);
286 if (gpgme_err_code (err) == GPG_ERR_EOF)
288 gpgme_op_keylist_end (ctx->
encctx);
293 gpgme_release (ctx->
encctx);
294 ctx->
encctx = openvas_init_gpgme_ctx (
"openvasmd");
297 g_critical (
"%s: can't continue w/o a gpgme context\n", G_STRFUNC);
303 static int genkey_tried;
307 if (!any_skipped && !genkey_tried && !no_create)
310 if (!create_the_key (ctx))
314 err = gpg_err_make (GPG_ERR_SOURCE_ANY, GPG_ERR_NOT_FOUND);
321 log_gpgme (G_LOG_LEVEL_MESSAGE, err,
322 "error searching for OpenPGP key '%s'",
324 gpgme_key_unref (found);
346 do_encrypt (
lsc_crypt_ctx_t ctx,
const void *plaintext,
size_t plaintextlen)
349 gpgme_data_t in, out;
350 gpgme_key_t keyarray[2];
352 size_t ciphertextlen;
357 ctx->
enckey = find_the_key (ctx, 0);
362 err = gpgme_data_new_from_mem (&in, plaintext, plaintextlen, 0);
365 log_gpgme (G_LOG_LEVEL_WARNING, err,
366 "%s: error creating data object from plaintext",
371 err = gpgme_data_new (&out);
374 log_gpgme (G_LOG_LEVEL_WARNING, err,
375 "%s: error creating data object for ciphertext",
377 gpgme_data_release (in);
381 gpgme_set_armor (ctx->
encctx, 0);
382 keyarray[0] = ctx->
enckey;
384 err = gpgme_op_encrypt (ctx->
encctx, keyarray,
385 GPGME_ENCRYPT_ALWAYS_TRUST, in, out);
386 gpgme_data_release (in);
389 log_gpgme (G_LOG_LEVEL_WARNING, err,
390 "%s: error encrypting credential",
392 gpgme_data_release (out);
395 ciphertext = gpgme_data_release_and_get_mem (out, &ciphertextlen);
398 g_critical (
"%s: error snatching memory", G_STRFUNC);
402 result = g_base64_encode ((
unsigned char *)ciphertext, ciphertextlen);
403 gpgme_free (ciphertext);
429 size_t *r_plaintextlen)
432 gpgme_data_t in, out;
434 size_t ciphertextlen;
438 ciphertext = (
char *)g_base64_decode (cipherstring, &ciphertextlen);
439 if (!ciphertext || !ciphertextlen)
442 err = gpgme_data_new_from_mem (&in, ciphertext, ciphertextlen, 0);
445 log_gpgme (G_LOG_LEVEL_WARNING, err,
446 "%s: error creating data object from ciphertext",
453 err = gpgme_data_new (&out);
456 log_gpgme (G_LOG_LEVEL_WARNING, err,
457 "%s: error creating data object for plaintext",
459 gpgme_data_release (in);
464 err = gpgme_op_decrypt (ctx->
encctx, in, out);
465 gpgme_data_release (in);
469 gpgme_decrypt_result_t decres;
470 gpgme_recipient_t recp;
472 gpgme_data_release (out);
473 log_gpgme (G_LOG_LEVEL_WARNING, err,
"error decrypting credential");
474 decres = gpgme_op_decrypt_result (ctx->
encctx);
475 if (decres->unsupported_algorithm)
476 log_gpgme (G_LOG_LEVEL_INFO, 0,
" unsupported algorithm (%s)",
477 decres->unsupported_algorithm);
478 if (decres->wrong_key_usage)
479 log_gpgme (G_LOG_LEVEL_INFO, 0,
" wrong key usage");
480 for (recp = decres->recipients; recp; recp = recp->next)
481 log_gpgme (G_LOG_LEVEL_INFO, recp->status,
482 " encrypted to keyid %s, algo=%d",
483 recp->keyid, recp->pubkey_algo);
486 result = gpgme_data_release_and_get_mem (out, r_plaintextlen);
489 g_critical (
"%s: error snatching memory", G_STRFUNC);
511 ctx = g_malloc0 (
sizeof *ctx);
512 ctx->
encctx = openvas_init_gpgme_ctx (
"openvasmd");
515 g_critical (
"%s: can't continue w/o a gpgme context\n", G_STRFUNC);
534 gpgme_release (ctx->
encctx);
556 key = find_the_key (ctx, TRUE);
559 gpgme_key_unref (key);
560 g_warning (
"A credentials encryption key already exists - " 561 "not creating another one.");
566 if (!create_the_key (ctx))
626 if (!ctx || !first_name)
631 stringbuf = g_string_sized_new (2048);
634 va_start (arg_ptr, first_name);
637 value = va_arg (arg_ptr,
const char *);
643 put32 (stringbuf, len);
644 g_string_append (stringbuf, name);
645 len = strlen (value);
648 g_warning (
"%s: value for '%s' larger than our limit (%d)",
650 g_string_free (stringbuf, TRUE);
654 put32 (stringbuf, len);
655 g_string_append (stringbuf, value);
658 while ((name = va_arg (arg_ptr,
const char *)))
661 plaintext = stringbuf->str;
662 plaintextlen = stringbuf->len;
663 g_string_free (stringbuf, FALSE);
664 g_assert (plaintextlen);
666 ciphertext = do_encrypt (ctx, plaintext, plaintextlen);
703 if (!ctx || !name || !*name)
707 static gboolean shown;
711 g_warning (
"note that decryption of credentials has been disabled");
727 if (!strcmp (nl->
name, name))
736 namelen = strlen (name);
744 n = get32 (p); p += 4; len -= 4;
747 if (n == namelen && !memcmp (p, name, namelen))
752 n = get32 (p); p += 4; len -= 4;
759 g_warning (
"%s: value for '%s' larger than our limit (%d)",
763 nl = g_malloc (
sizeof *nl + namelen);
765 strcpy (nl->
name, name);
769 strcpy (((
char *) nl) + (nl->name - (
char *) nl), name);
772 if (n + 1 < len && p[n] == 0)
786 nl->value = g_malloc (n + 1);
787 memcpy (nl->value, p, n);
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));
805 nl = g_malloc (
sizeof *nl + namelen);
807 strcpy (nl->
name, name);
811 strcpy (((
char *) nl) + (nl->name - (
char *) nl), name);
lsc_crypt_ctx_t lsc_crypt_new()
Return a new context for LSC encryption.
#define MAX_VALUE_LENGTH
The maximum size of an encrypted value.
int lsc_crypt_create_key()
Create the standard credential encryption key.
#define G_LOG_DOMAIN
GLib log domain.
const char * lsc_crypt_get_private_key(lsc_crypt_ctx_t ctx, const char *ciphertext)
Return an encrypted private key in the clear.
A linked list to help caching results.
int disable_encrypted_credentials
Flag indicating that encrypted credentials are disabled.
void lsc_crypt_flush(lsc_crypt_ctx_t ctx)
Flush an LSC encryption context.
#define ENCRYPTION_KEY_UID
The name of the encryption key.
const char * lsc_crypt_get_password(lsc_crypt_ctx_t ctx, const char *ciphertext)
Return an encrypted password in the clear.
The context object for encryption operations.
const char * lsc_crypt_decrypt(lsc_crypt_ctx_t ctx, const char *ciphertext, const char *name)
Return an encrypted value in the clear.
struct namelist_s * namelist
char * lsc_crypt_encrypt(lsc_crypt_ctx_t ctx, const char *first_name,...)
Encrypt a list of name/value pairs.
#define GPG_ERR_AMBIGUOUS
void lsc_crypt_release(lsc_crypt_ctx_t ctx)
Release an LSC encryption context.