summaryrefslogtreecommitdiff
path: root/vendor/github.com/mitchellh/packer/builder/oracle/oci/client/transport.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mitchellh/packer/builder/oracle/oci/client/transport.go')
-rw-r--r--vendor/github.com/mitchellh/packer/builder/oracle/oci/client/transport.go116
1 files changed, 116 insertions, 0 deletions
diff --git a/vendor/github.com/mitchellh/packer/builder/oracle/oci/client/transport.go b/vendor/github.com/mitchellh/packer/builder/oracle/oci/client/transport.go
new file mode 100644
index 00000000..79da2050
--- /dev/null
+++ b/vendor/github.com/mitchellh/packer/builder/oracle/oci/client/transport.go
@@ -0,0 +1,116 @@
+package oci
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha256"
+ "encoding/base64"
+ "fmt"
+ "io"
+ "net/http"
+ "strconv"
+ "strings"
+ "time"
+)
+
+type nopCloser struct {
+ io.Reader
+}
+
+func (nopCloser) Close() error {
+ return nil
+}
+
+// Transport adds OCI signature authentication to each outgoing request.
+type Transport struct {
+ transport http.RoundTripper
+ config *Config
+}
+
+// NewTransport creates a new Transport to add OCI signature authentication
+// to each outgoing request.
+func NewTransport(transport http.RoundTripper, config *Config) *Transport {
+ return &Transport{
+ transport: transport,
+ config: config,
+ }
+}
+
+func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
+ var buf *bytes.Buffer
+
+ if req.Body != nil {
+ buf = new(bytes.Buffer)
+ buf.ReadFrom(req.Body)
+ req.Body = nopCloser{buf}
+ }
+ if req.Header.Get("date") == "" {
+ req.Header.Set("date", time.Now().UTC().Format(http.TimeFormat))
+ }
+ if req.Header.Get("content-type") == "" {
+ req.Header.Set("content-type", "application/json")
+ }
+ if req.Header.Get("accept") == "" {
+ req.Header.Set("accept", "application/json")
+ }
+ if req.Header.Get("host") == "" {
+ req.Header.Set("host", req.URL.Host)
+ }
+
+ var signheaders []string
+ if (req.Method == "PUT" || req.Method == "POST") && buf != nil {
+ signheaders = []string{"(request-target)", "host", "date",
+ "content-length", "content-type", "x-content-sha256"}
+
+ if req.Header.Get("content-length") == "" {
+ req.Header.Set("content-length", strconv.Itoa(buf.Len()))
+ }
+
+ hasher := sha256.New()
+ hasher.Write(buf.Bytes())
+ hash := hasher.Sum(nil)
+ req.Header.Set("x-content-sha256", base64.StdEncoding.EncodeToString(hash))
+ } else {
+ signheaders = []string{"date", "host", "(request-target)"}
+ }
+
+ var signbuffer bytes.Buffer
+ for idx, header := range signheaders {
+ signbuffer.WriteString(header)
+ signbuffer.WriteString(": ")
+
+ if header == "(request-target)" {
+ signbuffer.WriteString(strings.ToLower(req.Method))
+ signbuffer.WriteString(" ")
+ signbuffer.WriteString(req.URL.RequestURI())
+ } else {
+ signbuffer.WriteString(req.Header.Get(header))
+ }
+
+ if idx < len(signheaders)-1 {
+ signbuffer.WriteString("\n")
+ }
+ }
+
+ h := sha256.New()
+ h.Write(signbuffer.Bytes())
+ digest := h.Sum(nil)
+ signature, err := rsa.SignPKCS1v15(rand.Reader, t.config.Key, crypto.SHA256, digest)
+ if err != nil {
+ return nil, err
+ }
+
+ authHeader := fmt.Sprintf("Signature headers=\"%s\","+
+ "keyId=\"%s/%s/%s\","+
+ "algorithm=\"rsa-sha256\","+
+ "signature=\"%s\","+
+ "version=\"1\"",
+ strings.Join(signheaders, " "),
+ t.config.Tenancy, t.config.User, t.config.Fingerprint,
+ base64.StdEncoding.EncodeToString(signature))
+ req.Header.Add("Authorization", authHeader)
+
+ return t.transport.RoundTrip(req)
+}