Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add p11proxy to OpenDNSSEC "test-rsaimport" tests #48

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 122 additions & 12 deletions p11mod/p11mod.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ type llSession struct {
session p11.Session
objects []p11.Object
objectsPending []p11.Object
signMechanism *pkcs11.Mechanism
signKeyIndex int
verifyMechanism *pkcs11.Mechanism
verifyKeyIndex int
}

type llBackend struct {
Expand Down Expand Up @@ -211,6 +215,10 @@ func (ll *llBackend) OpenSession(slotID uint, flags uint) (pkcs11.SessionHandle,
session: session,
objects: []p11.Object{},
objectsPending: []p11.Object{},
signMechanism: nil,
signKeyIndex: 0,
verifyMechanism: nil,
verifyKeyIndex: 0,
}

return sessionHandle, nil
Expand Down Expand Up @@ -521,15 +529,66 @@ func (ll *llBackend) DigestFinal(sh pkcs11.SessionHandle) ([]byte, error) {
}

func (ll *llBackend) SignInit(sh pkcs11.SessionHandle, m []*pkcs11.Mechanism, o pkcs11.ObjectHandle) error {
// TODO
log.Println("p11mod SignInit: not implemented")
return pkcs11.Error(pkcs11.CKR_FUNCTION_NOT_SUPPORTED)
session, err := ll.getSessionByHandle(sh)
if err != nil {
return err
}

// Handles are 1-indexed, while our slice is 0-indexed.
objectIndex := int(o-1)

if objectIndex < 0 || objectIndex >= len(session.objects) {
log.Printf("p11mod SignInit: key index invalid: requested %d, object count %d\n", objectIndex, len(session.objects))
return pkcs11.Error(pkcs11.CKR_KEY_HANDLE_INVALID)
}

if len(m) != 1 {
log.Println("p11mod SignInit: expected exactly one mechanism")
return pkcs11.Error(pkcs11.CKR_MECHANISM_INVALID)
}

if m[0] == nil {
log.Println("p11mod SignInit: nil mechanism")
return pkcs11.Error(pkcs11.CKR_MECHANISM_INVALID)
}

session.signMechanism = m[0]
session.signKeyIndex = objectIndex

return nil
}

func (ll *llBackend) Sign(sh pkcs11.SessionHandle, message []byte) ([]byte, error) {
// TODO
log.Println("p11mod Sign: not implemented")
return []byte{}, pkcs11.Error(pkcs11.CKR_FUNCTION_NOT_SUPPORTED)
session, err := ll.getSessionByHandle(sh)
if err != nil {
return nil, err
}

if session.signMechanism == nil {
return nil, pkcs11.Error(pkcs11.CKR_OPERATION_NOT_INITIALIZED)
}

// Inactivate the signature operation regardless of whether Sign errors.
defer func() {
session.signMechanism = nil
session.signKeyIndex = 0
}()

priv := p11.PrivateKey(session.objects[session.signKeyIndex])

signature, err := priv.Sign(*session.signMechanism, message)
if err != nil {
if err == pkcs11.Error(pkcs11.CKR_KEY_FUNCTION_NOT_PERMITTED) || err == pkcs11.Error(pkcs11.CKR_KEY_HANDLE_INVALID) || err == pkcs11.Error(pkcs11.CKR_KEY_SIZE_RANGE) || err == pkcs11.Error(pkcs11.CKR_KEY_TYPE_INCONSISTENT) || err == pkcs11.Error(pkcs11.CKR_MECHANISM_INVALID) || err == pkcs11.Error(pkcs11.CKR_MECHANISM_PARAM_INVALID) || err == pkcs11.Error(pkcs11.CKR_OPERATION_ACTIVE) || err == pkcs11.Error(pkcs11.CKR_PIN_EXPIRED) {
// priv.Sign() can relay these error values from SignInit, but
// PKCS#11 spec says Sign cannot return these. So we have to
// return a different error.
return nil, pkcs11.Error(pkcs11.CKR_FUNCTION_FAILED)
} else {
return nil, err
}
}

return signature, nil
}

func (ll *llBackend) SignUpdate(sh pkcs11.SessionHandle, message []byte) error {
Expand Down Expand Up @@ -557,15 +616,66 @@ func (ll *llBackend) SignRecover(sh pkcs11.SessionHandle, data []byte) ([]byte,
}

func (ll *llBackend) VerifyInit(sh pkcs11.SessionHandle, m []*pkcs11.Mechanism, key pkcs11.ObjectHandle) error {
// TODO
log.Println("p11mod VerifyInit: not implemented")
return pkcs11.Error(pkcs11.CKR_FUNCTION_NOT_SUPPORTED)
session, err := ll.getSessionByHandle(sh)
if err != nil {
return err
}

// Handles are 1-indexed, while our slice is 0-indexed.
objectIndex := int(key-1)

if objectIndex < 0 || objectIndex >= len(session.objects) {
log.Printf("p11mod VerifyInit: key index invalid: requested %d, object count %d\n", objectIndex, len(session.objects))
return pkcs11.Error(pkcs11.CKR_KEY_HANDLE_INVALID)
}

if len(m) != 1 {
log.Println("p11mod VerifyInit: expected exactly one mechanism")
return pkcs11.Error(pkcs11.CKR_MECHANISM_INVALID)
}

if m[0] == nil {
log.Println("p11mod VerifyInit: nil mechanism")
return pkcs11.Error(pkcs11.CKR_MECHANISM_INVALID)
}

session.verifyMechanism = m[0]
session.verifyKeyIndex = objectIndex

return nil
}

func (ll *llBackend) Verify(sh pkcs11.SessionHandle, data []byte, signature []byte) error {
// TODO
log.Println("p11mod Verify: not implemented")
return pkcs11.Error(pkcs11.CKR_FUNCTION_NOT_SUPPORTED)
session, err := ll.getSessionByHandle(sh)
if err != nil {
return err
}

if session.verifyMechanism == nil {
return pkcs11.Error(pkcs11.CKR_OPERATION_NOT_INITIALIZED)
}

// Inactivate the verification operation regardless of whether Verify errors.
defer func() {
session.verifyMechanism = nil
session.verifyKeyIndex = 0
}()

pub := p11.PublicKey(session.objects[session.verifyKeyIndex])

err = pub.Verify(*session.verifyMechanism, data, signature)
if err != nil {
if err == pkcs11.Error(pkcs11.CKR_KEY_FUNCTION_NOT_PERMITTED) || err == pkcs11.Error(pkcs11.CKR_KEY_HANDLE_INVALID) || err == pkcs11.Error(pkcs11.CKR_KEY_SIZE_RANGE) || err == pkcs11.Error(pkcs11.CKR_KEY_TYPE_INCONSISTENT) || err == pkcs11.Error(pkcs11.CKR_MECHANISM_INVALID) || err == pkcs11.Error(pkcs11.CKR_MECHANISM_PARAM_INVALID) || err == pkcs11.Error(pkcs11.CKR_OPERATION_ACTIVE) || err == pkcs11.Error(pkcs11.CKR_PIN_EXPIRED) || err == pkcs11.Error(pkcs11.CKR_USER_NOT_LOGGED_IN) {
// pub.Verify() can relay these error values from VerifyInit, but
// PKCS#11 spec says Verify cannot return these. So we have to
// return a different error.
return pkcs11.Error(pkcs11.CKR_FUNCTION_FAILED)
} else {
return err
}
}

return nil
}

func (ll *llBackend) VerifyUpdate(sh pkcs11.SessionHandle, part []byte) error {
Expand Down
15 changes: 14 additions & 1 deletion testdata/ci-opendnssec-tests.bash
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set -euo pipefail
shopt -s nullglob globstar

export PKCS11PROXY_CKBI_TARGET=/usr/lib64/pkcs11/libsofthsm2.so
export P11PROXY_CKBI_TARGET=$PKCS11PROXY_CKBI_TARGET

echo "===== init slot 0 ====="

Expand All @@ -17,10 +18,22 @@ echo "===== test-all slot 0 (via pkcs11proxy) ====="

pkcs11-testing --module ./libpkcs11proxy.so --slot "$SLOT_ID" --pin 1234 --test-all | tee test-all-pkcs11proxy.txt || true

echo "===== test-all slot 0 (diff) ====="
echo "===== test-all slot 0 (diff via pkcs11proxy) ====="

diff -I '^Modulus: [0-9A-F]\+$' test-all-default.txt test-all-pkcs11proxy.txt || testdata/dump-proxy-log-fail.bash

echo "===== test-rsaimport slot 0 (default) ====="

pkcs11-testing --module "$PKCS11PROXY_CKBI_TARGET" --slot "$SLOT_ID" --pin 1234 --test-rsaimport | tee test-rsaimport-default.txt || true

echo "===== test-rsaimport slot 0 (via p11proxy) ====="

pkcs11-testing --module ./libp11proxy.so --slot "$SLOT_ID" --pin 1234 --test-rsaimport | tee test-rsaimport-p11proxy.txt || true

echo "===== test-rsaimport slot 0 (diff via p11proxy) ====="

diff -I '^Modulus: [0-9A-F]\+$' test-rsaimport-default.txt test-rsaimport-p11proxy.txt || testdata/dump-proxy-log-fail.bash

echo "===== init slot 1 ====="

SLOT_ID=$(softhsm2-util --init-token --slot 1 --label softhsm --so-pin 1234 --pin 1234 | grep -oE '[^ ]+$')
Expand Down