Update to newest imgcrypt, aufs and zfs
Older versions transitively dragged in k8s.io/kubernetes, the newer versions do not. Signed-off-by: Davanum Srinivas <davanum@gmail.com>
This commit is contained in:
2
vendor/github.com/stefanberger/go-pkcs11uri/.gitignore
generated
vendored
Normal file
2
vendor/github.com/stefanberger/go-pkcs11uri/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*~
|
||||
pkcs11uri
|
||||
25
vendor/github.com/stefanberger/go-pkcs11uri/.travis.yml
generated
vendored
Normal file
25
vendor/github.com/stefanberger/go-pkcs11uri/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
dist: bionic
|
||||
language: go
|
||||
|
||||
os:
|
||||
- linux
|
||||
|
||||
go:
|
||||
- "1.13.x"
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- softhsm2
|
||||
|
||||
install:
|
||||
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.30.0
|
||||
|
||||
script:
|
||||
- make
|
||||
- make check
|
||||
- make test
|
||||
177
vendor/github.com/stefanberger/go-pkcs11uri/LICENSE
generated
vendored
Normal file
177
vendor/github.com/stefanberger/go-pkcs11uri/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
https://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
28
vendor/github.com/stefanberger/go-pkcs11uri/Makefile
generated
vendored
Normal file
28
vendor/github.com/stefanberger/go-pkcs11uri/Makefile
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Copyright IBM Corporation, 2020
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
.PHONY: check build test
|
||||
|
||||
all: build
|
||||
|
||||
FORCE:
|
||||
|
||||
check:
|
||||
golangci-lint run
|
||||
|
||||
build:
|
||||
go build ./...
|
||||
|
||||
test:
|
||||
go test ./... -test.v
|
||||
102
vendor/github.com/stefanberger/go-pkcs11uri/README.md
generated
vendored
Normal file
102
vendor/github.com/stefanberger/go-pkcs11uri/README.md
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
# go-pkcs11uri
|
||||
|
||||
Welcome to the go-pkcs11uri library. The implementation follows [RFC 7512](https://tools.ietf.org/html/rfc7512) and this [errata](https://www.rfc-editor.org/errata/rfc7512).
|
||||
|
||||
# Exampe usage:
|
||||
|
||||
The following example builds on this library [here](https://github.com/miekg/pkcs11) and are using softhsm2 on Fedora.
|
||||
|
||||
## Example
|
||||
|
||||
This example program extending the one found [here](https://github.com/miekg/pkcs11/blob/master/README.md#examples):
|
||||
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/miekg/pkcs11"
|
||||
pkcs11uri "github.com/stefanberger/go-pkcs11uri"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
panic("Missing pkcs11 URI argument")
|
||||
}
|
||||
uristr := os.Args[1]
|
||||
|
||||
uri, err := pkcs11uri.New()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = uri.Parse(uristr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
module, err := uri.GetModule()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
slot, ok := uri.GetPathAttribute("slot-id", false)
|
||||
if !ok {
|
||||
panic("No slot-id in pkcs11 URI")
|
||||
}
|
||||
slotid, err := strconv.Atoi(slot)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pin, err := uri.GetPIN()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
p := pkcs11.New(module)
|
||||
err = p.Initialize()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
defer p.Destroy()
|
||||
defer p.Finalize()
|
||||
|
||||
session, err := p.OpenSession(uint(slotid), pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer p.CloseSession(session)
|
||||
|
||||
err = p.Login(session, pkcs11.CKU_USER, pin)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer p.Logout(session)
|
||||
|
||||
p.DigestInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_SHA_1, nil)})
|
||||
hash, err := p.Digest(session, []byte("this is a string"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, d := range hash {
|
||||
fmt.Printf("%x", d)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
```
|
||||
|
||||
## Exampe Usage
|
||||
|
||||
```
|
||||
$ sudo softhsm2-util --init-token --slot 1 --label test --pin 1234 --so-pin 1234
|
||||
The token has been initialized and is reassigned to slot 2053753261
|
||||
$ go build ./...
|
||||
$ sudo ./pkcs11-example 'pkcs11:slot-id=2053753261?module-path=/usr/lib64/pkcs11/libsofthsm2.so&pin-value=1234'
|
||||
517592df8fec3ad146a79a9af153db2a4d784ec5
|
||||
```
|
||||
|
||||
453
vendor/github.com/stefanberger/go-pkcs11uri/pkcs11uri.go
generated
vendored
Normal file
453
vendor/github.com/stefanberger/go-pkcs11uri/pkcs11uri.go
generated
vendored
Normal file
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
(c) Copyright IBM Corporation, 2020
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package pkcs11uri
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Pkcs11URI holds a pkcs11 URI object
|
||||
type Pkcs11URI struct {
|
||||
// path and query attributes may have custom attributes that either
|
||||
// have to be in the query or in the path part, so we use two maps
|
||||
pathAttributes map[string]string
|
||||
queryAttributes map[string]string
|
||||
// directories to search for pkcs11 modules
|
||||
moduleDirectories []string
|
||||
// file paths of allowed pkcs11 modules
|
||||
allowedModulePaths []string
|
||||
// whether any module is allowed to be loaded
|
||||
allowAnyModule bool
|
||||
// A map of environment variables needed by the pkcs11 module using this URI.
|
||||
// This map is not needed by this implementation but is there for convenience.
|
||||
env map[string]string
|
||||
}
|
||||
|
||||
// upper character hex digits needed for pct-encoding
|
||||
const hex = "0123456789ABCDEF"
|
||||
|
||||
// escapeAll pct-escapes all characters in the string
|
||||
func escapeAll(s string) string {
|
||||
res := make([]byte, len(s)*3)
|
||||
j := 0
|
||||
for i := 0; i < len(s); i++ {
|
||||
c := s[i]
|
||||
res[j] = '%'
|
||||
res[j+1] = hex[c>>4]
|
||||
res[j+2] = hex[c&0xf]
|
||||
j += 3
|
||||
}
|
||||
return string(res)
|
||||
}
|
||||
|
||||
// escape pct-escapes the path and query part of the pkcs11 URI following the different rules of the
|
||||
// path and query part as decribed in RFC 7512 sec. 2.3
|
||||
func escape(s string, isPath bool) string {
|
||||
res := make([]byte, len(s)*3)
|
||||
j := 0
|
||||
for i := 0; i < len(s); i++ {
|
||||
c := s[i]
|
||||
// unreserved per RFC 3986 sec. 2.3
|
||||
if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') {
|
||||
res[j] = c
|
||||
} else if isPath && c == '&' {
|
||||
res[j] = c
|
||||
} else if !isPath && (c == '/' || c == '?' || c == '|') {
|
||||
res[j] = c
|
||||
} else {
|
||||
switch c {
|
||||
case '-', '.', '_', '~': // unreserved per RFC 3986 sec. 2.3
|
||||
res[j] = c
|
||||
case ':', '[', ']', '@', '!', '$', '\'', '(', ')', '*', '+', ',', '=':
|
||||
res[j] = c
|
||||
default:
|
||||
res[j] = '%'
|
||||
res[j+1] = hex[c>>4]
|
||||
res[j+2] = hex[c&0xf]
|
||||
j += 2
|
||||
}
|
||||
}
|
||||
j++
|
||||
}
|
||||
return string(res[:j])
|
||||
}
|
||||
|
||||
// New creates a new Pkcs11URI object
|
||||
func New() *Pkcs11URI {
|
||||
return &Pkcs11URI{
|
||||
pathAttributes: make(map[string]string),
|
||||
queryAttributes: make(map[string]string),
|
||||
env: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
func (uri *Pkcs11URI) setAttribute(attrMap map[string]string, name, value string) error {
|
||||
v, err := url.PathUnescape(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
attrMap[name] = v
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetPathAttribute returns the value of a path attribute in unescaped form or
|
||||
// pct-encoded form
|
||||
func (uri *Pkcs11URI) GetPathAttribute(name string, pctencode bool) (string, bool) {
|
||||
v, ok := uri.pathAttributes[name]
|
||||
if ok && pctencode {
|
||||
v = escape(v, true)
|
||||
}
|
||||
return v, ok
|
||||
}
|
||||
|
||||
// SetPathAttribute sets the value for a path attribute; this function may return an error
|
||||
// if the given value cannot be pct-unescaped
|
||||
func (uri *Pkcs11URI) SetPathAttribute(name, value string) error {
|
||||
return uri.setAttribute(uri.pathAttributes, name, value)
|
||||
}
|
||||
|
||||
// AddPathAttribute adds a path attribute; it returns an error if an attribute with the same
|
||||
// name already existed or if the given value cannot be pct-unescaped
|
||||
func (uri *Pkcs11URI) AddPathAttribute(name, value string) error {
|
||||
if _, ok := uri.pathAttributes[name]; ok {
|
||||
return errors.New("duplicate path attribute")
|
||||
}
|
||||
return uri.SetPathAttribute(name, value)
|
||||
}
|
||||
|
||||
// RemovePathAttribute removes a path attribute
|
||||
func (uri *Pkcs11URI) RemovePathAttribute(name string) {
|
||||
delete(uri.pathAttributes, name)
|
||||
}
|
||||
|
||||
// AddEnv adds an environment variable for the pkcs11 module
|
||||
func (uri *Pkcs11URI) AddEnv(name, value string) {
|
||||
uri.env[name] = value
|
||||
}
|
||||
|
||||
// SetEnvMap sets the environment variables for the pkcs11 module
|
||||
func (uri *Pkcs11URI) SetEnvMap(env map[string]string) {
|
||||
uri.env = env
|
||||
}
|
||||
|
||||
// GetEnvMap returns the map of environment variables
|
||||
func (uri *Pkcs11URI) GetEnvMap() map[string]string {
|
||||
return uri.env
|
||||
}
|
||||
|
||||
// GetQueryAttribute returns the value of a query attribute in unescaped or
|
||||
// pct-encoded form
|
||||
func (uri *Pkcs11URI) GetQueryAttribute(name string, pctencode bool) (string, bool) {
|
||||
v, ok := uri.queryAttributes[name]
|
||||
if ok && pctencode {
|
||||
v = escape(v, false)
|
||||
}
|
||||
return v, ok
|
||||
}
|
||||
|
||||
// SetQueryAttribute sets the value for a query attribute; this function may return an error
|
||||
// if the given value cannot pct-unescaped
|
||||
func (uri *Pkcs11URI) SetQueryAttribute(name, value string) error {
|
||||
return uri.setAttribute(uri.queryAttributes, name, value)
|
||||
}
|
||||
|
||||
// AddQueryAttribute adds a query attribute; it returns an error if an attribute with the same
|
||||
// name already existed or if the given value cannot be pct-unescaped
|
||||
func (uri *Pkcs11URI) AddQueryAttribute(name, value string) error {
|
||||
if _, ok := uri.queryAttributes[name]; ok {
|
||||
return errors.New("duplicate query attribute")
|
||||
}
|
||||
return uri.SetQueryAttribute(name, value)
|
||||
}
|
||||
|
||||
// RemoveQueryAttribute removes a path attribute
|
||||
func (uri *Pkcs11URI) RemoveQueryAttribute(name string) {
|
||||
delete(uri.queryAttributes, name)
|
||||
}
|
||||
|
||||
// Validate validates a Pkcs11URI object's attributes following RFC 7512 rules and proper formatting of
|
||||
// their values
|
||||
func (uri *Pkcs11URI) Validate() error {
|
||||
/* RFC 7512: 2.3 */
|
||||
/* slot-id should be DIGIT, but we go for number */
|
||||
if v, ok := uri.pathAttributes["slot-id"]; ok {
|
||||
if _, err := strconv.Atoi(v); err != nil {
|
||||
return fmt.Errorf("slot-id must be a number: %s", v)
|
||||
}
|
||||
}
|
||||
|
||||
/* library-version should 1*DIGIT [ "." 1 *DIGIT ]; allow NUMBERS for DIGIT */
|
||||
if v, ok := uri.pathAttributes["library-version"]; ok {
|
||||
m, err := regexp.Match("^[0-9]+(\\.[0-9]+)?$", []byte(v))
|
||||
if err != nil || !m {
|
||||
return fmt.Errorf("Invalid format for library-version '%s'", v)
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := uri.pathAttributes["type"]; ok {
|
||||
m, err := regexp.Match("^(public|private|cert|secret-key}data)?$", []byte(v))
|
||||
if err != nil || !m {
|
||||
return fmt.Errorf("Invalid type '%s'", v)
|
||||
}
|
||||
}
|
||||
|
||||
/* RFC 7512: 2.4 */
|
||||
_, ok1 := uri.queryAttributes["pin-source"]
|
||||
_, ok2 := uri.queryAttributes["pin-value"]
|
||||
if ok1 && ok2 {
|
||||
return errors.New("URI must not contain pin-source and pin-value")
|
||||
}
|
||||
|
||||
if v, ok := uri.queryAttributes["module-path"]; ok {
|
||||
if !filepath.IsAbs(v) {
|
||||
return fmt.Errorf("path %s of module-name attribute must be absolute", v)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasPIN allows the user to check whether a PIN has been provided either by the pin-value or the pin-source
|
||||
// attributes. It should be called before GetPIN(), which may still fail getting the PIN from a file for example.
|
||||
func (uri *Pkcs11URI) HasPIN() bool {
|
||||
_, ok := uri.queryAttributes["pin-value"]
|
||||
if ok {
|
||||
return true
|
||||
}
|
||||
_, ok = uri.queryAttributes["pin-source"]
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetPIN gets the PIN from either the pin-value or pin-source attribute; a user may want to call HasPIN()
|
||||
// before calling this function to determine whether a PIN has been provided at all so that an error code
|
||||
// returned by this function indicates that the PIN value could not be retrieved.
|
||||
func (uri *Pkcs11URI) GetPIN() (string, error) {
|
||||
if v, ok := uri.queryAttributes["pin-value"]; ok {
|
||||
return v, nil
|
||||
}
|
||||
if v, ok := uri.queryAttributes["pin-source"]; ok {
|
||||
pinuri, err := url.ParseRequestURI(v)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Could not parse pin-source: %s ", err)
|
||||
}
|
||||
switch pinuri.Scheme {
|
||||
case "", "file":
|
||||
if !filepath.IsAbs(pinuri.Path) {
|
||||
return "", fmt.Errorf("PIN URI path '%s' is not absolute", pinuri.Path)
|
||||
}
|
||||
pin, err := ioutil.ReadFile(pinuri.Path)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Could not open PIN file: %s", err)
|
||||
}
|
||||
return string(pin), nil
|
||||
default:
|
||||
return "", fmt.Errorf("PIN URI scheme %s is not supported", pinuri.Scheme)
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("Neither pin-source nor pin-value are available")
|
||||
}
|
||||
|
||||
// Parse parses a pkcs11: URI string
|
||||
func (uri *Pkcs11URI) Parse(uristring string) error {
|
||||
if !strings.HasPrefix(uristring, "pkcs11:") {
|
||||
return errors.New("Malformed pkcs11 URI: missing pcks11: prefix")
|
||||
}
|
||||
|
||||
parts := strings.SplitN(uristring[7:], "?", 2)
|
||||
|
||||
uri.pathAttributes = make(map[string]string)
|
||||
uri.queryAttributes = make(map[string]string)
|
||||
|
||||
if len(parts[0]) > 0 {
|
||||
/* parse path part */
|
||||
for _, part := range strings.Split(parts[0], ";") {
|
||||
p := strings.SplitN(part, "=", 2)
|
||||
if len(p) != 2 {
|
||||
return errors.New("Malformed pkcs11 URI: malformed path attribute")
|
||||
}
|
||||
if err := uri.AddPathAttribute(p[0], p[1]); err != nil {
|
||||
return fmt.Errorf("Malformed pkcs11 URI: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(parts) == 2 {
|
||||
/* parse query part */
|
||||
for _, part := range strings.Split(parts[1], "&") {
|
||||
p := strings.SplitN(part, "=", 2)
|
||||
if len(p) != 2 {
|
||||
return errors.New("Malformed pkcs11 URI: malformed query attribute")
|
||||
}
|
||||
if err := uri.AddQueryAttribute(p[0], p[1]); err != nil {
|
||||
return fmt.Errorf("Malformed pkcs11 URI: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return uri.Validate()
|
||||
}
|
||||
|
||||
// formatAttribute formats attributes and escapes their values as needed
|
||||
func formatAttributes(attrMap map[string]string, ispath bool) string {
|
||||
res := ""
|
||||
for key, value := range attrMap {
|
||||
switch key {
|
||||
case "id":
|
||||
/* id is always pct-encoded */
|
||||
value = escapeAll(value)
|
||||
default:
|
||||
if ispath {
|
||||
value = escape(value, true)
|
||||
} else {
|
||||
value = escape(value, false)
|
||||
}
|
||||
}
|
||||
if len(res) > 0 {
|
||||
if ispath {
|
||||
res += ";"
|
||||
} else {
|
||||
res += "&"
|
||||
}
|
||||
}
|
||||
res += key + "=" + value
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Format formats a Pkcs11URI to it string representaion
|
||||
func (uri *Pkcs11URI) Format() (string, error) {
|
||||
if err := uri.Validate(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
result := "pkcs11:" + formatAttributes(uri.pathAttributes, true)
|
||||
if len(uri.queryAttributes) > 0 {
|
||||
result += "?" + formatAttributes(uri.queryAttributes, false)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SetModuleDirectories sets the search directories for pkcs11 modules
|
||||
func (uri *Pkcs11URI) SetModuleDirectories(moduleDirectories []string) {
|
||||
uri.moduleDirectories = moduleDirectories
|
||||
}
|
||||
|
||||
// GetModuleDirectories gets the search directories for pkcs11 modules
|
||||
func (uri *Pkcs11URI) GetModuleDirectories() []string {
|
||||
return uri.moduleDirectories
|
||||
}
|
||||
|
||||
// SetAllowedModulePaths sets allowed module paths to restrict access to modules.
|
||||
// Directory entries must end with a '/', all other ones are assumed to be file entries.
|
||||
// Allowed modules are filtered by string matching.
|
||||
func (uri *Pkcs11URI) SetAllowedModulePaths(allowedModulePaths []string) {
|
||||
uri.allowedModulePaths = allowedModulePaths
|
||||
}
|
||||
|
||||
// SetAllowAnyModule allows any module to be loaded; by default this is not allowed
|
||||
func (uri *Pkcs11URI) SetAllowAnyModule(allowAnyModule bool) {
|
||||
uri.allowAnyModule = allowAnyModule
|
||||
}
|
||||
|
||||
func (uri *Pkcs11URI) isAllowedPath(path string, allowedPaths []string) bool {
|
||||
if uri.allowAnyModule {
|
||||
return true
|
||||
}
|
||||
for _, allowedPath := range allowedPaths {
|
||||
if allowedPath == path {
|
||||
// exact filename match
|
||||
return true
|
||||
}
|
||||
if allowedPath[len(allowedPath)-1] == '/' && strings.HasPrefix(path, allowedPath) {
|
||||
// allowedPath no subdirectory is allowed
|
||||
idx := strings.IndexRune(path[len(allowedPath):], os.PathSeparator)
|
||||
if idx < 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetModule returns the module to use or an error in case no module could be found.
|
||||
// First the module-path is checked for whether it holds an absolute that can be read
|
||||
// by the current user. If this is the case the module is returned. Otherwise either the module-path
|
||||
// is used or the user-provided module path is used to match a module containing what is set in the
|
||||
// attribute module-name.
|
||||
func (uri *Pkcs11URI) GetModule() (string, error) {
|
||||
var searchdirs []string
|
||||
v, ok := uri.queryAttributes["module-path"]
|
||||
|
||||
if ok {
|
||||
info, err := os.Stat(v)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("module-path '%s' is not accessible", v)
|
||||
}
|
||||
if err == nil && info.Mode().IsRegular() {
|
||||
// it's a file
|
||||
if uri.isAllowedPath(v, uri.allowedModulePaths) {
|
||||
return v, nil
|
||||
}
|
||||
return "", fmt.Errorf("module-path '%s' is not allowed by policy", v)
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return "", fmt.Errorf("module-path '%s' points to an invalid file type", v)
|
||||
}
|
||||
// v is a directory
|
||||
searchdirs = []string{v}
|
||||
} else {
|
||||
searchdirs = uri.GetModuleDirectories()
|
||||
}
|
||||
|
||||
moduleName, ok := uri.queryAttributes["module-name"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("module-name attribute is not set")
|
||||
}
|
||||
moduleName = strings.ToLower(moduleName)
|
||||
|
||||
for _, dir := range searchdirs {
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, file := range files {
|
||||
fileLower := strings.ToLower(file.Name())
|
||||
|
||||
i := strings.Index(fileLower, moduleName)
|
||||
if i < 0 {
|
||||
continue
|
||||
}
|
||||
// we require that the fileLower ends with moduleName or that
|
||||
// a suffix follows so that softhsm will not match libsofthsm2.so but only
|
||||
// libsofthsm.so
|
||||
if len(fileLower) == i+len(moduleName) || fileLower[i+len(moduleName)] == '.' {
|
||||
f := filepath.Join(dir, file.Name())
|
||||
if uri.isAllowedPath(f, uri.allowedModulePaths) {
|
||||
return f, nil
|
||||
}
|
||||
return "", fmt.Errorf("module '%s' is not allowed by policy", f)
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("No module could be found")
|
||||
}
|
||||
Reference in New Issue
Block a user