Skip to Main Content

Cloud Security, Observability and Administration

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

Issue with OCI Vault signatures and soft-protected RSA keys

James CollierNov 4 2024 — edited Nov 4 2024

I have been using software-protected RSA keys for testing and debugging in OCI Vault.

There seems to be a problem with SHA_256_RSA_PKCS1_V1_5 signatures generated from software-protected RSA keys when a DIGEST is provided, in that the signatures do not contain the expected ASN.1 DigestInfo wrapping as specified in RFC 2313 / 8017. (I tried providing the DigestInfo explicitly, but the /sign endpoint will only accept a raw 256-bit / 32-byte digest).

HSM-protected keys seem to work correctly, as do RAW (<245 byte) message signatures with software-protected keys.

To reproduce:

vault_digestinfo_issue_demo.bash:

#! /bin/bash 

echo "Signing 'Hello world' with Soft and HSM Keys:"

/usr/bin/env python << \\EOF

import json
import base64
import hashlib
import requests

from oci.config import from_file
from oci.signer import Signer

def get_auth_session(profile_name='DEFAULT'):
  #get config from file - ~/.oci/config
  config = from_file(profile_name=profile_name)
  auth = Signer(
    tenancy                   = config['tenancy'],
    user                      = config['user'],
    fingerprint               = config['fingerprint'],
    private_key_file_location = config['key_file'],
    pass_phrase               = config['pass_phrase']
    )
  session = requests.Session()
  session.auth=auth
  return session

def write_raw(data,filename):
  if isinstance(data, str):
    mode="w"
  else:
    mode="wb"
  file = open(filename, mode)
  file.write(data)
  file.close

def get_current_pubkey(s, key_id, vault_id, filename_prefix):
  mastkey_info_url          = mgmt_endpoint+"/20180608/keys/"+key_id
  mastkey_info_resp         = s.get(mastkey_info_url)
  mastkey_info              = mastkey_info_resp.json()
  current_key_version_id    = mastkey_info['currentKeyVersion']
  current_key_version_url   = mastkey_info_url+"/keyVersions/"+current_key_version_id
  current_key_version_resp  = s.get(current_key_version_url)
  current_key_version       = current_key_version_resp.json()
  pubkey                    = current_key_version['publicKey']
  write_raw(pubkey, filename_prefix+"-public-key.pem")

def vault_sign_digest(s, message, key_id, filename_prefix):
  msg_hash       = hashlib.sha256(message)
  msg_digest     = msg_hash.digest()
  write_raw(msg_digest, filename_prefix+"-digest.dat")
  msg_digest_b64 = base64.b64encode(msg_digest).decode('UTF-8')
  sign_req = {
    "keyId"            :  key_id,
    "message"          :  msg_digest_b64,
    "messageType"      : 'DIGEST',
    "signingAlgorithm" : 'SHA_256_RSA_PKCS1_V1_5'
    }
  sign_resp = s.post(sig_endpoint, json=sign_req)
  sigb64    = sign_resp.json()['signature']
  signature = base64.b64decode(sigb64)
  write_raw(signature, filename_prefix+"-signature.dat")

############ PYTHON MAIN ###############

crypto_endpoint = "https://<REDACTED 1>-crypto.kms.ap-sydney-1.oraclecloud.com"
mgmt_endpoint   = "https://<REDACTED 1>-management.kms.ap-sydney-1.oraclecloud.com"
sig_endpoint    = crypto_endpoint+"/20180608/sign"
vault_ocid      = "ocid1.vault.oc1.ap-sydney-1.<REDACTED 2>"
sftkey_ocid     =   "ocid1.key.oc1.ap-sydney-1.<REDACTED 2>"
hsmkey_ocid     =   "ocid1.key.oc1.ap-sydney-1.<REDACTED 2>"

message         = b"Hello world"

s=get_auth_session()

get_current_pubkey(s, sftkey_ocid, vault_ocid, "soft")
get_current_pubkey(s, hsmkey_ocid, vault_ocid, "hsm")

vault_sign_digest(s, message, sftkey_ocid, "soft")
vault_sign_digest(s, message, hsmkey_ocid, "hsm")
\EOF

############ BASH MAIN ###############

for prefix in hsm soft
do
  echo "Verifying $prefix key signature with openssl ..."
  openssl rsautl -verify -pubin -inkey $prefix-public-key.pem -in $prefix-signature.dat > $prefix-verified-signature.der
  echo
  echo "$prefix key original sha256 message digest:"
  od -t xC $prefix-digest.dat 
  echo
  echo "$prefix key signature verification output (digest should be at byte 20 following DigestInfo):"
  od -t xC $prefix-verified-signature.der
  echo
  echo "ASN.1 parsing $prefix key signature's DigestInfo structure:"
  if openssl asn1parse -in $prefix-verified-signature.der -inform der 
  then
    printf '\n DigestInfo OK \n\n'
  else
    printf '\n DigestInfo invalid or absent \n\n'
  fi
  echo "==========================================="
done

This produces:

$ ./vault_digestinfo_issue_demo.bash 
Signing 'Hello world' with Soft and HSM Keys:
Verifying hsm key signature with openssl ...

hsm key original sha256 message digest:
0000000 64 ec 88 ca 00 b2 68 e5 ba 1a 35 67 8a 1b 53 16
0000020 d2 12 f4 f3 66 b2 47 72 32 53 4a 8a ec a3 7f 3c
0000040

hsm key signature verification output (digest should be at byte 20 following DigestInfo):
0000000 30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05
0000020 00 04 20 64 ec 88 ca 00 b2 68 e5 ba 1a 35 67 8a
0000040 1b 53 16 d2 12 f4 f3 66 b2 47 72 32 53 4a 8a ec
0000060 a3 7f 3c 
0000063

ASN.1 parsing of hsm key signature's DigestInfo structure:
0:d=0 hl=2 l= 49 cons: SEQUENCE 
2:d=1 hl=2 l= 13 cons: SEQUENCE 
4:d=2 hl=2 l= 9 prim: OBJECT :sha256
15:d=2 hl=2 l= 0 prim: NULL 
17:d=1 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:64EC88CA00B268E5BA1A35678A1B5316D212F4F366B2477232534A8AECA37F3C

DigestInfo OK 

===========================================
Verifying soft key signature with openssl ...

soft key original sha256 message digest:
0000000 64 ec 88 ca 00 b2 68 e5 ba 1a 35 67 8a 1b 53 16
0000020 d2 12 f4 f3 66 b2 47 72 32 53 4a 8a ec a3 7f 3c
0000040

soft key signature verification output (digest should be at byte 20 following DigestInfo):
0000000 64 ec 88 ca 00 b2 68 e5 ba 1a 35 67 8a 1b 53 16
0000020 d2 12 f4 f3 66 b2 47 72 32 53 4a 8a ec a3 7f 3c
0000040

ASN.1 parsing soft key signature's DigestInfo structure:
Error in encoding
8414759936:error:0DFFF07B:asn1 encoding routines:CRYPTO_internal:header too long:/AppleInternal/Library/BuildRoots/91a344b1-f985-11ee-b563-fe8bc7981bff/Library/Caches/com.apple.xbs/Sources/libressl/libressl-3.3/crypto/asn1/asn1_lib.c:152:

DigestInfo invalid or absent 

===========================================

Is anyone else able to confirm this as a general problem?

Thanks!

Comments
Post Details
Added on Nov 4 2024
0 comments
71 views