certificates/kms/uri/uri.go
Mariano Cano b0f768a3fb Add implementation of URIs for KMS.
Implementation is based on the PKCS #11 URI Scheme RFC
https://tools.ietf.org/html/rfc7512
2020-05-19 17:32:52 -07:00

86 lines
1.9 KiB
Go

package uri
import (
"net/url"
"strings"
"github.com/pkg/errors"
)
// URI implements a parser for a URI format based on the the PKCS #11 URI Scheme
// defined in https://tools.ietf.org/html/rfc7512
//
// These URIs will be used to define the key names in a KMS.
type URI struct {
*url.URL
Values url.Values
}
// New creates a new URI from a scheme and key-value pairs.
func New(scheme string, values url.Values) *URI {
return &URI{
URL: &url.URL{
Scheme: scheme,
Opaque: strings.ReplaceAll(values.Encode(), "&", ";"),
},
Values: values,
}
}
// NewFile creates an uri for a file.
func NewFile(path string) *URI {
return &URI{
URL: &url.URL{
Scheme: "file",
Path: path,
},
}
}
// HasScheme returns true if the given uri has the given scheme, false otherwise.
func HasScheme(scheme, rawuri string) bool {
u, err := url.Parse(rawuri)
if err != nil {
return false
}
return strings.EqualFold(u.Scheme, scheme)
}
// Parse returns the URI for the given string or an error.
func Parse(rawuri string) (*URI, error) {
u, err := url.Parse(rawuri)
if err != nil {
return nil, errors.Wrapf(err, "error parsing %s", rawuri)
}
if u.Scheme == "" {
return nil, errors.Errorf("error parsing %s: scheme is missing", rawuri)
}
v, err := url.ParseQuery(u.Opaque)
if err != nil {
return nil, errors.Wrapf(err, "error parsing %s", rawuri)
}
return &URI{
URL: u,
Values: v,
}, nil
}
// ParseWithScheme returns the URI for the given string only if it has the given
// scheme.
func ParseWithScheme(scheme, rawuri string) (*URI, error) {
u, err := Parse(rawuri)
if err != nil {
return nil, err
}
if !strings.EqualFold(u.Scheme, scheme) {
return nil, errors.Errorf("error parsing %s: scheme not expected", rawuri)
}
return u, nil
}
// Get returns the first value in the uri with the give n key, it will return
// empty string if that field is not present.
func (u *URI) Get(key string) string {
return u.Values.Get(key)
}