miekg / pkcs11 Goto Github PK
View Code? Open in Web Editor NEWpkcs11 wrapper for Go
License: BSD 3-Clause "New" or "Revised" License
pkcs11 wrapper for Go
License: BSD 3-Clause "New" or "Revised" License
I believe this relates to the following line:
Line 1332 in 6120d95
I encountered this whilst using ThalesIgnite/crypto11 to add PKCS#11 support to cloudflare/cfssl. This seems to only occur on ARM, as the trace comes from running it on a raspberry pi, and I have been able to get it to work successfully on x86.
Full trace can be found at https://pastebin.com/au1ieLbp
Hi Miek, I am in process of removing softhsm(1) from Debian, and your package is one of the two that depends on the old one. Could you please switch to libsofthsm2.so and fix this?
go test -v github.com/miekg/pkcs11
=== RUN TestSetenv
--- PASS: TestSetenv (0.00s)
=== RUN TestInitialize
--- FAIL: TestInitialize (0.00s)
pkcs11_test.go:32: loading /usr/lib/softhsm/libsofthsm2.so
pkcs11_test.go:77: init error pkcs11: 0x5: CKR_GENERAL_ERROR
=== RUN TestGetInfo
--- FAIL: TestGetInfo (0.00s)
pkcs11_test.go:32: loading /usr/lib/softhsm/libsofthsm2.so
pkcs11_test.go:58: init error pkcs11: 0x5: CKR_GENERAL_ERROR
=== RUN TestFindObject
--- FAIL: TestFindObject (0.00s)
pkcs11_test.go:32: loading /usr/lib/softhsm/libsofthsm2.so
pkcs11_test.go:58: init error pkcs11: 0x5: CKR_GENERAL_ERROR
=== RUN TestGetAttributeValue
--- FAIL: TestGetAttributeValue (0.00s)
pkcs11_test.go:32: loading /usr/lib/softhsm/libsofthsm2.so
pkcs11_test.go:58: init error pkcs11: 0x5: CKR_GENERAL_ERROR
=== RUN TestDigest
--- FAIL: TestDigest (0.00s)
pkcs11_test.go:32: loading /usr/lib/softhsm/libsofthsm2.so
pkcs11_test.go:58: init error pkcs11: 0x5: CKR_GENERAL_ERROR
=== RUN TestDigestUpdate
--- FAIL: TestDigestUpdate (0.00s)
pkcs11_test.go:32: loading /usr/lib/softhsm/libsofthsm2.so
pkcs11_test.go:58: init error pkcs11: 0x5: CKR_GENERAL_ERROR
=== RUN TestGenerateKeyPair
--- FAIL: TestGenerateKeyPair (0.00s)
pkcs11_test.go:32: loading /usr/lib/softhsm/libsofthsm2.so
pkcs11_test.go:58: init error pkcs11: 0x5: CKR_GENERAL_ERROR
=== RUN TestSign
--- FAIL: TestSign (0.00s)
pkcs11_test.go:32: loading /usr/lib/softhsm/libsofthsm2.so
pkcs11_test.go:58: init error pkcs11: 0x5: CKR_GENERAL_ERROR
=== RUN ExampleSign
--- FAIL: ExampleSign (0.00s)
panic: runtime error: index out of range [recovered]
panic: runtime error: index out of range
goroutine 1 [running]:
panic(0x5a2e80, 0xc820014060)
/usr/lib/go/src/runtime/panic.go:464 +0x3e6
testing.runExample.func2(0xece97a492, 0xc81da65164, 0x8cd7a0, 0xc820076080, 0xc820076008, 0xc8200884e0, 0x5dbf60, 0xb, 0x629800, 0x5dc4b0, ...)
/usr/lib/go/src/testing/example.go:93 +0x3fa
panic(0x5a2e80, 0xc820014060)
/usr/lib/go/src/runtime/panic.go:426 +0x4e9
github.com/miekg/pkcs11.ExampleSign()
/tmp/build-area/golang-github-miekg-pkcs11-0.0~git20160222.0.df8ae6ca/obj-x86_64-linux-gnu/src/github.com/miekg/pkcs11/pkcs11_test.go:292 +0x1149
testing.runExample(0x5dbf60, 0xb, 0x629800, 0x5dc4b0, 0xa, 0x0)
/usr/lib/go/src/testing/example.go:98 +0x3d7
testing.RunExamples(0x629868, 0x8b7da0, 0x1, 0x1, 0x1)
/usr/lib/go/src/testing/example.go:36 +0x314
testing.(*M).Run(0xc82004bef8, 0xc82004be88)
/usr/lib/go/src/testing/testing.go:516 +0xbd
main.main()
github.com/miekg/pkcs11/_test/_testmain.go:72 +0x117
exit status 2
FAIL github.com/miekg/pkcs11 0.009s
Copyright header is missing for vendor.go file. All the other files have it.
It appears that it does, based on this comment: https://github.com/miekg/pkcs11/blame/287d9350987cc9334667882061e202e96cdfb4d0/params.go#L29
Current:
session, _ := p.OpenSession(slots[0], pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
defer p.CloseSession(session)
Target:
session, _ := slot.OpenSession(pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
defer session.Close()
I saw #72 referenced a SafeNet/Gemalto HSM and tried to use this to interface with one and only seemed to be able to interface with a SoftHSM despite thinking that I initializing with the right .so file. Does anyone have any experience with this?
I use your library in another project and I am very interested on how to (cross) compile correctly for win32
When calling GetMechanismList on a Gemalto .NET Token the C function will return CKR_BUFFER_TOO_SMALL on the first call (with the Mechanism List being a NULL Pointer).
This is apparently in violation of the specs which states that the function should return CKR_OK.
However i don't see much harm done to extend the error check in pkcs11.go:118 to be:
if (e != CKR_OK && e != CKR_BUFFER_TOO_SMALL) {
return e;
}
With this addition i was able to successfully query the supported mechanisms from the Gemalto card.
Maybe someone can cross-check how this is handled in other pkcs11 implementations? The Token works fine in other applications.
I notice in pkcs11.go, around line 1399, the VerifyRecover is invoking C.C.DecryptVerifyUpdate .
Is this correct ?
// VerifyRecover verifies a signature in a single-part
// operation, where the data is recovered from the signature.
func (c *Ctx) VerifyRecover(sh SessionHandle, signature []byte) ([]byte, error) {
var (
data C.CK_BYTE_PTR
datalen C.CK_ULONG
)
e := C.DecryptVerifyUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&signature[0])), C.CK_ULONG(len(signature)), &data, &datalen)
if toError(e) != nil {
return nil, toError(e)
}
h := C.GoBytes(unsafe.Pointer(data), C.int(datalen))
C.free(unsafe.Pointer(data))
return h, nil
}
go build vendor/github.com/miekg/pkcs11: invalid flag in #cgo LDFLAGS: -I/usr/local/share/libtool
Dump from the Golang ML:
On Friday, February 13, 2015 at 10:53:30 AM UTC-5, Miek Gieben wrote:
[ Quoting <[email protected] javascript:> in "Re: [go-nuts] PKCS#11
and creating ..." ]Thanks for the tip.
I upgraded to SoftHSM2b2. This allowed me to create the AES key.
However, I was unable to call encrypt.
err = p.EncryptInit(session,
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_CBC, nil)},
aesKey)
if err != nil {
panic(fmt.Sprintf("EncryptInit() failed %s\n", err))
}It appears that the mechanism requires extra attributes,
See the AES example here:
You make a comment in the code when creating the mechanism.
// TODO(miek): Not seen anything as elaborate as Attributes, so for know
do
nothing.I managed to get a working example of RSA encryption using a public and
private key pair, based off of the IBM documentation.Thanks for your help and for publishing the pkcs11 code. Very useful!
Thanks. Could you file a bug for the above?
I'm not sure if it's related, but I had a very similar issue when trying
this with the python PKCS11 library: PyKCS11. The solution to my problem
was that CKA_ID was not a specified attribute, and appeared to be required
when CKA_TOKEN=True. This is presumably because making it a TOKEN object
requires it to be stored persistently on the card, and thus it needs an ID.
Session keys do not require a CKA_ID. Hope that helps:
http://stackoverflow.com/questions/30106966/smartcard-pkcs11-aes-key-gen-failure
Hi all,
there is a problem when using the package as windows service. I get error 1053 upon starting the windows service. It should be mentioned that the sample code works perfectly when run as a standalone program, but when it is started as windows service (using github.com/kardianos/service) I get the error. It is really strange because after adding the following two lines to the code and compile the program I get the error upon windows service start.
p := pkcs11.New(CONST_PKCS11_DLL)
err := p.Initialize()
Any ideas would be appreciated.
Only a subset of the calloc
have a NULL check, like this:
*enc = calloc(*enclen, sizeof(CK_BYTE));
if (*enc == NULL) {
return CKR_HOST_MEMORY;
}
Since this package introduces a dependency on libtool, other packages which include this will fail to compile with the missing "ltdl.h" file error when not installed. It would be nice to:
Missing:
CKM_ECDSA_SHA224 = 0x00001043
CKM_ECDSA_SHA256 = 0x00001044
CKM_ECDSA_SHA384 = 0x00001045
CKM_ECDSA_SHA512 = 0x00001046
I notice that this package already includes some vendor-specific constants (from nCipher). Would a PR be accepted that adds vendor-specific constants from NSS?
FindObjects
takes a maximum number of results to return, and returns a bool
if there were more results, however there is no way to get the number of results that might have been returned had max
been larger without randomly trying increasing values for max
.
The easiest fix here would be to return the number of results instead of the "has more" flag, but that would obviously be a breaking API change for existing users.
Our implementation needs to use PublicKeyInfo. The current implementation of this library doesn't enable this attribute. Upon testing and inspection of the code it was found that the support for the attribute was missing primarily due to wrong type being set in the attribute constructor. The type is wrongly being set as CKA_OBJECT_ID instead of setting as CKA_PUBLIC_KEY_INFO.
A simple fix of assigning the right type in the constructor as below
fixed the issue. here is git diff P11Attributes.h
@@ -345,7 +345,7 @@ class P11AttrPublicKeyInfo : public P11Attribute
{
public:
// Constructor
P11AttrPublicKeyInfo(OSObject* inobject, CK_ULONG inchecks) : P11Attribute(inobject) { type = CKA_OBJECT_ID; checks = inchecks; }
P11AttrPublicKeyInfo(OSObject* inobject, CK_ULONG inchecks) : P11Attribute(inobject) { type = CKA_PUBLIC_KEY_INFO; checks = inchecks; }
With the fix we can now create and set pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_KEY_INFO, info) There are several attributes disabled in current implementation of PKCS11 Private and Public objects we plan to find and patch them as well eventually.
Wondering if there is interest to accept a pull request for the fix for CKA_PUBLIC_KEY_INFO or if this has been fixed by other means.
I got everything setup, but I can't get your Signing example (slightly modified with error printing), to work:
✗ go run hsmtest.go
pkcs11: 0xD1: CKR_TEMPLATE_INCONSISTENT
Code here: https://gist.github.com/diogomonica/89dd1e913c66421df284
This is running on a OS X 10.10.3. I can run the SHA1 example from the Readme (the softhsm seems to be working correctly)
Please consider assigning version numbers and tagging releases. Tags/releases
are useful for downstream package maintainers (in Debian and other distributions) to export source tarballs, automatically track new releases and to declare dependencies between packages. Read more in the Debian Upstream Guide.
Versioning provides additional benefits to encourage vendoring of a particular (e.g. latest stable) release contrary to random unreleased snapshots.
Thanks.
See also
Hi,
Sorry to bother... but can you maybe tag a release, then when we vendor into docker its prettier not based off a sha :)
thanks!
I am able to create a AES key but I cant encrypt...
err = p.EncryptInit(session,
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_CBC, nil)}, aesKey)
if err != nil {
panic(fmt.Sprintf("EncryptInit() failed %s\n", err))
}
It appears that the mechanism requires extra attributes,
See the AES example here:
http://www-01.ibm.com/support/knowledgecenter/linuxonibm/com.ibm.linux.z.lxce/lxce_linklib_crypto_samples.html
You make a comment in the code when creating the mechanism.
// TODO(miek): Not seen anything as elaborate as Attributes, so for know do
nothing.
Go 1.6 is changing its rules around passing Go-owned pointers to C. In particular, you may no longer pass Go pointers which contain Go pointers to C. This obviously poses a serious problem for e.g., cMechanismList
and cAttributeList
and other internal abstractions, where ~all the memory in a deeply-nested data structure is owned by Go.
Are there any plans to fix this package to comply with Go 1.6's pointer ownership rules?
Hi,
I use another pkcs11*.so and it works with example on the README.md.
How can I get objects attributes on the card (certificate holder name etc)?
I dont understand the FindObjects*() logic. I used like this:
template := []*pkcs11.Attribute{
//pkcs11.NewAttribute(pkcs11.CKA_SUBJECT, nil),
pkcs11.NewAttribute(pkcs11.CKA_LABEL, nil),
//pkcs11.NewAttribute(pkcs11.CKA_LABEL, ""), // and some alternatives
}
_ := p.FindObjectsInit(session, template)
objs, _, _ := p.FindObjects(session, 100)
_ = p.FindObjectsFinal(session) // found nothing
attr, _ := p.GetAttributeValue(session, objs[0], template)
//attr, _ := p.GetAttributeValue(session, pkcs11.ObjectHandle(1), template)
What is the easiest way (ie without getting rsa key etc)
Thanks.
const.go and friends were at one point generated with some shell hackery (see comments in that file). I think at the time I wrote that 'go generate' didn't exist; now that it does, these files should be generated from the pkcs11.h files.
In letsencrypt/boulder#795 and cloudflare/cfssl#322 we're trying to figure out the thread safety properties of the pkcs11 library. Is pkcs11 expected to work from multiple threads / goroutines? Are there any special considerations we need to take?
Thanks,
Jacob
Allocate at types.go:39 panics if and empty slice is passed, because it takes the pointer of obj[0]
panic: runtime error: index out of range
goroutine 1 [running]:
panic(0x46eb180, 0xc820014060)
/usr/local/go/src/runtime/panic.go:481 +0x3e6
path/vendor/github.com/miekg/pkcs11.(*arena).Allocate(0xc820122f70, 0x4bbabf8, 0x0, 0x0, 0x2, 0x2)
path/vendor/github.com/miekg/pkcs11/types.go:39 +0x244 path/vendor/github.com/miekg/pkcs11.cAttributeList(0xc82013c950, 0x2, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0)
path/vendor/github.com/miekg/pkcs11/types.go:210 +0x1b1
path/vendor/github.com/miekg/pkcs11.(*Ctx).FindObjectsInit(0xc820030280, 0x1, 0xc82013c950, 0x2, 0x2, 0x0, 0x0)
path/vendor/github.com/miekg/pkcs11/pkcs11.go:1078 +0x5c
Ran into this because softhsm doesn't add a CKA_ID by default, which if searched in turn returns an empty slice.
set up travis build and tests.
in types.go file:
type Mechanism struct {
Mechanism uint
Parameter []byte
}
in pkcs11t.h file:
typedef struct CK_ECDH1_DERIVE_PARAMS {
CK_EC_KDF_TYPE kdf;
CK_ULONG ulSharedDataLen;
CK_BYTE_PTR pSharedData;
CK_ULONG ulPublicDataLen;
CK_BYTE_PTR pPublicData;
} CK_ECDH1_DERIVE_PARAMS;
@miekg
how could I create an instance of CK_ECDH1_DERIVE_PARAMS struct and then assign it to Mechnism.Parameter ?
On Linux, I'm getting the following error when trying to build the master version with go1.9.4:
$ go install ./...
go build github.com/miekg/pkcs11: invalid flag in #cgo LDFLAGS: -Wl,--no-as-needed
On Mac OS, getting the error:
$ go install ./...
go build github.com/miekg/pkcs11: invalid flag in #cgo LDFLAGS: -I/usr/local/share/libtool
Same errors with go1.10rc2. This is likely be due to changes / security fixes in golang/go#23672
Using this code:
func findObject(p *Ctx, session SessionHandle, template
[]*(Attribute)) []ObjectHandle {
if err := p.FindObjectsInit(session, template); err != nil {
panic("FindObjectsInit")
}
obj, _, err := p.FindObjects(session, 1024)
if err != nil {
panic("FindObjects")
}
if err := p.FindObjectsFinal(session); err != nil {
panic("FindObjectsFinal")
}
if len(obj) > 0 {
fmt.Println("found!")
for _,o := range obj {
fmt.Println("Object = ",o)
}
fmt.Println()
}
return obj
}
successive calls to this function produce that the results
list is appended to the original one. For instance: I'm using it to
check first for valid keys and, giving that i'm testing my app, I'm
using it also for deleting the keys.
First call produce
Object = 89
Object = 90
Second call
Object = 89
Object = 90
Object = 89
Object = 90
We're seeing a panic from
Line 782 in eda1d77
when the library is inaccessible, e.g. if the user has no permissions on it. Unfortunately this is all the data I have, just that it's coming from this line and it's a SIGSEGV.
Hi there
I need to generate/store generated AES keys in an ePass2003. The hardware clearly supports AES. I implemented my code with SoftHSMv2 for generating an AES key and for storing an AES key, through the CreateObject function.
After I've tested everything with SoftHSM2, I started using the ePass2003. I used the exact same CreateObject and attributes but I get a: CKR_ATTRIBUTE_VALUE_INVALID error.
I then implemented AES key generation instead of the CreateObject function. I tested it with SoftHSM and it worked 100%. When I tested it with the ePass2003 I get a CKR_FUNCTION_NOT_SUPPORTED error.
Here is my code for the CreateObject function:
key := []byte("0123456789123456")
attr := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY),
pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_AES),
pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
pkcs11.NewAttribute(pkcs11.CKA_LABEL, "My AES KEY"),
pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true),
pkcs11.NewAttribute(pkcs11.CKA_VALUE, key),
pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false),
}
_, err = p.CreateObject(session, attr)
if err != nil {
panic(err)
}
And here is my code for the GenerateKey function:
attr := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY),
pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_AES),
pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true),
pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true),
pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),
pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true),
pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, false),
pkcs11.NewAttribute(pkcs11.CKA_VALUE_LEN, 16),
pkcs11.NewAttribute(pkcs11.CKA_LABEL, "My AES KEY"),
}
mech := []*pkcs11.Mechanism{
pkcs11.NewMechanism(pkcs11.CKM_AES_KEY_GEN, nil),
}
_, err = p.GenerateKey(session, mech, attr)
if err != nil {
panic(err)
}
Does the library support using AES on hardware keys? Any help would be greatly appreciated.
Please make it compatible with FreeBSD.
Just add to pkcs11.go:
#cgo freebsd CFLAGS: -I/usr/local/include/
#cgo freebsd LDFLAGS: -lltdl -L/usr/local/lib/
It worked for me
Thanks
As a user of the p11 package, I should Be Able To perform a WrapKey request So That I Can securely export keys from a module.
acceptance criteria
GIVEN session.go
WHEN I look at the Session interface
THEN I expect to see a WrapKey
method added.
GIVEN sessionImpl
WHEN I look at implemented methods
THEN I expect to find an implementation for WrapKey
type Mechanism struct {
Mechanism uint
Parameter []byte
}
typedef struct CK_KEY_DERIVATION_STRING_DATA {
CK_BYTE_PTR pData;
CK_ULONG ulLen;
} CK_KEY_DERIVATION_STRING_DATA;
In go1.6, how could I create an instance of CK_KEY_DERIVATION_STRING_DATA struct and then assign it to Mechnism.Parameter ?
In
Line 858 in c6d6ee8
CK_TOKEN_INFO
at https://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/errata01/os/pkcs11-base-v2.40-errata01-os-complete.html does not indicate that utcTime
is padded (although the other strings in that struct are indeed padded with spaces). I'm not an expert on pkcs11, so maybe I'm misreading the spec, but figured I'd file an issue here in case this is a bug.Is there support for the key derivation method CKM_CONCATENATE_BASE_AND_DATA? It requires the structure CK_KEY_DERIVATION_STRING_DATA be sent in as the Parameter to the Mechanism, which I don't see in the code. If I just pass the data in, arena.Allocate is just going to calloc the size of the byte array, but the pkcs11 API is expecting the byte array and a CK_ULONG.
When I run it naively, just passing the byte array as the Parameter in the mechanism, I get CKR_MECHANISM_INVALID.
If there's no support, I can either jury rig it in my code (not ideal) or implement it in your package and then do a pull request.
If there is support, great! How does it work?
Thanks for implementing this very useful package.
I am able to create pair of RSA keys, encrypt and decrypt using them however these keys are not persistent for some reason. Every invocation of my sample code generates a new set. I went through the sqlite db to find the keys but all the tables except for Token are empty. Does the session need to be initialized in a certain way for the keys to be stored? I am using softhsm for this test. Any ideas what might be going wrong?
These methods are defined by PKCS#11 to take a CK_MECHANISM_PTR
, but their Go method signatures take a []*Mechanism
. For clarity, I think they should take a single *Mechanism
or possibly Mechanism
.
func (c *Ctx) DecryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error
func (c *Ctx) DeriveKey(sh SessionHandle, m []*Mechanism, basekey ObjectHandle, a []*Attribute) (ObjectHandle, error)
func (c *Ctx) DigestInit(sh SessionHandle, m []*Mechanism) error
func (c *Ctx) EncryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error
func (c *Ctx) GenerateKey(sh SessionHandle, m []*Mechanism, temp []*Attribute) (ObjectHandle, error)
func (c *Ctx) GenerateKeyPair(sh SessionHandle, m []*Mechanism, public, private []*Attribute) (ObjectHandle, ObjectHandle, error)
func (c *Ctx) GetMechanismInfo(slotID uint, m []*Mechanism) (MechanismInfo, error)
func (c *Ctx) SignInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error
func (c *Ctx) SignRecoverInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error
func (c *Ctx) UnwrapKey(sh SessionHandle, m []*Mechanism, unwrappingkey ObjectHandle, wrappedkey []byte, a []*Attribute) (ObjectHandle, error)
func (c *Ctx) VerifyInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error
func (c *Ctx) VerifyRecoverInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error
func (c *Ctx) WrapKey(sh SessionHandle, m []*Mechanism, wrappingkey, key ObjectHandle) ([]byte, error)
I realize this is would be a breaking change, so feel free to say WONTFIX, but I wanted to point it out as a bit of a confusing thing in this package.
I couldn't get the right total slots number when I use CryptokiMPX with two different tokens such as ePass and eToken Pro, but when I wrote a simple C program and load the PKCS11 directly, it worked fine.
https://github.com/hajikhorasani/cryptokimpx
Golang newbie question: I can't figure out how to build (cross-compile) my signing-test-prog for Windows usage. I'm working in OsX and managed to get all done without any (bigger) problem .
This is ok :
iMac@pkcs11$ GOOS=darwin GOARCH=amd64 go build -o t5.osx test5.go
iMac@pkcs11$ ./t5.osx
..... etc ... works like charm .....
Cross-compiling Win .exe :
► iMac@pkcs11$ GOOS=windows GOARCH=amd64 go build -o t5.exe test5.go
# command-line-arguments
./test5.go:13:7: undefined: pkcs11.New
./test5.go:42:27: undefined: pkcs11.Attribute
./test5.go:81:25: undefined: pkcs11.Mechanism
and here's my code (at least beginning og code) :
package main
import (
"encoding/base64"
"fmt"
"github.com/miekg/pkcs11"
)
func main() {
// p := pkcs11.New("/usr/local/lib/softhsm/libsofthsm2.so")
p := pkcs11.New("./lib/libykcs11.dylib") // <-- line 13 !!!
p.Initialize()
defer p.Destroy()
defer p.Finalize()
slots, err := p.GetSlotList(true)
if err != nil {
fmt.Println(err)
}
.... etc .....
My HSM is Yubikey 4 (PIV) , and it is configured and works OK.
Any workaround for getting this cross-compile done with OsX. Tried also in Win10, but my toolchain there is lacking at least Libtool etc. Anyway, for me it is simplest to develop with osx and only cross-compile for Win10.
Thanks for advise. Sorry but I'm just learning Golang more serious, but have to solve this quickly.
I cannot for the life of me figure out what I am doing wrong. Code snippet incoming:
...
var P big.Int
var Q big.Int
var G big.Int
var Y big.Int
var Label string
setP := false
setQ := false
setG := false
setY := false
...
template = []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_DSA),
pkcs11.NewAttribute(pkcs11.CKA_PRIME, nil),
pkcs11.NewAttribute(pkcs11.CKA_SUBPRIME, nil),
pkcs11.NewAttribute(pkcs11.CKA_BASE, nil),
pkcs11.NewAttribute(pkcs11.CKA_VALUE, nil),
}
attr, err := p.GetAttributeValue(session, pub_obj, template)
if err != nil {
return err
}
for _, a := range attr {
//log.Printf("attr %d, type %d, valuelen %d", i, a.Type, len(a.Value))
if a.Type == pkcs11.CKA_LABEL {
Label = string(a.Value)
}
if a.Type == pkcs11.CKA_PRIME {
P.SetBytes(a.Value)
log.Printf("PRIME\n%s", hex.Dump(a.Value))
setP = true
}
if a.Type == pkcs11.CKA_SUBPRIME {
Q.SetBytes(a.Value)
log.Printf("SUBPRIME\n%s", hex.Dump(a.Value))
setQ = true
}
if a.Type == pkcs11.CKA_BASE {
G.SetBytes(a.Value)
log.Printf("BASE\n%s", hex.Dump(a.Value))
setG = true
}
if a.Type == pkcs11.CKA_VALUE {
Y.SetBytes(a.Value)
log.Printf("VALUE\n%s", hex.Dump(a.Value))
setY = true
}
}
if !setP || !setQ || !setG || !setY {
return fmt.Errorf("Issue getting public key from HSM")
}
var key = dsa.PublicKey{
Parameters: dsa.Parameters{
P: &P,
Q: &Q,
G: &G,
},
Y: &Y,
}
pemfile, err := os.Create(out_dir + "/" + Label + ".pem")
if err != nil {
return err
}
asn1Bytes, err := asn1.Marshal(key)
if err != nil {
return err
}
pemkey := &pem.Block{
Type: "PUBLIC KEY",
Bytes: asn1Bytes}
err = pem.Encode(pemfile, pemkey)
if err != nil {
return err
}
pemfile.Close()
...
The above snippet intends to export a DSA Public Key from a HSM (testing with SoftHSMv2) in PEM format so that at a later date it can be imported to be used with dsa.Verify()
from crypto/dsa
. My problem here is that either either the Public Key isn't being generated properly, or I am not parsing the DSA signature properly. I believe I am generating the Public Key properly, but I'm wondering if anyone can verify this is the case. I've noticed for example, that I am unable to use this public key in OpenSSL due to it being a different format.
There do not seem to be many examples of this on the internet (in this library or otherwise).
The bool on FindObjects which according to the comment indicates if the resultset is larger than max, always returns false. FindObjects comment.
The softHSMv1 findObjects implementation returns the number of results read until max. So it will never be larger than max.
The oasis docs specify the following
C_FindObjects continues a search for token and session objects that match a template, obtaining additional object handles. hSession is the session’s handle; phObject points to the location that receives the list (array) of additional object handles; ulMaxObjectCount is the maximum number of object handles to be returned; pulObjectCount points to the location that receives the actual number of object handles returned.
So it seems the softHSM implementation is correct.
Miek,
The library is not working with Cloud HSM when trying to invoke CKM_AES_GCM mechanism and keeps throwing CKR_MECHANISM_INVALID error.
Also the CKM_AES_GCM params struct does not exists within the library
https://www.cryptsoft.com/pkcs11doc/v230/structCK__GCM__PARAMS.html
Please let me know if you need more information.
In our application we are trying to use softhsm as our primary keystore to save PKI certs and Pvt and Public keys. Multiple applications will be using this softhsm keystore hosted on our infrastructure and each app initializes its own application specific token. So our softhsm should allow for initializing multiple tokens. We are currently using this pkc11 Go library to interface with softhsm. The problem I'm facing is for initToken there is no option in API to choose --free like we use in softhsm-util. The softhsm2-util --init-token --slot 0 --label xyz will only work if its the first slot being initialized with a token. Once there is a slot present, slot 0 is no longer accepted as a staging slot. I want to be able to create tokens via API and allow for multiple tokens to be initialized at different points of time. We did implement logic to find a Token which returns 0 or CKR_INVALID_SLOT_ID if token is not present, which is good, but at that point I don't have a way to create a token in a new slot. using the slotId 0 will not work if there is already atleast token present and I haven't been able to find an option to use --free as a part of API call. I basically want to be able to create a new token in any available slot.
After updating to macOS Sierra 10.12.4 (Xcode 8.3) programs that include the pkcs11 package get killed at startup. This includes programs (e.g., unit tests) that include the package in a dependency chain and do not use the pkcs11 functions directly.
Running one such program under gdb produced the following output:
Reading symbols from ./certs.bad...
warning: `/tmp/go-build198504308/crypto/x509/_obj/root_cgo_darwin.cgo2.o': can't open to read symbols: No such file or directory.warning: `/tmp/go-build198504308/net/_obj/_cgo_export.o': can't open to read symbols: No such file or directory.
warning: `/tmp/go-build198504308/net/_obj/cgo_resnew.cgo2.o': can't open to read symbols: No such file or directory.
warning: `/tmp/go-build198504308/net/_obj/cgo_unix.cgo2.o': can't open to read symbols: No such file or directory.
warning: `/tmp/go-build198504308/runtime/cgo/_obj/gcc_amd64.o': can't open to read symbols: No such file or directory.
warning: `/tmp/go-build198504308/runtime/cgo/_obj/gcc_context.o': can't open to read symbols: No such file or directory.
warning: `/tmp/go-build198504308/runtime/cgo/_obj/gcc_darwin_amd64.o': can't open to read symbols: No such file or directory.
warning: `/tmp/go-build198504308/runtime/cgo/_obj/gcc_libinit.o': can't open to read symbols: No such file or directory.
warning: `/tmp/go-build198504308/runtime/cgo/_obj/gcc_setenv.o': can't open to read symbols: No such file or directory.
warning: `/tmp/go-build198504308/runtime/cgo/_obj/gcc_util.o': can't open to read symbols: No such file or directory.
warning: `/var/folders/f0/1chs6k912_l0p5fzvx_n6zmm0000gn/T/go-build889960085/bb.commandscape.com/cs/global/vendor/github.com/miekg/pkcs11/_obj/_cgo_export.o': can't open to read symbols: No such file or directory.
warning: `/var/folders/f0/1chs6k912_l0p5fzvx_n6zmm0000gn/T/go-build889960085/bb.commandscape.com/cs/global/vendor/github.com/miekg/pkcs11/_obj/pkcs11.cgo2.o': can't open to read symbols: No such file or directory.
warning: `/var/folders/f0/1chs6k912_l0p5fzvx_n6zmm0000gn/T/go-build889960085/bb.commandscape.com/cs/global/vendor/github.com/miekg/pkcs11/_obj/types.cgo2.o': can't open to read symbols: No such file or directory.
warning: `/var/folders/f0/1chs6k912_l0p5fzvx_n6zmm0000gn/T/go-link-749695904/go.o': can't open to read symbols: No such file or directory.
done.
(gdb) run
Starting program: /Users/bepayne/src/bb.commandscape.com/cs/global/certs.bad
During startup program terminated with signal SIGKILL, Killed.
After removing the pkcs11 dependency, the same unit test under gdb produced:
Reading symbols from ./certs.good...done.
Loading Go Runtime support.
(gdb) run
Starting program: /Users/bepayne/src/bb.commandscape.com/cs/global/certs.good
[New Thread 0x1403 of process 7406]
warning: unhandled dyld version (15)
--- FAIL: TestPool (0.00s)
certs_test.go:37: Pool error: open testdata/self_signed.pem: no such file or directory
FAIL
[Inferior 1 (process 7406) exited with code 01]
It would be really useful if an example or just an implementation of the crypto.Signer interface was provided https://golang.org/pkg/crypto/#Signer
Plenty of other packages use it like ssh which would mean I can use PKCS#11 for my SSH code.
I couldn't figure it out myself at the moment.
Hi,
There is an example of signature but I feel that is not being tested.
Is there any special reason why there are no specific test cases for key generation, signature, wrap and unwrap?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.