/** * gnutls_pcert_import_openpgp: * @pcert: The pcert structure * @crt: The raw certificate to be imported * @flags: zero for now * * This convenience function will import the given certificate to a * #gnutls_pcert_st structure. The structure must be deinitialized * afterwards using gnutls_pcert_deinit(); * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_pcert_import_openpgp (gnutls_pcert_st* pcert, gnutls_openpgp_crt_t crt, unsigned int flags) { int ret; size_t sz; memset(pcert, 0, sizeof(*pcert)); pcert->type = GNUTLS_CRT_OPENPGP; pcert->cert.data = NULL; sz = 0; ret = gnutls_openpgp_crt_export(crt, GNUTLS_OPENPGP_FMT_RAW, NULL, &sz); if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { ret = gnutls_assert_val(ret); goto cleanup; } pcert->cert.data = gnutls_malloc(sz); if (pcert->cert.data == NULL) { ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); goto cleanup; } ret = gnutls_openpgp_crt_export(crt, GNUTLS_X509_FMT_DER, pcert->cert.data, &sz); if (ret < 0) { ret = gnutls_assert_val(ret); goto cleanup; } pcert->cert.size = sz; ret = gnutls_pubkey_init(&pcert->pubkey); if (ret < 0) { ret = gnutls_assert_val(ret); goto cleanup; } ret = gnutls_pubkey_import_openpgp(pcert->pubkey, crt, 0); if (ret < 0) { gnutls_pubkey_deinit(pcert->pubkey); ret = gnutls_assert_val(ret); goto cleanup; } return 0; cleanup: gnutls_free(pcert->cert.data); return ret; }
static void print_openpgp_info (gnutls_session_t session, int flag, int print_cert) { gnutls_openpgp_crt_t crt; const gnutls_datum_t *cert_list; unsigned int cert_list_size = 0; int ret; printf ("- Certificate type: OpenPGP\n"); cert_list = gnutls_certificate_get_peers (session, &cert_list_size); if (cert_list_size > 0) { gnutls_datum_t cinfo; gnutls_openpgp_crt_init (&crt); ret = gnutls_openpgp_crt_import (crt, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW); if (ret < 0) { fprintf (stderr, "Decoding error: %s\n", gnutls_strerror (ret)); return; } ret = gnutls_openpgp_crt_print (crt, flag, &cinfo); if (ret == 0) { printf ("- %s\n", cinfo.data); gnutls_free (cinfo.data); } if (print_cert) { size_t size = 0; char *p = NULL; ret = gnutls_openpgp_crt_export (crt, GNUTLS_OPENPGP_FMT_BASE64, p, &size); if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { p = malloc (size); if (!p) { fprintf (stderr, "gnutls_malloc\n"); exit (1); } ret = gnutls_openpgp_crt_export (crt, GNUTLS_OPENPGP_FMT_BASE64, p, &size); } if (ret < 0) { fprintf (stderr, "Encoding error: %s\n", gnutls_strerror (ret)); return; } fputs (p, stdout); fputs ("\n", stdout); gnutls_free (p); } gnutls_openpgp_crt_deinit (crt); } }
static void print_openpgp_info (gnutls_session_t session, const char *hostname, int insecure) { gnutls_openpgp_crt_t crt; const gnutls_datum_t *cert_list; int cert_list_size = 0; int hostname_ok = 0; int ret; cert_list = gnutls_certificate_get_peers (session, &cert_list_size); if (cert_list_size > 0) { gnutls_datum_t cinfo; gnutls_openpgp_crt_init (&crt); ret = gnutls_openpgp_crt_import (crt, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW); if (ret < 0) { fprintf (stderr, "Decoding error: %s\n", gnutls_strerror (ret)); return; } if (verbose) ret = gnutls_openpgp_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &cinfo); else ret = gnutls_openpgp_crt_print (crt, GNUTLS_CRT_PRINT_ONELINE, &cinfo); if (ret == 0) { printf (" - %s\n", cinfo.data); gnutls_free (cinfo.data); } if (print_cert) { size_t size = 0; char *p = NULL; ret = gnutls_openpgp_crt_export (crt, GNUTLS_OPENPGP_FMT_BASE64, p, &size); if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { p = malloc (size); if (!p) { fprintf (stderr, "gnutls_malloc\n"); exit (1); } ret = gnutls_openpgp_crt_export (crt, GNUTLS_OPENPGP_FMT_BASE64, p, &size); } if (ret < 0) { fprintf (stderr, "Encoding error: %s\n", gnutls_strerror (ret)); return; } fputs (p, stdout); fputs ("\n", stdout); gnutls_free (p); } if (hostname != NULL) { /* Check the hostname of the first certificate if it matches * the name of the host we connected to. */ if (gnutls_openpgp_crt_check_hostname (crt, hostname) == 0) hostname_ok = 1; else hostname_ok = 2; } gnutls_openpgp_crt_deinit (crt); } if (hostname_ok == 1) { printf ("- The hostname in the certificate does NOT match '%s'\n", hostname); if (!insecure) exit (1); } else if (hostname_ok == 2) { printf ("- The hostname in the certificate matches '%s'.\n", hostname); } }
/* Converts a parsed gnutls_openpgp_crt_t to a gnutls_cert structure. */ int _gnutls_openpgp_crt_to_gcert (gnutls_cert * gcert, gnutls_openpgp_crt_t cert) { int ret; gnutls_openpgp_keyid_t keyid; char err_buf[33]; memset (gcert, 0, sizeof (gnutls_cert)); gcert->cert_type = GNUTLS_CRT_OPENPGP; gcert->version = gnutls_openpgp_crt_get_version (cert); gcert->params_size = MAX_PUBLIC_PARAMS_SIZE; ret = gnutls_openpgp_crt_get_preferred_key_id (cert, keyid); if (ret == 0) { int idx; uint32_t kid32[2]; _gnutls_debug_log ("Importing Openpgp cert and using openpgp sub key: %s\n", _gnutls_bin2hex (keyid, sizeof (keyid), err_buf, sizeof (err_buf))); KEYID_IMPORT (kid32, keyid); idx = gnutls_openpgp_crt_get_subkey_idx (cert, keyid); if (idx < 0) { gnutls_assert (); return idx; } gcert->subject_pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm (cert, idx, NULL); gnutls_openpgp_crt_get_subkey_usage (cert, idx, &gcert->key_usage); gcert->use_subkey = 1; memcpy (gcert->subkey_id, keyid, sizeof (keyid)); ret = _gnutls_openpgp_crt_get_mpis (cert, kid32, gcert->params, &gcert->params_size); } else { _gnutls_debug_log ("Importing Openpgp cert and using main openpgp key\n"); gcert->subject_pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm (cert, NULL); gnutls_openpgp_crt_get_key_usage (cert, &gcert->key_usage); ret = _gnutls_openpgp_crt_get_mpis (cert, NULL, gcert->params, &gcert->params_size); gcert->use_subkey = 0; } if (ret < 0) { gnutls_assert (); return ret; } { /* copy the raw certificate */ #define SMALL_RAW 512 opaque *raw; size_t raw_size = SMALL_RAW; /* initially allocate a bogus size, just in case the certificate * fits in it. That way we minimize the DER encodings performed. */ raw = gnutls_malloc (raw_size); if (raw == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } ret = gnutls_openpgp_crt_export (cert, GNUTLS_OPENPGP_FMT_RAW, raw, &raw_size); if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { gnutls_assert (); gnutls_free (raw); return ret; } if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { raw = gnutls_realloc (raw, raw_size); if (raw == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } ret = gnutls_openpgp_crt_export (cert, GNUTLS_OPENPGP_FMT_RAW, raw, &raw_size); if (ret < 0) { gnutls_assert (); gnutls_free (raw); return ret; } } gcert->raw.data = raw; gcert->raw.size = raw_size; } return 0; }