summaryrefslogtreecommitdiffstats
path: root/crypto/pkcs11/common.go
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/pkcs11/common.go')
-rw-r--r--crypto/pkcs11/common.go134
1 files changed, 134 insertions, 0 deletions
diff --git a/crypto/pkcs11/common.go b/crypto/pkcs11/common.go
new file mode 100644
index 0000000..072d7fe
--- /dev/null
+++ b/crypto/pkcs11/common.go
@@ -0,0 +1,134 @@
+/*
+ Copyright The ocicrypt Authors.
+ 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 pkcs11
+
+import (
+ "fmt"
+
+ pkcs11uri "github.com/stefanberger/go-pkcs11uri"
+ "gopkg.in/yaml.v3"
+)
+
+// Pkcs11KeyFile describes the format of the pkcs11 (private) key file.
+// It also carries pkcs11 module related environment variables that are transferred to the
+// Pkcs11URI object and activated when the pkcs11 module is used.
+type Pkcs11KeyFile struct {
+ Pkcs11 struct {
+ Uri string `yaml:"uri"`
+ } `yaml:"pkcs11"`
+ Module struct {
+ Env map[string]string `yaml:"env,omitempty"`
+ } `yaml:"module"`
+}
+
+// Pkcs11KeyFileObject is a representation of the Pkcs11KeyFile with the pkcs11 URI as an object
+type Pkcs11KeyFileObject struct {
+ Uri *pkcs11uri.Pkcs11URI
+}
+
+// ParsePkcs11Uri parses a pkcs11 URI
+func ParsePkcs11Uri(uri string) (*pkcs11uri.Pkcs11URI, error) {
+ p11uri := pkcs11uri.New()
+ err := p11uri.Parse(uri)
+ if err != nil {
+ return nil, fmt.Errorf("Could not parse Pkcs11URI from file: %w", err)
+ }
+ return p11uri, err
+}
+
+// ParsePkcs11KeyFile parses a pkcs11 key file holding a pkcs11 URI describing a private key.
+// The file has the following yaml format:
+// pkcs11:
+// - uri : <pkcs11 uri>
+// An error is returned if the pkcs11 URI is malformed
+func ParsePkcs11KeyFile(yamlstr []byte) (*Pkcs11KeyFileObject, error) {
+ p11keyfile := Pkcs11KeyFile{}
+
+ err := yaml.Unmarshal(yamlstr, &p11keyfile)
+ if err != nil {
+ return nil, fmt.Errorf("Could not unmarshal pkcs11 keyfile: %w", err)
+ }
+
+ p11uri, err := ParsePkcs11Uri(p11keyfile.Pkcs11.Uri)
+ if err != nil {
+ return nil, err
+ }
+ p11uri.SetEnvMap(p11keyfile.Module.Env)
+
+ return &Pkcs11KeyFileObject{Uri: p11uri}, err
+}
+
+// IsPkcs11PrivateKey checks whether the given YAML represents a Pkcs11 private key
+func IsPkcs11PrivateKey(yamlstr []byte) bool {
+ _, err := ParsePkcs11KeyFile(yamlstr)
+ return err == nil
+}
+
+// IsPkcs11PublicKey checks whether the given YAML represents a Pkcs11 public key
+func IsPkcs11PublicKey(yamlstr []byte) bool {
+ _, err := ParsePkcs11KeyFile(yamlstr)
+ return err == nil
+}
+
+// Pkcs11Config describes the layout of a pkcs11 config file
+// The file has the following yaml format:
+// module-directories:
+// - /usr/lib64/pkcs11/
+// allowd-module-paths
+// - /usr/lib64/pkcs11/libsofthsm2.so
+type Pkcs11Config struct {
+ ModuleDirectories []string `yaml:"module-directories"`
+ AllowedModulePaths []string `yaml:"allowed-module-paths"`
+}
+
+// GetDefaultModuleDirectories returns module directories covering
+// a variety of Linux distros
+func GetDefaultModuleDirectories() []string {
+ dirs := []string{
+ "/usr/lib64/pkcs11/", // Fedora,RHEL,openSUSE
+ "/usr/lib/pkcs11/", // Fedora,ArchLinux
+ "/usr/local/lib/pkcs11/",
+ "/usr/lib/softhsm/", // Debian,Ubuntu
+ }
+
+ // Debian directory: /usr/lib/(x86_64|aarch64|arm|powerpc64le|riscv64|s390x)-linux-gnu/
+ hosttype, ostype, q := getHostAndOsType()
+ if len(hosttype) > 0 {
+ dir := fmt.Sprintf("/usr/lib/%s-%s-%s/", hosttype, ostype, q)
+ dirs = append(dirs, dir)
+ }
+ return dirs
+}
+
+// GetDefaultModuleDirectoresFormatted returns the default module directories formatted for YAML
+func GetDefaultModuleDirectoriesYaml(indent string) string {
+ res := ""
+
+ for _, dir := range GetDefaultModuleDirectories() {
+ res += indent + "- " + dir + "\n"
+ }
+ return res
+}
+
+// ParsePkcs11ConfigFile parses a pkcs11 config file hat influences the module search behavior
+// as well as the set of modules that users are allowed to use
+func ParsePkcs11ConfigFile(yamlstr []byte) (*Pkcs11Config, error) {
+ p11conf := Pkcs11Config{}
+
+ err := yaml.Unmarshal(yamlstr, &p11conf)
+ if err != nil {
+ return &p11conf, fmt.Errorf("Could not parse Pkcs11Config: %w", err)
+ }
+ return &p11conf, nil
+}