gnutls_datum_t *load_secret_key(int mand, common_info_st * info) { char raw_key[64]; size_t raw_key_size = sizeof(raw_key); static gnutls_datum_t key; gnutls_datum_t hex_key; int ret; if (info->verbose) fprintf(stderr, "Loading secret key...\n"); if (info->secret_key == NULL) { if (mand) { fprintf(stderr, "missing --secret-key\n"); exit(1); } else return NULL; } hex_key.data = (void *) info->secret_key; hex_key.size = strlen(info->secret_key); ret = gnutls_hex_decode(&hex_key, raw_key, &raw_key_size); if (ret < 0) { fprintf(stderr, "hex_decode: %s\n", gnutls_strerror(ret)); exit(1); } key.data = (void *) raw_key; key.size = raw_key_size; return &key; }
gnutls_datum_t * load_secret_key (int mand, common_info_st * info) { unsigned char raw_key[64]; size_t raw_key_size = sizeof (raw_key); static gnutls_datum_t key; gnutls_datum_t hex_key; int ret; fprintf (stderr, "Loading secret key...\n"); if (info->secret_key == NULL) { if (mand) error (EXIT_FAILURE, 0, "missing --secret-key"); else return NULL; } hex_key.data = (char *) info->secret_key; hex_key.size = strlen (info->secret_key); ret = gnutls_hex_decode (&hex_key, raw_key, &raw_key_size); if (ret < 0) error (EXIT_FAILURE, 0, "hex_decode: %s", gnutls_strerror (ret)); key.data = raw_key; key.size = raw_key_size; return &key; }
/** * gnutls_psk_set_client_credentials - Used to set the username/password, in a gnutls_psk_client_credentials_t structure * @res: is a #gnutls_psk_client_credentials_t structure. * @username: is the user's zero-terminated userid * @key: is the user's key * @format: indicate the format of the key, either * %GNUTLS_PSK_KEY_RAW or %GNUTLS_PSK_KEY_HEX. * * This function sets the username and password, in a * gnutls_psk_client_credentials_t structure. Those will be used in * PSK authentication. @username should be an ASCII string or UTF-8 * strings prepared using the "SASLprep" profile of "stringprep". * The key can be either in raw byte format or in Hex (not with the * '0x' prefix). * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ int gnutls_psk_set_client_credentials (gnutls_psk_client_credentials_t res, const char *username, const gnutls_datum_t * key, gnutls_psk_key_flags flags) { int ret; if (username == NULL || key == NULL || key->data == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } ret = _gnutls_set_datum (&res->username, username, strlen (username)); if (ret < 0) return ret; if (flags == GNUTLS_PSK_KEY_RAW) { if (_gnutls_set_datum (&res->key, key->data, key->size) < 0) { gnutls_assert (); ret = GNUTLS_E_MEMORY_ERROR; goto error; } } else { /* HEX key */ size_t size; size = res->key.size = key->size / 2; res->key.data = gnutls_malloc (size); if (res->key.data == NULL) { gnutls_assert (); ret = GNUTLS_E_MEMORY_ERROR; goto error; } ret = gnutls_hex_decode (key, (char *) res->key.data, &size); res->key.size = (unsigned int) size; if (ret < 0) { gnutls_assert (); goto error; } } return 0; error: _gnutls_free_datum (&res->username); return ret; }
static int get_id(const char *url, uint8_t * bin, size_t * bin_size, unsigned cert) { int ret; unsigned url_size = strlen(url); const char *p = url, *p2; gnutls_datum_t tmp; if (cert != 0) { if (url_size < sizeof(WIN_URL) || strncmp(url, WIN_URL, WIN_URL_SIZE) != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); } else { if (url_size < sizeof(WIN_URL) || strncmp(url, WIN_URL, WIN_URL_SIZE) != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); } p += sizeof(WIN_URL) - 1; p = strstr(p, "id="); if (p == NULL) return gnutls_assert_val(GNUTLS_E_PARSING_ERROR); p += 3; p2 = strchr(p, ';'); if (p2 == NULL) { url_size = strlen(p); } else { url_size = (p2 - p); } tmp.data = p; tmp.size = url_size; ret = gnutls_hex_decode(&tmp, bin, bin_size); if (ret < 0) return ret; return 0; }
/** * infd_acl_account_info_from_xml: * @xml: The XML node from which to read the account information. * @error: Location to store error information, if any. * * Reads information for one account from a serialized XML node. The account * info can be written to XML with the infd_acl_account_info_to_xml() * function. If the function fails it returns %NULL and @error is set. * * Returns: A #InfdAclAccountInfo, or %NULL. Free with * infd_acl_account_info_free() when no longer needed. */ InfdAclAccountInfo* infd_acl_account_info_from_xml(xmlNodePtr xml, GError** error) { InfdAclAccountInfo* info; InfAclAccount* account; GError* local_error; gboolean has_first_seen; gdouble first_seen; gboolean has_last_seen; gdouble last_seen; xmlChar* password_salt; xmlChar* password_hash; gnutls_datum_t datum; size_t hash_len; int res; gchar* binary_salt; gchar* binary_hash; xmlNodePtr child; GPtrArray* certificate_array; guint i; g_return_val_if_fail(xml != NULL, NULL); g_return_val_if_fail(error == NULL || *error == NULL, NULL); local_error = NULL; has_first_seen = inf_xml_util_get_attribute_double( xml, "first-seen", &first_seen, &local_error ); if(local_error != NULL) return NULL; has_last_seen = inf_xml_util_get_attribute_double( xml, "last-seen", &last_seen, &local_error ); if(local_error != NULL) return NULL; account = inf_acl_account_from_xml(xml, error); if(account == NULL) return NULL; password_salt = inf_xml_util_get_attribute(xml, "password-salt"); password_hash = inf_xml_util_get_attribute(xml, "password-hash"); if( (password_salt != NULL && password_hash == NULL) || (password_salt == NULL && password_hash != NULL)) { g_set_error( error, inf_request_error_quark(), INF_REQUEST_ERROR_INVALID_ATTRIBUTE, "%s", _("If one of \"password-hash\" or \"password-salt\" is provided, the " "other must be provided as well.") ); if(password_salt != NULL) xmlFree(password_salt); if(password_hash != NULL) xmlFree(password_hash); inf_acl_account_free(account); return NULL; } if(password_salt != NULL && password_hash != NULL) { datum.data = password_salt; datum.size = strlen(password_salt); hash_len = 32; binary_salt = g_malloc(hash_len); res = gnutls_hex_decode(&datum, binary_salt, &hash_len); xmlFree(password_salt); if(hash_len != 32) { g_set_error( error, inf_request_error_quark(), INF_REQUEST_ERROR_INVALID_ATTRIBUTE, "%s", _("The length of the password salt is incorrect, it should " "be 32 bytes") ); xmlFree(password_hash); g_free(binary_salt); return NULL; } else if(res != GNUTLS_E_SUCCESS) { inf_gnutls_set_error(error, res); xmlFree(password_hash); g_free(binary_salt); return NULL; } datum.data = password_hash; datum.size = strlen(password_hash); hash_len = gnutls_hash_get_len(GNUTLS_DIG_SHA256); binary_hash = g_malloc(hash_len); res = gnutls_hex_decode(&datum, binary_hash, &hash_len); xmlFree(password_hash); if(hash_len != gnutls_hash_get_len(GNUTLS_DIG_SHA256)) { g_set_error( error, inf_request_error_quark(), INF_REQUEST_ERROR_INVALID_ATTRIBUTE, _("The length of the password hash is incorrect, it should be " "%u bytes"), (unsigned int)gnutls_hash_get_len(GNUTLS_DIG_SHA256) ); g_free(binary_salt); g_free(binary_hash); return NULL; } else if(res != GNUTLS_E_SUCCESS) { inf_gnutls_set_error(error, res); g_free(binary_salt); g_free(binary_hash); return NULL; } } else { binary_salt = NULL; binary_hash = NULL;\ if(password_salt != NULL) xmlFree(password_salt); if(password_hash != NULL) xmlFree(password_hash); } certificate_array = g_ptr_array_new(); for(child = xml->children; child != NULL; child = child->next) { if(child->type != XML_ELEMENT_NODE) continue; if(strcmp((const char*)child->name, "certificate") == 0) g_ptr_array_add(certificate_array, xmlNodeGetContent(child)); } info = infd_acl_account_info_new(account->id, account->name, FALSE); inf_acl_account_free(account); info->certificates = g_malloc(sizeof(gchar*) * certificate_array->len); for(i = 0; i < certificate_array->len; ++i) { info->certificates[i] = g_strdup(certificate_array->pdata[i]); xmlFree(certificate_array->pdata[i]); } info->n_certificates = certificate_array->len; g_ptr_array_free(certificate_array, TRUE); info->password_salt = binary_salt; info->password_hash = binary_hash; if(has_first_seen == TRUE) info->first_seen = first_seen * 1e6; else info->first_seen = 0; if(has_last_seen == TRUE) info->last_seen = last_seen * 1e6; else info->last_seen = 0; return info; }
static int psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key) { const char *hint = gnutls_psk_client_get_hint (session); unsigned char *rawkey; char *passwd; int ret; size_t res_size; gnutls_datum_t tmp; printf ("- PSK client callback. "); if (hint) printf ("PSK hint '%s'\n", hint); else printf ("No PSK hint\n"); if (info.psk_username) *username = gnutls_strdup (info.psk_username); else { char *tmp = NULL; size_t n; printf ("Enter PSK identity: "); fflush (stdout); getline (&tmp, &n, stdin); if (tmp == NULL) { fprintf (stderr, "No username given, aborting...\n"); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } if (tmp[strlen (tmp) - 1] == '\n') tmp[strlen (tmp) - 1] = '\0'; if (tmp[strlen (tmp) - 1] == '\r') tmp[strlen (tmp) - 1] = '\0'; *username = gnutls_strdup (tmp); free (tmp); } if (!*username) return GNUTLS_E_MEMORY_ERROR; passwd = getpass ("Enter key: "); if (passwd == NULL) { fprintf (stderr, "No key given, aborting...\n"); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } tmp.data = passwd; tmp.size = strlen (passwd); res_size = tmp.size / 2 + 1; rawkey = gnutls_malloc (res_size); if (rawkey == NULL) return GNUTLS_E_MEMORY_ERROR; ret = gnutls_hex_decode (&tmp, rawkey, &res_size); if (ret < 0) { fprintf (stderr, "Error deriving password: %s\n", gnutls_strerror (ret)); gnutls_free (*username); return ret; } key->data = rawkey; key->size = res_size; if (info.debug) { char hexkey[41]; res_size = sizeof (hexkey); gnutls_hex_encode (key, hexkey, &res_size); fprintf (stderr, "PSK username: %s\n", *username); fprintf (stderr, "PSK hint: %s\n", hint); fprintf (stderr, "PSK key: %s\n", hexkey); } return 0; }
static int decode_tpmkey_url(const char *url, struct tpmkey_url_st *s) { char *p; size_t size; int ret; unsigned int i, j; if (strstr(url, "tpmkey:") == NULL) return gnutls_assert_val(GNUTLS_E_PARSING_ERROR); memset(s, 0, sizeof(*s)); p = strstr(url, "file="); if (p != NULL) { p += sizeof("file=") - 1; size = strlen(p); s->filename = gnutls_malloc(size + 1); if (s->filename == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); ret = unescape_string(s->filename, p, &size, ';'); if (ret < 0) { gnutls_assert(); goto cleanup; } s->filename[size] = 0; } else if ((p = strstr(url, "uuid=")) != NULL) { char tmp_uuid[33]; uint8_t raw_uuid[16]; gnutls_datum_t tmp; p += sizeof("uuid=") - 1; size = strlen(p); for (j = i = 0; i < size; i++) { if (j == sizeof(tmp_uuid) - 1) { break; } if (c_isalnum(p[i])) tmp_uuid[j++] = p[i]; } tmp_uuid[j] = 0; tmp.data = (void*)tmp_uuid; tmp.size = strlen(tmp_uuid); size = sizeof(raw_uuid); ret = gnutls_hex_decode(&tmp, raw_uuid, &size); if (ret < 0) { gnutls_assert(); goto cleanup; } memcpy(&s->uuid.ulTimeLow, raw_uuid, 4); memcpy(&s->uuid.usTimeMid, &raw_uuid[4], 2); memcpy(&s->uuid.usTimeHigh, &raw_uuid[6], 2); s->uuid.bClockSeqHigh = raw_uuid[8]; s->uuid.bClockSeqLow = raw_uuid[9]; memcpy(&s->uuid.rgbNode, &raw_uuid[10], 6); s->uuid_set = 1; } else { return gnutls_assert_val(GNUTLS_E_PARSING_ERROR); } if (strstr(url, "storage=user") != NULL) s->storage = TSS_PS_TYPE_USER; else s->storage = TSS_PS_TYPE_SYSTEM; return 0; cleanup: clear_tpmkey_url(s); return ret; }
/* Run an HMAC using the key above on the library binary data. * Returns true on success and false on error. */ static unsigned check_binary_integrity(const char* libname, const char* symbol) { int ret; unsigned prev; char mac_file[GNUTLS_PATH_MAX]; char file[GNUTLS_PATH_MAX]; uint8_t hmac[HMAC_SIZE]; uint8_t new_hmac[HMAC_SIZE]; size_t hmac_size; gnutls_datum_t data; ret = get_library_path(libname, symbol, file, sizeof(file)); if (ret < 0) { _gnutls_debug_log("Could not get path for library %s\n", libname); return 0; } _gnutls_debug_log("Loading: %s\n", file); ret = gnutls_load_file(file, &data); if (ret < 0) { _gnutls_debug_log("Could not load: %s\n", file); return gnutls_assert_val(0); } prev = _gnutls_get_lib_state(); _gnutls_switch_lib_state(LIB_STATE_OPERATIONAL); ret = gnutls_hmac_fast(HMAC_ALGO, FIPS_KEY, sizeof(FIPS_KEY)-1, data.data, data.size, new_hmac); _gnutls_switch_lib_state(prev); gnutls_free(data.data); if (ret < 0) return gnutls_assert_val(0); /* now open the .hmac file and compare */ get_hmac_file(mac_file, sizeof(mac_file), file); ret = gnutls_load_file(mac_file, &data); if (ret < 0) { get_hmac_file2(mac_file, sizeof(mac_file), file); ret = gnutls_load_file(mac_file, &data); if (ret < 0) { _gnutls_debug_log("Could not open %s for MAC testing: %s\n", mac_file, gnutls_strerror(ret)); return gnutls_assert_val(0); } } hmac_size = hex_data_size(data.size); ret = gnutls_hex_decode(&data, hmac, &hmac_size); gnutls_free(data.data); if (ret < 0) { _gnutls_debug_log("Could not convert hex data to binary for MAC testing for %s.\n", libname); return gnutls_assert_val(0); } if (hmac_size != sizeof(hmac) || memcmp(hmac, new_hmac, sizeof(hmac)) != 0) { _gnutls_debug_log("Calculated MAC for %s does not match\n", libname); return gnutls_assert_val(0); } _gnutls_debug_log("Successfully verified MAC for %s (%s)\n", mac_file, libname); return 1; }