Пример #1
0
/* Verifies signature for the local file DATA_FILENAME first, and on failure
 * downloads the signature based on DATA_URL and tries to verify again.
 *
 * returns: true if signature verification succeeded, false if verification
 * failed, or the signature download failed
 */
bool download_and_verify_signature(const char *data_url, const char *data_filename)
{
	char *sig_url;
	char *sig_filename;
	int ret;
	bool result;

	if (!sigcheck) {
		return false;
	}

	string_or_die(&sig_url, "%s.sig", data_url);

	string_or_die(&sig_filename, "%s.sig", data_filename);

	// Try verifying a local copy of the signature first
	result = verify_signature(data_filename, sig_filename, false);
	if (result) {
		goto out;
	}

	// Else, download a fresh signature, and verify
	ret = swupd_curl_get_file(sig_url, sig_filename, NULL, NULL, false);
	if (ret == 0) {
		result = verify_signature(data_filename, sig_filename, true);
	} else {
		// download failed
		result = false;
	}
out:
	free(sig_filename);
	free(sig_url);
	return result;
}
Пример #2
0
void verify_page(fz_context *ctx, pdf_document *doc, int n, pdf_page *page)
{
	pdf_widget *widget;
	for (widget = pdf_first_widget(ctx, page); widget; widget = pdf_next_widget(ctx, widget))
		if (pdf_widget_type(ctx, widget) == PDF_WIDGET_TYPE_SIGNATURE)
			verify_signature(ctx, doc, n, widget);
}
Пример #3
0
int main(int argc, char *argv[])
{
	if (argc != 2)
		fail("usage: sceverify filename");

	ptr = mmap_file(argv[1]);

	type = be16(ptr + 0x0a);

	if (type == 1)
		read_self_header();
	else if(type == 3)
		read_pkg_header();
	else if(type == 4)
		read_spp_header();
	else
		fail("Unknown type: %d", type);

	if (flags & 0x8000)
		fail("devkit file; nothing to verify");

	if (klist == NULL)
		fail("no key found");

	decrypt();
	verify_signature();
	verify_hashes();

	if (did_fail)
		printf(" * please not that the hash will always fail for "
		       "unaligned non-LOAD phdrs\n");
	return 0;
}
Пример #4
0
void
inspect_key (SSL *ssl, const char *hostname)
{

    verify_signature (ssl, hostname);
    check_name (ssl, hostname);
}
Пример #5
0
bool PeerRequest::validate(const Lock& lock) const
{
    bool validNym = false;

    if (nym_) {
        validNym = nym_->VerifyPseudonym();
    } else {
        otErr << __FUNCTION__ << ": invalid nym." << std::endl;
    }

    const bool validSyntax = proto::Validate(contract(lock), VERBOSE);

    if (!validSyntax) {
        otErr << __FUNCTION__ << ": invalid syntax." << std::endl;
    }

    if (1 > signatures_.size()) {
        otErr << __FUNCTION__ << ": Missing signature." << std::endl;

        return false;
    }

    bool validSig = false;
    auto& signature = *signatures_.cbegin();

    if (signature) { validSig = verify_signature(lock, *signature); }

    if (!validSig) {
        otErr << __FUNCTION__ << ": invalid signature." << std::endl;
    }

    return (validNym && validSyntax && validSig);
}
Пример #6
0
int
inline_gpg_verify(const char *content, size_t len, const char *keyring)
{
	verify_signature(content, len, keyring, NULL);

	return 0;
}
Пример #7
0
void
inspect_key (ssl_context *ssl, const char *hostname)
{
  verify_signature (ssl, hostname);

  // ssl_get_verify_result() already checks for CN / subjectAltName match
  // and reports the mismatch as error. So check_name() is not called
}
Пример #8
0
void verify_page(fz_context *ctx, pdf_document *doc, int n, pdf_page *page)
{
	pdf_annot *annot;
	for (annot = pdf_first_annot(ctx, page); annot; annot = pdf_next_annot(ctx, annot))
		if (pdf_annot_type(ctx, annot) == PDF_ANNOT_WIDGET)
			if (pdf_widget_type(ctx, annot) == PDF_WIDGET_TYPE_SIGNATURE)
				verify_signature(ctx, doc, n, annot);
}
Пример #9
0
bool verify_signature(const ec_uncompressed& point, const hash_digest& hash,
    const ec_signature& signature)
{
    secp256k1_pubkey pubkey;
    const auto context = verification.context();
    return parse(context, pubkey, point) &&
        verify_signature(context, pubkey, hash, signature);
}
int verify_message_signature(notary_header *hdr, RSA* pub_key) {
    
    int sig_len = ntohs(hdr->sig_len);
    int data_len = ntohs(hdr->total_len) - sig_len - sizeof(notary_header);
    char* data = (char*)(hdr + 1);
    unsigned char *sig = (unsigned char*) (data + data_len);
    DPRINTF(DEBUG_CRYPTO, "msg verify: data_len = %d sig_len = %d \n",
          data_len, sig_len);
    return verify_signature(data, data_len, pub_key, sig, sig_len);
}
Пример #11
0
bool verify_update_signature(dwindow_update_signature *signature)
{
	if (!signature)
		return false;

	unsigned char sha1[20];
	SHA1Hash(sha1, ((unsigned char*)signature) + sizeof(signature->signature), 
		sizeof(dwindow_update_signature) - sizeof(signature->signature));

	return verify_signature((DWORD*)sha1, (DWORD*)signature->signature, dwindow_network_n);
}
Пример #12
0
int
main(int argc, char **argv)
{
    GError *error = NULL;
    int retval = EXIT_SUCCESS;
    EVP_PKEY *pubkey;

    if (!process_arguments(&argc, &argv, &error)) {
        retval = handle_error(error);
        g_clear_error(&error);
    } else if ((pubkey = read_public_key(option_key_file, &error)) == NULL) {
        retval = handle_error(error);
        g_clear_error(&error);
    } else {
        FILE *infile = fopen(option_data_file, "rb");

        if (infile == NULL) {
            fprintf(stderr, "%s: %s\n", option_data_file, strerror(errno));
            retval = EXIT_IO_ERROR;
        } else {
            uint8_t hash[SHA256_DIGEST_LENGTH];
            uint8_t signature[SIGNATURE_SIZE];

            if (fread(signature, 1, sizeof(signature), infile) !=
                sizeof(signature)) {
                if (ferror(infile)) {
                    fprintf(
                        stderr, "%s: %s\n", option_data_file, strerror(errno));
                    retval = EXIT_IO_ERROR;
                } else {
                    fprintf(stderr,
                            "%s: File too short for signature\n",
                            option_data_file);
                    retval = EXIT_FORMAT_ERROR;
                }
            } else if (!hash_stream(infile, hash, &error) ||
                       !verify_signature(hash, signature, pubkey, &error)) {
                retval = handle_error(error);
                g_clear_error(&error);
            } else if (option_out_file &&
                       !write_out_file(infile, option_out_file, &error)) {
                retval = handle_error(error);
                g_clear_error(&error);
            }

            fclose(infile);
        }

        EVP_PKEY_free(pubkey);
    }

    return retval;
}
Пример #13
0
int sigverify_main(int argc, char *argv[])
{
    int opt;

    static struct option long_options[] = {
        {"help",      no_argument, 0, 'h'},
        {0, 0, 0, 0}
    };

    int long_index = 0;

    while ((opt = getopt_long(argc, argv, "h", long_options, &long_index)) != -1) {
        switch (opt) {
        case 'h':
            sigverify_usage(stdout);
            return EXIT_SUCCESS;

        default:
            sigverify_usage(stderr);
            return EXIT_FAILURE;
        }
    }

    if (argc - optind != 2) {
        sigverify_usage(stderr);
        return EXIT_FAILURE;
    }

#if COMPILE_ERROR_STRINGS
    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();
#endif

    const char *path = argv[optind];
    const char *sig_path = argv[optind + 1];

    SigVerifyResult result = verify_signature(path, sig_path);

    switch (result) {
    case SigVerifyResult::Valid:
        return EXIT_SUCCESS;
    case SigVerifyResult::Invalid:
        return EXIT_INVALID;
    case SigVerifyResult::Failure:
    default:
        return EXIT_FAILURE;
    }
}
Пример #14
0
int _tmain()
{
	const wchar_t* file_name = L"Diablo III Launcher.exe";
	if (verify_signature(file_name) == true)
	{
		wprintf_s(L"The file \"%s\" is signed and the signature was verified.\n", file_name);

		std::wstring signer = get_signer(file_name);
		wprintf_s(L"%s signer is %s\n", file_name, signer.c_str());
	}
	else
	{
		wprintf_s(L"The file \"%s\" is not trusted.\n", file_name);
	}

	return 0;
}
Пример #15
0
/**
 * Verifies "data" against "signature".
 *
 * @return TRUE if the signature matches.
 */
bool
svn_release_notification_verify(uint32 revision, time_t date,
                                const struct array *signature)
{
    char rev[12], data[64];
    struct array input;

    uint32_to_string_buf(revision, rev, sizeof rev);
    input.data = (void *) data;
    input.size = concat_strings(data, sizeof data,
                                "r", rev,
                                "@", uint32_to_string(date),
                                (void *) 0);

    return verify_signature(svn_release_notify_certificate(),
                            &input, signature);
}
Пример #16
0
retvalue signature_check(const struct signature_requirement *requirements, const char *releasegpg, const char *releasename, const char *releasedata, size_t releaselen) {
	gpg_error_t err;
	int gpgfd;
	gpgme_data_t dh, dh_gpg;

	assert (requirements != NULL);

	if (FAILEDTOALLOC(releasedata) || FAILEDTOALLOC(releasegpg))
		return RET_ERROR_OOM;

	assert (context != NULL);

	/* Read the file and its signature into memory: */
	gpgfd = open(releasegpg, O_RDONLY|O_NOCTTY);
	if (gpgfd < 0) {
		int e = errno;
		fprintf(stderr, "Error opening '%s': %s\n",
				releasegpg, strerror(e));
		return RET_ERRNO(e);
	}
	err = gpgme_data_new_from_fd(&dh_gpg, gpgfd);
	if (err != 0) {
		(void)close(gpgfd);
		fprintf(stderr, "Error reading '%s':\n", releasegpg);
		return gpgerror(err);
	}
	err = gpgme_data_new_from_mem(&dh, releasedata, releaselen, 0);
	if (err != 0) {
		gpgme_data_release(dh_gpg);
		return gpgerror(err);
	}

	/* Verify the signature */

	err = gpgme_op_verify(context, dh_gpg, dh, NULL);
	gpgme_data_release(dh_gpg);
	gpgme_data_release(dh);
	close(gpgfd);
	if (err != 0) {
		fprintf(stderr, "Error verifying '%s':\n", releasegpg);
		return gpgerror(err);
	}

	return verify_signature(requirements, releasegpg, releasename);
}
/**
 * Given the file name of a signed boot image, verifies the signature
 * @param image_file Name of the boot image file
 */
static int verify(const char *image_file)
{
    BootSignature *bs = NULL;
    int fd = -1;
    int rc = 1;
    off64_t offset = 0;

    if (!image_file) {
        return rc;
    }

    if ((fd = open(image_file, O_RDONLY | O_LARGEFILE)) == -1) {
        return rc;
    }

    if (get_signature_offset(fd, &offset) == -1) {
        goto out;
    }

    if (read_signature(fd, offset, &bs) == -1) {
        goto out;
    }

    if (validate_signature_block(bs, offset) == -1) {
        goto out;
    }

    if (verify_signature(fd, offset, bs) == -1) {
        goto out;
    }

    printf("Signature is VALID\n");
    rc = 0;

out:
    if (bs) {
        BootSignature_free(bs);
    }

    if (fd != -1) {
        close(fd);
    }

    return rc;
}
Пример #18
0
static bool check_signature(const char *path, const char *sig_path)
{
    SigVerifyResult result;
    result = verify_signature(path, sig_path);
    switch (result) {
    case SigVerifyResult::VALID:
        return true;
    case SigVerifyResult::INVALID:
        LOGE("%s: Invalid signature", path);
        return false;
    case SigVerifyResult::FAILURE:
        LOGE("%s: Failed to check signature", path);
        return false;
    default:
        assert(false);
        return false;
    }
}
static bool	process_hunk(char const *program,
			     struct notify_info *notify,
			     struct memory_block_data const *payload,
			     struct memory_block_signature const *signature)
{
	struct signature_algorithm	*sigalg = NULL;
	struct decompression_algorithm	*decompalg = NULL;


	sigalg = create_sigalg(signature);
	if (!sigalg)
		goto err;

	decompalg = create_decompress(payload);
	if (!decompalg && payload->compression != STREAM_COMPRESS_NONE)
		goto err;

	if (!send_stream(program, notify, payload, sigalg, decompalg))
		goto err;

	if (!signature_update(sigalg, payload->mem.stream->extra_salt,
			      payload->mem.stream->extra_salt_len) ||
	    !signature_update(sigalg, signature->shdr->salt,
			      sizeof signature->shdr->salt) ||
	    !signature_update(sigalg, signature->hhdr,
			      sizeof *signature->hhdr))
		goto err;

	if (signature->mem.len && !verify_signature(signature, sigalg))
		goto err;

	if (!finish_stream(program, payload, sigalg))
		goto err;

	signature_free(sigalg);

	return true;

err:
	decompression_free(decompalg);
	signature_free(sigalg);

	return false;
}
Пример #20
0
int
detached_gpg_verify(const char *content, size_t len,
    const char *signature, size_t signature_len, const char *keyring)
{
	int fd;
	const char *tmpdir;
	char *tempsig;
	ssize_t ret;

	if (gpg_cmd == NULL) {
		warnx("GPG variable not set, failing signature check");
		return -1;
	}

	if ((tmpdir = getenv("TMPDIR")) == NULL)
		tmpdir = "/tmp";
	tempsig = xasprintf("%s/pkg_install.XXXXXX", tmpdir);

	fd = mkstemp(tempsig);
	if (fd == -1) {
		warnx("Creating temporary file for GPG signature failed");
		return -1;
	}

	while (signature_len) {
		ret = write(fd, signature, signature_len);
		if (ret == -1)
			err(EXIT_FAILURE, "Write to GPG failed");
		if (ret == 0)
			errx(EXIT_FAILURE, "Short write to GPG");
		signature_len -= ret;
		signature += ret;
	}

	verify_signature(content, len, keyring, tempsig);

	unlink(tempsig);
	close(fd);
	free(tempsig);

	return 0;
}
Пример #21
0
static gpg_error_t
collect_signature (void *cookie, const char *data)
{
  receive_ctx_t ctx = cookie;

  if (!ctx->signature)
    if (!(ctx->signature = es_fopenmem (MAX_SIGNATURE, "w+b,samethread")))
      return gpg_error_from_syserror ();
  if (data)
    es_fputs (data, ctx->signature);

  if (es_ferror (ctx->signature))
    return gpg_error_from_syserror ();

  if (!data)
    {
      verify_signature (ctx);
    }

  return 0;
}
Пример #22
0
int asymmetric_verify(struct key *keyring, const char *sig,
		      int siglen, const char *data, int datalen)
{
	struct public_key_signature pks;
	struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
	struct key *key;
	int ret = -ENOMEM;

	if (siglen <= sizeof(*hdr))
		return -EBADMSG;

	siglen -= sizeof(*hdr);

	if (siglen != __be16_to_cpu(hdr->sig_size))
		return -EBADMSG;

	if (hdr->hash_algo >= PKEY_HASH__LAST)
		return -ENOPKG;

	key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid));
	if (IS_ERR(key))
		return PTR_ERR(key);

	memset(&pks, 0, sizeof(pks));

	pks.pkey_hash_algo = hdr->hash_algo;
	pks.digest = (u8 *)data;
	pks.digest_size = datalen;
	pks.nr_mpi = 1;
	pks.rsa.s = mpi_read_raw_data(hdr->sig, siglen);

	if (pks.rsa.s)
		ret = verify_signature(key, &pks);

	mpi_free(pks.rsa.s);
	key_put(key);
	pr_debug("%s() = %d\n", __func__, ret);
	return ret;
}
/**
 * restrict_link_by_signature - Restrict additions to a ring of public keys
 * @trust_keyring: A ring of keys that can be used to vouch for the new cert.
 * @type: The type of key being added.
 * @payload: The payload of the new key.
 *
 * Check the new certificate against the ones in the trust keyring.  If one of
 * those is the signing key and validates the new certificate, then mark the
 * new certificate as being trusted.
 *
 * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a
 * matching parent certificate in the trusted list, -EKEYREJECTED if the
 * signature check fails or the key is blacklisted and some other error if
 * there is a matching certificate but the signature check cannot be performed.
 */
int restrict_link_by_signature(struct key *trust_keyring,
			       const struct key_type *type,
			       const union key_payload *payload)
{
	const struct public_key_signature *sig;
	struct key *key;
	int ret;

	pr_devel("==>%s()\n", __func__);

	if (!trust_keyring)
		return -ENOKEY;

	if (type != &key_type_asymmetric)
		return -EOPNOTSUPP;

	sig = payload->data[asym_auth];
	if (!sig->auth_ids[0] && !sig->auth_ids[1])
		return -ENOKEY;

	if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
		return -EPERM;

	/* See if we have a key that signed this one. */
	key = find_asymmetric_key(trust_keyring,
				  sig->auth_ids[0], sig->auth_ids[1],
				  false);
	if (IS_ERR(key))
		return -ENOKEY;

	if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))
		ret = -ENOKEY;
	else
		ret = verify_signature(key, sig);
	key_put(key);
	return ret;
}
Пример #24
0
static void *worker_loop(void *ignored) {
  bool keep_running = true;
  while(keep_running) {
    brine_task_s *task = (brine_task_s *) brine_queue_dequeue(queue);
    if (!task) {
      keep_running = false;
      break;
    }
    switch(task->cmd) {
    case BRINE_STOP:
      keep_running = false;
      break;
    case BRINE_NEW_KEYPAIR:
      generate_keypair(task);
      break;
    case BRINE_NEW_KEYPAIR_FROM_SEED:
      generate_keypair_from_seed(task);
      break;
    case BRINE_SIGN_MSG:
      sign_message(task);
      break;
    case BRINE_VERIFY:
      verify_signature(task);
      break;
    case BRINE_TO_BINARY:
      keypair_to_binary(task);
      break;
    case BRINE_TO_KEYPAIR:
      binary_to_keypair(task);
      break;
    default:
      break;
    }
    brine_task_destroy(&task);
  }
  return NULL;
}
Пример #25
0
TEST_FIXTURE(HandshakeFixture, VerifiedSignatureIsHMAC)
{
  int err = verify_signature(signature, pubkey, expected_hmac);
  CHECK_EQUAL(0, err);
}
Пример #26
0
static themis_status_t secure_session_finish_server(secure_session_t *session_ctx, const void *data, size_t data_length, void *output, size_t *output_length)
{
	const soter_container_hdr_t *proto_message = data;
	soter_container_hdr_t *response_message;
	themis_status_t res;

	const uint8_t *mac;
	size_t mac_length = 0;

	const uint8_t *signature;
	size_t signature_length;

	soter_kdf_context_buf_t sign_data[4];

	uint8_t ecdh_key[1024];
	size_t ecdh_key_length = sizeof(ecdh_key);

	uint8_t shared_secret[1024];
	size_t shared_secret_length = sizeof(shared_secret);


	if (data_length < sizeof(soter_container_hdr_t))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if (memcmp(proto_message->tag, THEMIS_SESSION_PROTO_TAG, SOTER_CONTAINER_TAG_LENGTH))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if (data_length < (soter_container_data_size(proto_message) + sizeof(soter_container_hdr_t)))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if (THEMIS_SUCCESS != soter_verify_container_checksum(proto_message))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	/* Get length of used mac */
	res = compute_mac(session_ctx->peer.ecdh_key, session_ctx->peer.ecdh_key_length, NULL, 0, NULL, &mac_length);
	if (THEMIS_BUFFER_TOO_SMALL != res)
	{
		return res;
	}

	signature_length = soter_container_data_size(proto_message) - mac_length;
	signature = soter_container_const_data(proto_message);
	mac = signature + signature_length;

	res = soter_asym_ka_export_key(&(session_ctx->ecdh_ctx), ecdh_key, &ecdh_key_length, false);
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	sign_data[0].data = session_ctx->peer.ecdh_key;
	sign_data[0].length = session_ctx->peer.ecdh_key_length;

	sign_data[1].data = ecdh_key;
	sign_data[1].length = ecdh_key_length;

	sign_data[2].data = session_ctx->peer.id;
	sign_data[2].length = session_ctx->peer.id_length;

	sign_data[3].data = session_ctx->we.id;
	sign_data[3].length = session_ctx->we.id_length;

	res = verify_signature(session_ctx->peer.sign_key, session_ctx->peer.sign_key_length, sign_data, 4, signature, signature_length);
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	res = soter_asym_ka_derive(&(session_ctx->ecdh_ctx), session_ctx->peer.ecdh_key, session_ctx->peer.ecdh_key_length, shared_secret, &shared_secret_length);
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	res = soter_kdf(NULL, 0, SESSION_ID_GENERATION_LABEL, sign_data, 4, &(session_ctx->session_id), sizeof(session_ctx->session_id));
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	sign_data[0].data = (const uint8_t *)(&(session_ctx->session_id));
	sign_data[0].length = sizeof(session_ctx->session_id);

	res = soter_kdf(shared_secret, shared_secret_length, SESSION_MASTER_KEY_GENERATION_LABEL, sign_data, 1, session_ctx->session_master_key, sizeof(session_ctx->session_master_key));
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	sign_data[0].data = ecdh_key;
	sign_data[0].length = ecdh_key_length;

	sign_data[1].data = (const uint8_t *)(&(session_ctx->session_id));
	sign_data[1].length = sizeof(session_ctx->session_id);

	res = verify_mac(session_ctx->session_master_key, sizeof(session_ctx->session_master_key), sign_data, 2, mac, mac_length);
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	sign_data[0].data = session_ctx->peer.ecdh_key;
	sign_data[0].length = session_ctx->peer.ecdh_key_length;

	/* we will reuse ecdh_key buffer for mac response computation */
	ecdh_key_length = sizeof(ecdh_key) - sizeof(soter_container_hdr_t);
	response_message = (soter_container_hdr_t *)ecdh_key;

	res = compute_mac(session_ctx->session_master_key, sizeof(session_ctx->session_master_key), sign_data, 2, soter_container_data(response_message), &ecdh_key_length);
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	if ((NULL == output) || (*output_length < (ecdh_key_length + sizeof(soter_container_hdr_t))))
	{
		*output_length = ecdh_key_length + sizeof(soter_container_hdr_t);
		return THEMIS_BUFFER_TOO_SMALL;
	}

	*output_length = ecdh_key_length + sizeof(soter_container_hdr_t);

	res = secure_session_derive_message_keys(session_ctx);
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	memcpy(response_message->tag, THEMIS_SESSION_PROTO_TAG, SOTER_CONTAINER_TAG_LENGTH);
	soter_container_set_data_size(response_message, ecdh_key_length);
	soter_update_container_checksum(response_message);

	memcpy(output, ecdh_key, soter_container_data_size(response_message) + sizeof(soter_container_hdr_t));

	/* "Server mode": negotiation completed */
	session_ctx->state_handler = NULL;

	if (session_ctx->user_callbacks->state_changed)
	{
		session_ctx->user_callbacks->state_changed(STATE_ESTABLISHED, session_ctx->user_callbacks->user_data);
	}

	return res;
}
Пример #27
0
static themis_status_t secure_session_proceed_client(secure_session_t *session_ctx, const void *data, size_t data_length, void *output, size_t *output_length)
{
	const soter_container_hdr_t *proto_message = data;
	const soter_container_hdr_t *peer_id;

	const soter_container_hdr_t *peer_ecdh_key;
	size_t peer_ecdh_key_length;

	const uint8_t *signature;
	size_t signature_length;

	themis_status_t res = THEMIS_SUCCESS;
	soter_status_t soter_status;

	uint8_t sign_key[1024]; /* Should be enough for RSA 8192 which is 512 bytes */
	size_t sign_key_length;

	uint8_t ecdh_key[1024];
	size_t ecdh_key_length = sizeof(ecdh_key);

	const soter_container_hdr_t *peer_sign_key;
	soter_kdf_context_buf_t sign_data[4];

	uint8_t *data_to_send = output;
	size_t length_to_send;

	soter_container_hdr_t *container;
	uint8_t *mac;

	if (data_length < sizeof(soter_container_hdr_t))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if (memcmp(proto_message->tag, THEMIS_SESSION_PROTO_TAG, SOTER_CONTAINER_TAG_LENGTH))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if (data_length < (soter_container_data_size(proto_message) + sizeof(soter_container_hdr_t)))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if (THEMIS_SUCCESS != soter_verify_container_checksum(proto_message))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	peer_id = (const soter_container_hdr_t *)soter_container_const_data(proto_message);

	if (memcmp(peer_id->tag, THEMIS_SESSION_ID_TAG, SOTER_CONTAINER_TAG_LENGTH))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if (THEMIS_SUCCESS != soter_verify_container_checksum(peer_id))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	peer_ecdh_key = (const soter_container_hdr_t *)(soter_container_const_data(peer_id) + soter_container_data_size(peer_id));

	if (memcmp(peer_ecdh_key->tag, EC_PUB_KEY_PREF, strlen(EC_PUB_KEY_PREF)))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	peer_ecdh_key_length = ntohl(peer_ecdh_key->size);

	signature = (const uint8_t *)peer_ecdh_key + peer_ecdh_key_length;
	signature_length = (const uint8_t *)data + soter_container_data_size(proto_message) + sizeof(soter_container_hdr_t) - signature;
	if (session_ctx->user_callbacks->get_public_key_for_id(soter_container_const_data(peer_id), soter_container_data_size(peer_id), sign_key, sizeof(sign_key), session_ctx->user_callbacks->user_data))
	{
		return THEMIS_SSESSION_GET_PUB_FOR_ID_CALLBACK_ERROR;
	}

	peer_sign_key = (const soter_container_hdr_t *)sign_key;

	if (memcmp(peer_sign_key->tag, EC_PUB_KEY_PREF, strlen(EC_PUB_KEY_PREF)))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	sign_key_length = ntohl(peer_sign_key->size);

	if (sizeof(soter_container_hdr_t) >= sign_key_length)
	{
		return THEMIS_INVALID_PARAMETER;
	}

	soter_status = soter_asym_ka_export_key(&(session_ctx->ecdh_ctx), ecdh_key, &ecdh_key_length, false);
	if (THEMIS_SUCCESS != soter_status)
	{
		return soter_status;
	}

	sign_data[0].data = (const uint8_t *)peer_ecdh_key;
	sign_data[0].length = peer_ecdh_key_length;

	sign_data[1].data = ecdh_key;
	sign_data[1].length = ecdh_key_length;

	sign_data[2].data = soter_container_const_data(peer_id);
	sign_data[2].length = soter_container_data_size(peer_id);

	sign_data[3].data = session_ctx->we.id;
	sign_data[3].length = session_ctx->we.id_length;

	res = verify_signature(peer_sign_key, sign_key_length, sign_data, 4, signature, signature_length);
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	res = secure_session_peer_init(&(session_ctx->peer), soter_container_const_data(peer_id), soter_container_data_size(peer_id), peer_ecdh_key, peer_ecdh_key_length, peer_sign_key, sign_key_length);
	if (THEMIS_SUCCESS != res)
	{
		goto err;
	}

	sign_data[0].data = ecdh_key;
	sign_data[0].length = ecdh_key_length;

	sign_data[1].data = (const uint8_t *)peer_ecdh_key;
	sign_data[1].length = peer_ecdh_key_length;

	sign_data[2].data = session_ctx->we.id;
	sign_data[2].length = session_ctx->we.id_length;

	sign_data[3].data = soter_container_const_data(peer_id);
	sign_data[3].length = soter_container_data_size(peer_id);

	res = soter_kdf(NULL, 0, SESSION_ID_GENERATION_LABEL, sign_data, 4, &(session_ctx->session_id), sizeof(session_ctx->session_id));
	if (THEMIS_SUCCESS != res)
	{
		goto err;
	}

	/* we will reuse sign_key buffer for shared secret computation */
	sign_key_length = sizeof(sign_key);
	res = soter_asym_ka_derive(&(session_ctx->ecdh_ctx), peer_ecdh_key, peer_ecdh_key_length, sign_key, &sign_key_length);
	if (THEMIS_SUCCESS != res)
	{
		goto err;
	}

	sign_data[0].data = (const uint8_t *)(&(session_ctx->session_id));
	sign_data[0].length = sizeof(session_ctx->session_id);

	res = soter_kdf(sign_key, sign_key_length, SESSION_MASTER_KEY_GENERATION_LABEL, sign_data, 1, session_ctx->session_master_key, sizeof(session_ctx->session_master_key));
	if (THEMIS_SUCCESS != res)
	{
		goto err;
	}

	/* restore sign data for signature computation */
	sign_data[0].data = ecdh_key;
	sign_data[0].length = ecdh_key_length;

	res = compute_signature(session_ctx->we.sign_key, session_ctx->we.sign_key_length, NULL, 0, NULL, &signature_length);
	if (THEMIS_BUFFER_TOO_SMALL != res)
	{
		goto err;
	}

	/* we will reuse sign_key_length for mac length retrieval */
	res = compute_mac(session_ctx->session_master_key, sizeof(session_ctx->session_master_key), NULL, 0, NULL, &sign_key_length);
	if (THEMIS_BUFFER_TOO_SMALL != res)
	{
		goto err;
	}

	length_to_send = sizeof(soter_container_hdr_t) + signature_length + sign_key_length;
	if ((NULL == output) || (*output_length < length_to_send))
	{
		*output_length = length_to_send;
		res = THEMIS_BUFFER_TOO_SMALL;
		goto err;
	}

	container = (soter_container_hdr_t *)data_to_send;

	/* Actual signature may be 1 or 2 bytes less than reported above because leading zeroes are stripped */
	length_to_send -= signature_length;

	res = compute_signature(session_ctx->we.sign_key, session_ctx->we.sign_key_length, sign_data, 4, soter_container_data(container), &signature_length);
	if (THEMIS_SUCCESS != res)
	{
		goto err;
	}

	length_to_send += signature_length;
	mac = soter_container_data(container) + signature_length;

	sign_data[0].data = (const uint8_t *)(session_ctx->peer.ecdh_key);
	sign_data[0].length = session_ctx->peer.ecdh_key_length;

	sign_data[1].data = (const uint8_t *)(&(session_ctx->session_id));
	sign_data[1].length = sizeof(session_ctx->session_id);

	res = compute_mac(session_ctx->session_master_key, sizeof(session_ctx->session_master_key), sign_data, 2, mac, &sign_key_length);
	if (THEMIS_SUCCESS != res)
	{
		goto err;
	}

	*output_length = length_to_send;

	memcpy(container->tag, THEMIS_SESSION_PROTO_TAG, SOTER_CONTAINER_TAG_LENGTH);
	soter_container_set_data_size(container, length_to_send - sizeof(soter_container_hdr_t));
	soter_update_container_checksum(container);

	/* "Client mode": waiting final confirmation from server */
	session_ctx->state_handler = secure_session_finish_client;

err:

	if (THEMIS_SUCCESS != res)
	{
		secure_session_peer_cleanup(&(session_ctx->peer));
	}

	return res;
}
Пример #28
0
static themis_status_t secure_session_accept(secure_session_t *session_ctx, const void *data, size_t data_length, void *output, size_t *output_length)
{
	const soter_container_hdr_t *proto_message = data;
	const soter_container_hdr_t *peer_id;

	const soter_container_hdr_t *peer_ecdh_key;
	size_t peer_ecdh_key_length;

	const uint8_t *signature;
	size_t signature_length;

	themis_status_t res = THEMIS_SUCCESS;
	soter_status_t soter_status;

	uint8_t sign_key[1024]; /* Should be enough for RSA 8192 which is 512 bytes */
	size_t sign_key_length;

	const soter_container_hdr_t *peer_sign_key;
	soter_kdf_context_buf_t sign_data[4];

	uint8_t *data_to_send = output;
	size_t length_to_send;

	size_t ecdh_key_length = 0;
	soter_container_hdr_t *container;

	if (data_length < sizeof(soter_container_hdr_t))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if (memcmp(proto_message->tag, THEMIS_SESSION_PROTO_TAG, SOTER_CONTAINER_TAG_LENGTH))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if (data_length < (soter_container_data_size(proto_message) + sizeof(soter_container_hdr_t)))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if (THEMIS_SUCCESS != soter_verify_container_checksum(proto_message))
	{

		return THEMIS_INVALID_PARAMETER;
	}

	peer_id = (const soter_container_hdr_t *)soter_container_const_data(proto_message);

	if (memcmp(peer_id->tag, THEMIS_SESSION_ID_TAG, SOTER_CONTAINER_TAG_LENGTH))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if (THEMIS_SUCCESS != soter_verify_container_checksum(peer_id))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	peer_ecdh_key = (const soter_container_hdr_t *)(soter_container_const_data(peer_id) + soter_container_data_size(peer_id));

	if (memcmp(peer_ecdh_key->tag, EC_PUB_KEY_PREF, strlen(EC_PUB_KEY_PREF)))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	peer_ecdh_key_length = soter_container_data_size(peer_ecdh_key) + sizeof(soter_container_hdr_t);

	signature = (const uint8_t *)peer_ecdh_key + peer_ecdh_key_length;
	signature_length = (const uint8_t *)data + soter_container_data_size(proto_message) + sizeof(soter_container_hdr_t) - signature;
	if (session_ctx->user_callbacks->get_public_key_for_id(soter_container_const_data(peer_id), soter_container_data_size(peer_id), sign_key, sizeof(sign_key), session_ctx->user_callbacks->user_data))
	{
		return THEMIS_SSESSION_GET_PUB_FOR_ID_CALLBACK_ERROR;
	}

	peer_sign_key = (const soter_container_hdr_t *)sign_key;

	if (memcmp(peer_sign_key->tag, EC_PUB_KEY_PREF, strlen(EC_PUB_KEY_PREF)))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	sign_key_length = ntohl(peer_sign_key->size);

	if (sizeof(soter_container_hdr_t) >= sign_key_length)
	{
		return THEMIS_INVALID_PARAMETER;
	}

	sign_data[0].data = (const uint8_t *)peer_ecdh_key;
	sign_data[0].length = peer_ecdh_key_length;

	res = verify_signature(peer_sign_key, sign_key_length, sign_data, 1, signature, signature_length);
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	/* Preparing to send response */
	res = compute_signature(session_ctx->we.sign_key, session_ctx->we.sign_key_length, NULL, 0, NULL, &signature_length);
	if (THEMIS_BUFFER_TOO_SMALL != res)
	{
		return res;
	}

	soter_status = soter_asym_ka_export_key(&(session_ctx->ecdh_ctx), NULL, &ecdh_key_length, false);
	if (THEMIS_BUFFER_TOO_SMALL != soter_status)
	{
		return soter_status;
	}

	length_to_send = 2 * sizeof(soter_container_hdr_t) + session_ctx->we.id_length + ecdh_key_length + signature_length;
	if ((NULL == output) || (*output_length < length_to_send))
	{
		*output_length = length_to_send;
		return THEMIS_BUFFER_TOO_SMALL;
	}

	res = secure_session_peer_init(&(session_ctx->peer), soter_container_const_data(peer_id), soter_container_data_size(peer_id), peer_ecdh_key, peer_ecdh_key_length, peer_sign_key, sign_key_length);
	if (THEMIS_SUCCESS != res)
	{
		goto err;
	}

	/* Storing ID in a container */
	container = (soter_container_hdr_t *)data_to_send + 1;

	memcpy(container->tag, THEMIS_SESSION_ID_TAG, SOTER_CONTAINER_TAG_LENGTH);
	soter_container_set_data_size(container, session_ctx->we.id_length);
	memcpy(soter_container_data(container), session_ctx->we.id, session_ctx->we.id_length);
	soter_update_container_checksum(container);

	/* Moving back to beginning of allocated buffer */
	container = (soter_container_hdr_t *)data_to_send;

	soter_status = soter_asym_ka_export_key(&(session_ctx->ecdh_ctx), data_to_send + (2 * sizeof(soter_container_hdr_t)) + session_ctx->we.id_length, &ecdh_key_length, false);
	if (THEMIS_SUCCESS != soter_status)
	{
		res = soter_status;
		goto err;
	}

	sign_data[0].data = data_to_send + (2 * sizeof(soter_container_hdr_t)) + session_ctx->we.id_length;
	sign_data[0].length = ecdh_key_length;

	sign_data[1].data = session_ctx->peer.ecdh_key;
	sign_data[1].length = session_ctx->peer.ecdh_key_length;

	sign_data[2].data = session_ctx->we.id;
	sign_data[2].length = session_ctx->we.id_length;

	sign_data[3].data = session_ctx->peer.id;
	sign_data[3].length = session_ctx->peer.id_length;

	/* Actual signature may be 1 or 2 bytes less than reported above because leading zeroes are stripped */
	length_to_send -= signature_length;

	res = compute_signature(session_ctx->we.sign_key, session_ctx->we.sign_key_length, sign_data, 4, data_to_send + (2 * sizeof(soter_container_hdr_t)) + session_ctx->we.id_length + ecdh_key_length, &signature_length);
	if (THEMIS_SUCCESS != res)
	{
		goto err;
	}

	length_to_send += signature_length;
	*output_length = length_to_send;

	memcpy(container->tag, THEMIS_SESSION_PROTO_TAG, SOTER_CONTAINER_TAG_LENGTH);
	soter_container_set_data_size(container, length_to_send - sizeof(soter_container_hdr_t));
	soter_update_container_checksum(container);

	/* "Server mode": waiting response from the client */
	session_ctx->state_handler = secure_session_finish_server;

	if (session_ctx->user_callbacks->state_changed)
	{
		session_ctx->user_callbacks->state_changed(STATE_NEGOTIATING, session_ctx->user_callbacks->user_data);
	}

err:

	if (THEMIS_SUCCESS != res)
	{
		secure_session_peer_cleanup(&(session_ctx->peer));
	}

	return res;
}
Пример #29
0
static int verify_private_key_ownership(struct openssl_session_auth_context* ctx, const char* private_key, int private_key_length, const char* client_certificate, int client_certificate_length) {
    char* x_buffer = NULL, *y_buffer = NULL, *concat_buffer = NULL;
    int ret, tmp;
    char* yx_signature = NULL, *xy_signature = NULL;
    int yx_signature_length, xy_signature_length;

    x_buffer = malloc(XY_RANDOM_DATA_LENGTH);
    y_buffer = malloc(XY_RANDOM_DATA_LENGTH);
    concat_buffer = malloc(2*XY_RANDOM_DATA_LENGTH);
    if ( !x_buffer || !y_buffer || !concat_buffer )
        goto failed;

    get_random_key(x_buffer, XY_RANDOM_DATA_LENGTH);

    if ( write_u32(ctx, XY_RANDOM_DATA_LENGTH) != 4 ) {
        printf("Failed to x buffer size\n");
        goto failed;
    }

    if ( openssl_local_write(ctx, x_buffer, XY_RANDOM_DATA_LENGTH) != XY_RANDOM_DATA_LENGTH ) {
        printf("Failed to send x buffer\n");
        goto failed;
    }

    if ( openssl_local_read(ctx, XY_RANDOM_DATA_LENGTH, y_buffer, &tmp) < XY_RANDOM_DATA_LENGTH ) {
        printf( "Failed to read y buffer\n");
        goto failed;
    }

    memcpy(concat_buffer,y_buffer, XY_RANDOM_DATA_LENGTH);
    memcpy(concat_buffer+XY_RANDOM_DATA_LENGTH,x_buffer, XY_RANDOM_DATA_LENGTH);

    yx_signature_length = read_u32(ctx);
    if ( yx_signature_length == READ_ERROR ) {
        printf("Failed to read yx signature length\n");
        goto failed;
    }

    yx_signature = malloc(yx_signature_length);
    if ( !yx_signature )
        goto failed;

    if ( openssl_local_read(ctx,  yx_signature_length, yx_signature, &tmp) < yx_signature_length ) {
        printf("Failed to read yx signature\n");
        goto failed;
    }

    ret = verify_signature(client_certificate, client_certificate_length, concat_buffer, 2*XY_RANDOM_DATA_LENGTH, yx_signature, yx_signature_length);
    if ( ret ) {
        printf("Failed to verify yx signature\n");
        goto failed;
    }

    memcpy(concat_buffer,x_buffer, XY_RANDOM_DATA_LENGTH);
    memcpy(concat_buffer+XY_RANDOM_DATA_LENGTH,y_buffer, XY_RANDOM_DATA_LENGTH);

    ret = sign_data(private_key, private_key_length, concat_buffer, 2*XY_RANDOM_DATA_LENGTH, &xy_signature, &xy_signature_length);
    if ( ret ) {
        printf("Failed to sign xy buffer\n");
        goto failed;
    }

    if ( write_u32(ctx, xy_signature_length) != 4) {
        printf("Failed to send xy signature length\n");
        goto failed;
    }

    /* Send server certificate */
    if ( openssl_local_write(ctx, xy_signature, xy_signature_length) != xy_signature_length ) {
        printf("Failed to send xy signature\n");
        goto failed;
    }

    goto done;
failed:
    ret = -1;
done:
    free(x_buffer);
    free(y_buffer);
    free(concat_buffer);
    free(xy_signature);
    free(yx_signature);
    return ret;
};
Пример #30
0
/**
 * Check the trust on one PKCS#7 SignedInfo block.
 */
int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
			     struct pkcs7_signed_info *sinfo,
			     struct key *trust_keyring)
{
	struct public_key_signature *sig = &sinfo->sig;
	struct x509_certificate *x509, *last = NULL, *p;
	struct key *key;
	bool trusted;
	int ret;

	kenter(",%u,", sinfo->index);

	for (x509 = sinfo->signer; x509; x509 = x509->signer) {
		if (x509->seen) {
			if (x509->verified) {
				trusted = x509->trusted;
				goto verified;
			}
			kleave(" = -ENOKEY [cached]");
			return -ENOKEY;
		}
		x509->seen = true;

		/* Look to see if this certificate is present in the trusted
		 * keys.
		 */
		key = pkcs7_request_asymmetric_key(
			trust_keyring,
			x509->subject, strlen(x509->subject),
			x509->fingerprint, strlen(x509->fingerprint));
		if (!IS_ERR(key))
			/* One of the X.509 certificates in the PKCS#7 message
			 * is apparently the same as one we already trust.
			 * Verify that the trusted variant can also validate
			 * the signature on the descendant.
			 */
			goto matched;
		if (key == ERR_PTR(-ENOMEM))
			return -ENOMEM;

		 /* Self-signed certificates form roots of their own, and if we
		  * don't know them, then we can't accept them.
		  */
		if (x509->next == x509) {
			kleave(" = -ENOKEY [unknown self-signed]");
			return -ENOKEY;
		}

		might_sleep();
		last = x509;
		sig = &last->sig;
	}

	/* No match - see if the root certificate has a signer amongst the
	 * trusted keys.
	 */
	if (!last || !last->issuer || !last->authority) {
		kleave(" = -ENOKEY [no backref]");
		return -ENOKEY;
	}

	key = pkcs7_request_asymmetric_key(
		trust_keyring,
		last->issuer, strlen(last->issuer),
		last->authority, strlen(last->authority));
	if (IS_ERR(key))
		return PTR_ERR(key) == -ENOMEM ? -ENOMEM : -ENOKEY;
	x509 = last;

matched:
	ret = verify_signature(key, sig);
	trusted = test_bit(KEY_FLAG_TRUSTED, &key->flags);
	key_put(key);
	if (ret < 0) {
		if (ret == -ENOMEM)
			return ret;
		kleave(" = -EKEYREJECTED [verify %d]", ret);
		return -EKEYREJECTED;
	}

verified:
	x509->verified = true;
	for (p = sinfo->signer; p != x509; p = p->signer) {
		p->verified = true;
		p->trusted = trusted;
	}
	sinfo->trusted = trusted;
	kleave(" = 0");
	return 0;
}