Skip to content
This repository has been archived by the owner on Mar 21, 2020. It is now read-only.

Commit

Permalink
Create SKI tag matching X509 SubjectKeyIdentifier and replace DIGEST.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacob H. Haven committed Jun 29, 2015
1 parent f3bf328 commit dc80618
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 15 deletions.
1 change: 1 addition & 0 deletions kssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef struct {
// digest_public_key)
#define KSSL_TAG_SNI 0x02 // Server name (optional)
#define KSSL_TAG_CLIENT_IP 0x03 // Client IP (4 bytes for IPv4, 16 for IPv6)
#define KSSL_TAG_SKI 0x04 // Public key SKI
#define KSSL_TAG_OPCODE 0x11 // Requested operation (one of KSSL_OP_*)
#define KSSL_TAG_PAYLOAD 0x12 // Payload

Expand Down
10 changes: 6 additions & 4 deletions kssl_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,15 @@ kssl_error_code kssl_operate(kssl_header *header,
int max_payload_size;
int key_id;

if (request.is_digest_set == 0) {
if (request.is_ski_set) {
// Identify private key from request ski
key_id = find_private_key(privates, request.ski, NULL);
} else if (request.is_digest_set) {
key_id = find_private_key(privates, NULL, request.digest);
} else {
err = KSSL_ERROR_FORMAT;
break;
}

// Identify private key from request digest
key_id = find_private_key(privates, request.digest);
if (key_id < 0) {
err = KSSL_ERROR_KEY_NOT_FOUND;
break;
Expand Down
17 changes: 17 additions & 0 deletions kssl_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ kssl_error_code flatten_operation(kssl_header *header,
if (operation->is_payload_set) {
local_req_len += KSSL_ITEM_HEADER_SIZE + operation->payload_len;
}
if (operation->is_ski_set) {
local_req_len += KSSL_ITEM_HEADER_SIZE + KSSL_SKI_SIZE;
}
if (operation->is_digest_set) {
local_req_len += KSSL_ITEM_HEADER_SIZE + KSSL_DIGEST_SIZE;
}
Expand Down Expand Up @@ -304,6 +307,10 @@ kssl_error_code flatten_operation(kssl_header *header,
flatten_item(KSSL_TAG_PAYLOAD, operation->payload, operation->payload_len,
local_req, &offset);
}
if (operation->is_ski_set) {
flatten_item(KSSL_TAG_SKI, operation->ski, KSSL_SKI_SIZE,
local_req, &offset);
}
if (operation->is_digest_set) {
flatten_item(KSSL_TAG_DIGEST, operation->digest, KSSL_DIGEST_SIZE,
local_req, &offset);
Expand All @@ -326,6 +333,8 @@ void zero_operation(kssl_operation *operation) {
if (operation != NULL) {
operation->is_opcode_set = 0;
operation->opcode = 0;
operation->is_ski_set = 0;
operation->ski = NULL;
operation->is_digest_set = 0;
operation->digest = NULL;
operation->is_payload_set = 0;
Expand Down Expand Up @@ -374,6 +383,14 @@ kssl_error_code parse_message_payload(BYTE *payload, //
operation->is_opcode_set = 1;
break;
}
case KSSL_TAG_SKI:
{
// Skip over malformed tags
if (temp_item.length != KSSL_SKI_SIZE) continue;
operation->ski = temp_item.data;
operation->is_ski_set = 1;
break;
}
case KSSL_TAG_DIGEST:
{
// Skip over malformed tags
Expand Down
3 changes: 3 additions & 0 deletions kssl_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@
// Helper macros for known sizes of V1 items
#define KSSL_OPCODE_ITEM_SIZE (KSSL_ITEM_HEADER_SIZE + 1)
#define KSSL_ERROR_ITEM_SIZE (KSSL_ITEM_HEADER_SIZE + 1)
#define KSSL_SKI_SIZE 20
#define KSSL_DIGEST_SIZE 32

// Structure containing request information parsed from payload
typedef struct kssl_operation_ {
int is_opcode_set;
BYTE opcode;
int is_ski_set;
BYTE *ski;
int is_digest_set;
BYTE *digest;
int is_payload_set;
Expand Down
48 changes: 40 additions & 8 deletions kssl_private_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,24 @@
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/conf.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/x509.h>
#include <openssl/sha.h>

#include "kssl.h"
#include "kssl_helpers.h"
#include "kssl_log.h"

#include "kssl_private_key.h"
#include "kssl_core.h"

extern int silent;

// private_key is an EVP key with its associate SHA256 digest
// private_key is an EVP key with its associate SHA256 ski
typedef struct {
BYTE ski[KSSL_SKI_SIZE]; // SKI of public key.
BYTE digest[KSSL_DIGEST_SIZE]; // SHA256 digest of key.
EVP_PKEY *key; // EVP private key
EVP_PKEY *key; // EVP private key
} private_key;

// pk_list_ is an array of private_key structures
Expand Down Expand Up @@ -67,6 +68,21 @@ static int opcode_to_digest_nid(BYTE opcode) {
return 0;
}

// get_ski: calculates the Subject Key Identifier of a given public key.
// SKI must be initialized with at least 20 bytes of space and is used to
// return a SHA-1 ski.
static int get_ski(EVP_PKEY *key, BYTE *ski) {
X509_PUBKEY *xpk;
if(!X509_PUBKEY_set(&xpk, key) ||
!xpk ||
!xpk->public_key ||
!xpk->public_key->data) {
return 1;
}
SHA1(xpk->public_key->data, xpk->public_key->length, ski);
return 0;
}

// digest_public_key: calculates the SHA256 digest of the
// hexadecimal representation of the EVP public key. For an RSA key
// this is based on public modulus. For an EC key, this is based on
Expand Down Expand Up @@ -158,7 +174,13 @@ static kssl_error_code add_key_from_bio(BIO *key_bp, // BIO Key value in PEM
return KSSL_ERROR_INTERNAL;
}
}

list->privates[list->current].key = local_key;

if(get_ski(local_key, list->privates[list->current].ski) != 0) {
return KSSL_ERROR_INTERNAL;
}

if(digest_public_key(local_key, list->privates[list->current].digest) != 0) {
return KSSL_ERROR_INTERNAL;
}
Expand Down Expand Up @@ -273,17 +295,27 @@ kssl_error_code add_key_from_buffer(const char *key, // Key value in PEM format
return KSSL_ERROR_NONE;
}

// find_private_key: returns an id for the key that matches the digest.
// find_private_key: returns an id for the key that matches the ski.
// In this implementation key id is the index into the list of privates.
// A negative return indicates an error.
int find_private_key(pk_list list, // Array of private keys from new_pk_list
BYTE *ski, // SKI of key searched for (see get_ski)
BYTE *digest) { // Digest of key searched for (see digest_public_key)
int j;
int found = 0;
for (j = 0; j < list->current; j++) {
if (constant_time_eq(list->privates[j].digest, digest, KSSL_DIGEST_SIZE) == 1) {
found = 1;
break;
if (ski) {
if (constant_time_eq(list->privates[j].ski, ski, KSSL_SKI_SIZE) == 1) {
found = 1;
break;
}
}

if (digest) {
if (constant_time_eq(list->privates[j].digest, digest, KSSL_DIGEST_SIZE) == 1) {
found = 1;
break;
}
}
}

Expand Down
7 changes: 4 additions & 3 deletions kssl_private_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ kssl_error_code add_key_from_buffer(
int key_len, // Length of key in bytes
pk_list list); // Array of private keys

// find_private_key: returns an id for the key that matches the digest.
// find_private_key: returns an id for the key that matches the ski.
// In this implementation key id is the index into the list of privates.
// A negative return indicates an error.
int find_private_key(
pk_list list, // Array of private keys from new_pk_list
BYTE *digest); // Digest of key to search for (see digest_public_key)
pk_list list, // Array of private keys from new_pk_list
BYTE *ski, // SKI of key searched for (see get_ski)
BYTE *digest); // Digest of key searched for (see digest_public_key)

// private_key_operation: perform a private key operation
kssl_error_code private_key_operation(
Expand Down

0 comments on commit dc80618

Please sign in to comment.