コード例 #1
0
ファイル: process_keys.c プロジェクト: bluviolin/pgpanalysis
static void cleanup_siglist (struct sig **sig, char *keyid)
{
  struct sig **last = sig;
  struct sig *p, *q;
  
  for (p = *sig; p; p = q)
  {
    q = p->next;
    if (!strcmp (keyid, p->id) || check_sig_id (p->next, p->id))
    {
      *last = p->next;
      p->next = NULL;
      free_sig (&p);
    }
    else
      last = &p->next;
  }
}
コード例 #2
0
ファイル: process_keys.c プロジェクト: bluviolin/pgpanalysis
static void do_key (struct key *k)
{
  struct sig *interesting_signatures = NULL, *sigp;
  struct uid *uidp;
  
  if (k->rev)
    return;
  
  for (uidp = k->uids; uidp; uidp = uidp->next)
    if (DontRequireSelfSig || check_selfsig (uidp, k))
      join_siglists (&interesting_signatures, &uidp->sigs);
  
  cleanup_siglist (&interesting_signatures, k->id);
  if (interesting_signatures)
  { 
    printf ("p%s\n", k->id);
    for (sigp = interesting_signatures; sigp; sigp = sigp->next)
      printf ("s%s\n", sigp->id);
  }

  free_sig (&interesting_signatures);
  free_uid (&k->uids);
}
コード例 #3
0
ファイル: core.c プロジェクト: Yubico/libu2f-server-dpkg
/**
 * u2fs_registration_verify:
 * @ctx: a context handle, from u2fs_init().
 * @response: a U2F registration response message Base64 encoded.
 * @output: pointer to output structure containing the relevant data for a well formed request. Memory should be free'd.
 *
 * Get a U2F registration response and check its validity.
 *
 * Returns: On success %U2FS_OK (integer 0) is returned and @output is filled up with the user public key, the key handle and the attestation certificate. On errors
 * a #u2fs_rc error code.
 */
u2fs_rc u2fs_registration_verify(u2fs_ctx_t * ctx, const char *response,
                                 u2fs_reg_res_t ** output)
{
  char *registrationData;
  char *clientData;
  char *clientData_decoded;
  unsigned char *user_public_key;
  size_t keyHandle_len;
  char *keyHandle;
  char *origin;
  char *challenge;
  char buf[_B64_BUFSIZE];
  unsigned char c = 0;
  u2fs_X509_t *attestation_certificate;
  u2fs_ECDSA_t *signature;
  u2fs_EC_KEY_t *key;
  u2fs_rc rc;

  if (ctx == NULL || response == NULL || output == NULL)
    return U2FS_MEMORY_ERROR;

  key = NULL;
  clientData_decoded = NULL;
  challenge = NULL;
  origin = NULL;
  attestation_certificate = NULL;
  user_public_key = NULL;
  signature = NULL;
  registrationData = NULL;
  clientData = NULL;
  keyHandle = NULL;
  *output = NULL;

  rc = parse_registration_response(response, &registrationData,
                                   &clientData);
  if (rc != U2FS_OK)
    goto failure;

  if (debug) {
    fprintf(stderr, "registrationData: %s\n", registrationData);
    fprintf(stderr, "clientData: %s\n", clientData);
  }

  rc = parse_registrationData(registrationData, &user_public_key,
                              &keyHandle_len, &keyHandle,
                              &attestation_certificate, &signature);
  if (rc != U2FS_OK)
    goto failure;

  rc = extract_EC_KEY_from_X509(attestation_certificate, &key);

  if (rc != U2FS_OK)
    goto failure;

  //TODO Add certificate validation

  rc = decode_clientData(clientData, &clientData_decoded);

  if (rc != U2FS_OK)
    goto failure;

  rc = parse_clientData(clientData_decoded, &challenge, &origin);

  if (rc != U2FS_OK)
    goto failure;

  if (strcmp(ctx->challenge, challenge) != 0) {
    rc = U2FS_CHALLENGE_ERROR;
    goto failure;
  }

  if (strcmp(ctx->origin, origin) != 0) {
    rc = U2FS_ORIGIN_ERROR;
    goto failure;
  }

  struct sha256_state sha_ctx;
  char challenge_parameter[U2FS_HASH_LEN],
      application_parameter[U2FS_HASH_LEN];

  sha256_init(&sha_ctx);
  sha256_process(&sha_ctx, (unsigned char *) ctx->appid,
                 strlen(ctx->appid));
  sha256_done(&sha_ctx, (unsigned char *) application_parameter);

  sha256_init(&sha_ctx);
  sha256_process(&sha_ctx, (unsigned char *) clientData_decoded,
                 strlen(clientData_decoded));
  sha256_done(&sha_ctx, (unsigned char *) challenge_parameter);

  unsigned char dgst[U2FS_HASH_LEN];
  sha256_init(&sha_ctx);
  sha256_process(&sha_ctx, &c, 1);
  sha256_process(&sha_ctx, (unsigned char *) application_parameter,
                 U2FS_HASH_LEN);
  sha256_process(&sha_ctx, (unsigned char *) challenge_parameter,
                 U2FS_HASH_LEN);
  sha256_process(&sha_ctx, (unsigned char *) keyHandle, keyHandle_len);
  sha256_process(&sha_ctx, user_public_key, U2FS_PUBLIC_KEY_LEN);
  sha256_done(&sha_ctx, dgst);

  rc = verify_ECDSA(dgst, U2FS_HASH_LEN, signature, key);

  if (rc != U2FS_OK)
    goto failure;

  free_sig(signature);
  signature = NULL;

  *output = calloc(1, sizeof(**output));
  if (*output == NULL) {
    rc = U2FS_MEMORY_ERROR;
    goto failure;
  }

  rc = encode_b64u(keyHandle, keyHandle_len, buf);
  if (rc != U2FS_OK)
    goto failure;

  u2fs_EC_KEY_t *key_ptr;
  (*output)->keyHandle = strndup(buf, strlen(buf));

  rc = decode_user_key(user_public_key, &key_ptr);
  if (rc != U2FS_OK)
    goto failure;

  (*output)->attestation_certificate = dup_cert(attestation_certificate);

  rc = dump_user_key(key_ptr, &(*output)->publicKey);
  if (rc != U2FS_OK)
    goto failure;

  rc = dump_X509_cert(attestation_certificate, &(*output)->attestation_certificate_PEM);
  if (rc != U2FS_OK)
    goto failure;

  if ((*output)->keyHandle == NULL
      || (*output)->publicKey == NULL
      || (*output)->attestation_certificate == NULL) {
    rc = U2FS_MEMORY_ERROR;
    goto failure;
  }

  free_key(key);
  key = NULL;

  free_cert(attestation_certificate);
  attestation_certificate = NULL;

  free(clientData_decoded);
  clientData_decoded = NULL;

  free(challenge);
  challenge = NULL;

  free(origin);
  origin = NULL;

  free(user_public_key);
  user_public_key = NULL;

  free(registrationData);
  registrationData = NULL;

  free(clientData);
  clientData = NULL;

  free(keyHandle);
  keyHandle = NULL;

  return U2FS_OK;

failure:
  if (key) {
    free_key(key);
    key = NULL;
  }

  if (clientData_decoded) {
    free(clientData_decoded);
    clientData_decoded = NULL;
  }

  if (challenge) {
    free(challenge);
    challenge = NULL;
  }

  if (origin) {
    free(origin);
    origin = NULL;
  }

  if (attestation_certificate) {
    free_cert(attestation_certificate);
    attestation_certificate = NULL;
  }

  if (user_public_key) {
    free(user_public_key);
    user_public_key = NULL;
  }

  if (signature) {
    free_sig(signature);
    signature = NULL;
  }

  if (registrationData) {
    free(registrationData);
    registrationData = NULL;
  }

  if (clientData) {
    free(clientData);
    clientData = NULL;
  }

  if (keyHandle) {
    free(keyHandle);
    keyHandle = NULL;
  }

  return rc;
}
コード例 #4
0
ファイル: core.c プロジェクト: Yubico/libu2f-server-dpkg
/**
 * u2fs_authentication_verify:
 * @ctx: a context handle, from u2fs_init()
 * @response: pointer to output string with JSON data.
 * @output: pointer to output structure containing the relevant data for a well formed request. Memory should be free'd.
 *
 * Get a U2F authentication response and check its validity.
 *
 * Returns: On a successful verification %U2FS_OK (integer 0) is returned and @output is filled with the authentication result (same as the returned value), the counter received from the token and the user presence information. On errors
 * a #u2fs_rc error code is returned.
 */
u2fs_rc u2fs_authentication_verify(u2fs_ctx_t * ctx, const char *response,
                                   u2fs_auth_res_t ** output)
{
  char *signatureData;
  char *clientData;
  char *clientData_decoded;
  char *keyHandle;
  char *challenge;
  char *origin;
  uint8_t user_presence;
  uint32_t counter_num;
  uint32_t counter;
  u2fs_ECDSA_t *signature;
  u2fs_rc rc;

  if (ctx == NULL || response == NULL || output == NULL)
    return U2FS_MEMORY_ERROR;

  signatureData = NULL;
  clientData = NULL;
  clientData_decoded = NULL;
  keyHandle = NULL;
  challenge = NULL;
  origin = NULL;
  signature = NULL;
  *output = NULL;

  rc = parse_authentication_response(response, &signatureData,
                                     &clientData, &keyHandle);
  if (rc != U2FS_OK)
    goto failure;

  if (debug) {
    fprintf(stderr, "signatureData: %s\n", signatureData);
    fprintf(stderr, "clientData: %s\n", clientData);
    fprintf(stderr, "keyHandle: %s\n", keyHandle);
  }

  rc = parse_signatureData(signatureData, &user_presence,
                           &counter, &signature);
  if (rc != U2FS_OK)
    goto failure;

  rc = decode_clientData(clientData, &clientData_decoded);

  if (rc != U2FS_OK)
    goto failure;

  rc = parse_clientData(clientData_decoded, &challenge, &origin);

  if (rc != U2FS_OK)
    goto failure;

  if (strcmp(ctx->challenge, challenge) != 0) {
    rc = U2FS_CHALLENGE_ERROR;
    goto failure;
  }

  if (strcmp(ctx->origin, origin) != 0) {
    rc = U2FS_ORIGIN_ERROR;
    goto failure;
  }

  struct sha256_state sha_ctx;
  char challenge_parameter[U2FS_HASH_LEN],
      application_parameter[U2FS_HASH_LEN];

  sha256_init(&sha_ctx);
  sha256_process(&sha_ctx, (unsigned char *) ctx->appid,
                 strlen(ctx->appid));
  sha256_done(&sha_ctx, (unsigned char *) application_parameter);

  sha256_init(&sha_ctx);
  sha256_process(&sha_ctx, (unsigned char *) clientData_decoded,
                 strlen(clientData_decoded));
  sha256_done(&sha_ctx, (unsigned char *) challenge_parameter);

  unsigned char dgst[U2FS_HASH_LEN];
  sha256_init(&sha_ctx);
  sha256_process(&sha_ctx, (unsigned char *) application_parameter,
                 U2FS_HASH_LEN);
  sha256_process(&sha_ctx, (unsigned char *) &user_presence, 1);
  sha256_process(&sha_ctx, (unsigned char *) &counter, U2FS_COUNTER_LEN);
  sha256_process(&sha_ctx, (unsigned char *) challenge_parameter,
                 U2FS_HASH_LEN);
  sha256_done(&sha_ctx, dgst);

  rc = verify_ECDSA(dgst, U2FS_HASH_LEN, signature, ctx->key);

  if (rc != U2FS_OK)
    goto failure;

  free_sig(signature);
  signature = NULL;

  *output = calloc(1, sizeof(**output));
  if (*output == NULL) {
    rc = U2FS_MEMORY_ERROR;
    goto failure;
  }

  counter_num = 0;
  counter_num |= (counter & 0xFF000000) >> 24;
  counter_num |= (counter & 0x00FF0000) >> 8;
  counter_num |= (counter & 0x0000FF00) << 8;
  counter_num |= (counter & 0x000000FF) << 24;

  (*output)->verified = U2FS_OK;
  (*output)->user_presence = user_presence;
  (*output)->counter = counter_num;

  free(origin);
  origin = NULL;

  free(challenge);
  challenge = NULL;

  free(keyHandle);
  keyHandle = NULL;

  free(signatureData);
  signatureData = NULL;

  free(clientData);
  clientData = NULL;

  free(clientData_decoded);
  clientData_decoded = NULL;

  return U2FS_OK;

failure:
  if (clientData_decoded) {
    free(clientData_decoded);
    clientData_decoded = NULL;
  }

  if (challenge) {
    free(challenge);
    challenge = NULL;
  }

  if (origin) {
    free(origin);
    origin = NULL;
  }

  if (signature) {
    free_sig(signature);
    signature = NULL;
  }

  if (signatureData) {
    free(signatureData);
    signatureData = NULL;
  }

  if (clientData) {
    free(clientData);
    clientData = NULL;
  }

  if (keyHandle) {
    free(keyHandle);
    keyHandle = NULL;
  }

  return rc;
}