Move to vendor
Signed-off-by: Olivier Gambier <olivier@docker.com>
This commit is contained in:
parent
c8d8e7e357
commit
77e69b9cf3
1268 changed files with 34 additions and 24 deletions
210
vendor/github.com/aws/aws-sdk-go/service/cloudfront/sign/policy.go
generated
vendored
Normal file
210
vendor/github.com/aws/aws-sdk-go/service/cloudfront/sign/policy.go
generated
vendored
Normal file
|
@ -0,0 +1,210 @@
|
|||
package sign
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// An AWSEpochTime wraps a time value providing JSON serialization needed for
|
||||
// AWS Policy epoch time fields.
|
||||
type AWSEpochTime struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// NewAWSEpochTime returns a new AWSEpochTime pointer wrapping the Go time provided.
|
||||
func NewAWSEpochTime(t time.Time) *AWSEpochTime {
|
||||
return &AWSEpochTime{t}
|
||||
}
|
||||
|
||||
// MarshalJSON serializes the epoch time as AWS Profile epoch time.
|
||||
func (t AWSEpochTime) MarshalJSON() ([]byte, error) {
|
||||
return []byte(fmt.Sprintf(`{"AWS:EpochTime":%d}`, t.UTC().Unix())), nil
|
||||
}
|
||||
|
||||
// An IPAddress wraps an IPAddress source IP providing JSON serialization information
|
||||
type IPAddress struct {
|
||||
SourceIP string `json:"AWS:SourceIp"`
|
||||
}
|
||||
|
||||
// A Condition defines the restrictions for how a signed URL can be used.
|
||||
type Condition struct {
|
||||
// Optional IP address mask the signed URL must be requested from.
|
||||
IPAddress *IPAddress `json:"IpAddress,omitempty"`
|
||||
|
||||
// Optional date that the signed URL cannot be used until. It is invalid
|
||||
// to make requests with the signed URL prior to this date.
|
||||
DateGreaterThan *AWSEpochTime `json:",omitempty"`
|
||||
|
||||
// Required date that the signed URL will expire. A DateLessThan is required
|
||||
// sign cloud front URLs
|
||||
DateLessThan *AWSEpochTime `json:",omitempty"`
|
||||
}
|
||||
|
||||
// A Statement is a collection of conditions for resources
|
||||
type Statement struct {
|
||||
// The Web or RTMP resource the URL will be signed for
|
||||
Resource string
|
||||
|
||||
// The set of conditions for this resource
|
||||
Condition Condition
|
||||
}
|
||||
|
||||
// A Policy defines the resources that a signed will be signed for.
|
||||
//
|
||||
// See the following page for more information on how policies are constructed.
|
||||
// http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html#private-content-custom-policy-statement
|
||||
type Policy struct {
|
||||
// List of resource and condition statements.
|
||||
// Signed URLs should only provide a single statement.
|
||||
Statements []Statement `json:"Statement"`
|
||||
}
|
||||
|
||||
// Override for testing to mock out usage of crypto/rand.Reader
|
||||
var randReader = rand.Reader
|
||||
|
||||
// Sign will sign a policy using an RSA private key. It will return a base 64
|
||||
// encoded signature and policy if no error is encountered.
|
||||
//
|
||||
// The signature and policy should be added to the signed URL following the
|
||||
// guidelines in:
|
||||
// http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html
|
||||
func (p *Policy) Sign(privKey *rsa.PrivateKey) (b64Signature, b64Policy []byte, err error) {
|
||||
if err = p.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Build and escape the policy
|
||||
b64Policy, jsonPolicy, err := encodePolicy(p)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
awsEscapeEncoded(b64Policy)
|
||||
|
||||
// Build and escape the signature
|
||||
b64Signature, err = signEncodedPolicy(randReader, jsonPolicy, privKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
awsEscapeEncoded(b64Signature)
|
||||
|
||||
return b64Signature, b64Policy, nil
|
||||
}
|
||||
|
||||
// Validate verifies that the policy is valid and usable, and returns an
|
||||
// error if there is a problem.
|
||||
func (p *Policy) Validate() error {
|
||||
if len(p.Statements) == 0 {
|
||||
return fmt.Errorf("at least one policy statement is required")
|
||||
}
|
||||
for i, s := range p.Statements {
|
||||
if s.Resource == "" {
|
||||
return fmt.Errorf("statement at index %d does not have a resource", i)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateResource constructs, validates, and returns a resource URL string. An
|
||||
// error will be returned if unable to create the resource string.
|
||||
func CreateResource(scheme, u string) (string, error) {
|
||||
scheme = strings.ToLower(scheme)
|
||||
|
||||
if scheme == "http" || scheme == "https" {
|
||||
return u, nil
|
||||
}
|
||||
|
||||
if scheme == "rtmp" {
|
||||
parsed, err := url.Parse(u)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to parse rtmp URL, err: %s", err)
|
||||
}
|
||||
|
||||
rtmpURL := strings.TrimLeft(parsed.Path, "/")
|
||||
if parsed.RawQuery != "" {
|
||||
rtmpURL = fmt.Sprintf("%s?%s", rtmpURL, parsed.RawQuery)
|
||||
}
|
||||
|
||||
return rtmpURL, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("invalid URL scheme must be http, https, or rtmp. Provided: %s", scheme)
|
||||
}
|
||||
|
||||
// NewCannedPolicy returns a new Canned Policy constructed using the resource
|
||||
// and expires time. This can be used to generate the basic model for a Policy
|
||||
// that can be then augmented with additional conditions.
|
||||
//
|
||||
// See the following page for more information on how policies are constructed.
|
||||
// http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html#private-content-custom-policy-statement
|
||||
func NewCannedPolicy(resource string, expires time.Time) *Policy {
|
||||
return &Policy{
|
||||
Statements: []Statement{
|
||||
{
|
||||
Resource: resource,
|
||||
Condition: Condition{
|
||||
DateLessThan: NewAWSEpochTime(expires),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// encodePolicy encodes the Policy as JSON and also base 64 encodes it.
|
||||
func encodePolicy(p *Policy) (b64Policy, jsonPolicy []byte, err error) {
|
||||
jsonPolicy, err = json.Marshal(p)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to encode policy, %s", err.Error())
|
||||
}
|
||||
|
||||
// Remove leading and trailing white space, JSON encoding will note include
|
||||
// whitespace within the encoding.
|
||||
jsonPolicy = bytes.TrimSpace(jsonPolicy)
|
||||
|
||||
b64Policy = make([]byte, base64.StdEncoding.EncodedLen(len(jsonPolicy)))
|
||||
base64.StdEncoding.Encode(b64Policy, jsonPolicy)
|
||||
return b64Policy, jsonPolicy, nil
|
||||
}
|
||||
|
||||
// signEncodedPolicy will sign and base 64 encode the JSON encoded policy.
|
||||
func signEncodedPolicy(randReader io.Reader, jsonPolicy []byte, privKey *rsa.PrivateKey) ([]byte, error) {
|
||||
hash := sha1.New()
|
||||
if _, err := bytes.NewReader(jsonPolicy).WriteTo(hash); err != nil {
|
||||
return nil, fmt.Errorf("failed to calculate signing hash, %s", err.Error())
|
||||
}
|
||||
|
||||
sig, err := rsa.SignPKCS1v15(randReader, privKey, crypto.SHA1, hash.Sum(nil))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to sign policy, %s", err.Error())
|
||||
}
|
||||
|
||||
b64Sig := make([]byte, base64.StdEncoding.EncodedLen(len(sig)))
|
||||
base64.StdEncoding.Encode(b64Sig, sig)
|
||||
return b64Sig, nil
|
||||
}
|
||||
|
||||
// special characters to be replaced with awsEscapeEncoded
|
||||
var invalidEncodedChar = map[byte]byte{
|
||||
'+': '-',
|
||||
'=': '_',
|
||||
'/': '~',
|
||||
}
|
||||
|
||||
// awsEscapeEncoded will replace base64 encoding's special characters to be URL safe.
|
||||
func awsEscapeEncoded(b []byte) {
|
||||
for i, v := range b {
|
||||
if r, ok := invalidEncodedChar[v]; ok {
|
||||
b[i] = r
|
||||
}
|
||||
}
|
||||
}
|
68
vendor/github.com/aws/aws-sdk-go/service/cloudfront/sign/privkey.go
generated
vendored
Normal file
68
vendor/github.com/aws/aws-sdk-go/service/cloudfront/sign/privkey.go
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
package sign
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
// LoadPEMPrivKeyFile reads a PEM encoded RSA private key from the file name.
|
||||
// A new RSA private key will be returned if no error.
|
||||
func LoadPEMPrivKeyFile(name string) (*rsa.PrivateKey, error) {
|
||||
file, err := os.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
return LoadPEMPrivKey(file)
|
||||
}
|
||||
|
||||
// LoadPEMPrivKey reads a PEM encoded RSA private key from the io.Reader.
|
||||
// A new RSA private key will be returned if no error.
|
||||
func LoadPEMPrivKey(reader io.Reader) (*rsa.PrivateKey, error) {
|
||||
block, err := loadPem(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
}
|
||||
|
||||
// LoadEncryptedPEMPrivKey decrypts the PEM encoded private key using the
|
||||
// password provided returning a RSA private key. If the PEM data is invalid,
|
||||
// or unable to decrypt an error will be returned.
|
||||
func LoadEncryptedPEMPrivKey(reader io.Reader, password []byte) (*rsa.PrivateKey, error) {
|
||||
block, err := loadPem(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decryptedBlock, err := x509.DecryptPEMBlock(block, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return x509.ParsePKCS1PrivateKey(decryptedBlock)
|
||||
}
|
||||
|
||||
func loadPem(reader io.Reader) (*pem.Block, error) {
|
||||
b, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(b)
|
||||
if block == nil {
|
||||
// pem.Decode will set block to nil if there is no PEM data in the input
|
||||
// the second parameter will contain the provided bytes that failed
|
||||
// to be decoded.
|
||||
return nil, fmt.Errorf("no valid PEM data provided")
|
||||
}
|
||||
|
||||
return block, nil
|
||||
}
|
30
vendor/github.com/aws/aws-sdk-go/service/cloudfront/sign/randomreader.go
generated
vendored
Normal file
30
vendor/github.com/aws/aws-sdk-go/service/cloudfront/sign/randomreader.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
package sign
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
// A randomReader wraps a math/rand.Rand within an reader so that it can used
|
||||
// as a predictable testing replacement for crypto/rand.Reader
|
||||
type randomReader struct {
|
||||
b *bytes.Buffer
|
||||
r *rand.Rand
|
||||
}
|
||||
|
||||
// newRandomReader returns a new instance of the random reader
|
||||
func newRandomReader(r *rand.Rand) *randomReader {
|
||||
return &randomReader{b: &bytes.Buffer{}, r: r}
|
||||
}
|
||||
|
||||
// Read will read random bytes from up to the length of b.
|
||||
func (m *randomReader) Read(b []byte) (int, error) {
|
||||
for i := 0; i < len(b); {
|
||||
binary.Write(m.b, binary.LittleEndian, m.r.Int63())
|
||||
n, _ := m.b.Read(b[i:])
|
||||
i += n
|
||||
}
|
||||
|
||||
return len(b), nil
|
||||
}
|
205
vendor/github.com/aws/aws-sdk-go/service/cloudfront/sign/sign_url.go
generated
vendored
Normal file
205
vendor/github.com/aws/aws-sdk-go/service/cloudfront/sign/sign_url.go
generated
vendored
Normal file
|
@ -0,0 +1,205 @@
|
|||
// Package sign provides utilities to generate signed URLs for Amazon CloudFront.
|
||||
//
|
||||
// More information about signed URLs and their structure can be found at:
|
||||
// http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-canned-policy.html
|
||||
//
|
||||
// To sign a URL create a URLSigner with your private key and credential pair key ID.
|
||||
// Once you have a URLSigner instance you can call Sign or SignWithPolicy to
|
||||
// sign the URLs.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Sign URL to be valid for 1 hour from now.
|
||||
// signer := sign.NewURLSigner(keyID, privKey)
|
||||
// signedURL, err := signer.Sign(rawURL, time.Now().Add(1*time.Hour))
|
||||
// if err != nil {
|
||||
// log.Fatalf("Failed to sign url, err: %s\n", err.Error())
|
||||
// }
|
||||
//
|
||||
package sign
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// An URLSigner provides URL signing utilities to sign URLs for Amazon CloudFront
|
||||
// resources. Using a private key and Credential Key Pair key ID the URLSigner
|
||||
// only needs to be created once per Credential Key Pair key ID and private key.
|
||||
//
|
||||
// The signer is safe to use concurrently.
|
||||
type URLSigner struct {
|
||||
keyID string
|
||||
privKey *rsa.PrivateKey
|
||||
}
|
||||
|
||||
// NewURLSigner constructs and returns a new URLSigner to be used to for signing
|
||||
// Amazon CloudFront URL resources with.
|
||||
func NewURLSigner(keyID string, privKey *rsa.PrivateKey) *URLSigner {
|
||||
return &URLSigner{
|
||||
keyID: keyID,
|
||||
privKey: privKey,
|
||||
}
|
||||
}
|
||||
|
||||
// Sign will sign a single URL to expire at the time of expires sign using the
|
||||
// Amazon CloudFront default Canned Policy. The URL will be signed with the
|
||||
// private key and Credential Key Pair Key ID previously provided to URLSigner.
|
||||
//
|
||||
// This is the default method of signing Amazon CloudFront URLs. If extra policy
|
||||
// conditions are need other than URL expiry use SignWithPolicy instead.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Sign URL to be valid for 1 hour from now.
|
||||
// signer := sign.NewURLSigner(keyID, privKey)
|
||||
// signedURL, err := signer.Sign(rawURL, time.Now().Add(1*time.Hour))
|
||||
// if err != nil {
|
||||
// log.Fatalf("Failed to sign url, err: %s\n", err.Error())
|
||||
// }
|
||||
//
|
||||
func (s URLSigner) Sign(url string, expires time.Time) (string, error) {
|
||||
scheme, cleanedURL, err := cleanURLScheme(url)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
resource, err := CreateResource(scheme, url)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return signURL(scheme, cleanedURL, s.keyID, NewCannedPolicy(resource, expires), false, s.privKey)
|
||||
}
|
||||
|
||||
// SignWithPolicy will sign a URL with the Policy provided. The URL will be
|
||||
// signed with the private key and Credential Key Pair Key ID previously provided to URLSigner.
|
||||
//
|
||||
// Use this signing method if you are looking to sign a URL with more than just
|
||||
// the URL's expiry time, or reusing Policies between multiple URL signings.
|
||||
// If only the expiry time is needed you can use Sign and provide just the
|
||||
// URL's expiry time. A minimum of at least one policy statement is required for a signed URL.
|
||||
//
|
||||
// Note: It is not safe to use Polices between multiple signers concurrently
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Sign URL to be valid for 30 minutes from now, expires one hour from now, and
|
||||
// // restricted to the 192.0.2.0/24 IP address range.
|
||||
// policy := &sign.Policy{
|
||||
// Statements: []Statement{
|
||||
// {
|
||||
// Resource: rawURL,
|
||||
// Condition: Condition{
|
||||
// // Optional IP source address range
|
||||
// IPAddress: &IPAddress{SourceIP: "192.0.2.0/24"},
|
||||
// // Optional date URL is not valid until
|
||||
// DateGreaterThan: &AWSEpochTime{time.Now().Add(30 * time.Minute)},
|
||||
// // Required date the URL will expire after
|
||||
// DateLessThan: &AWSEpochTime{time.Now().Add(1 * time.Hour)},
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// signer := sign.NewURLSigner(keyID, privKey)
|
||||
// signedURL, err := signer.SignWithPolicy(rawURL, policy)
|
||||
// if err != nil {
|
||||
// log.Fatalf("Failed to sign url, err: %s\n", err.Error())
|
||||
// }
|
||||
//
|
||||
func (s URLSigner) SignWithPolicy(url string, p *Policy) (string, error) {
|
||||
scheme, cleanedURL, err := cleanURLScheme(url)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return signURL(scheme, cleanedURL, s.keyID, p, true, s.privKey)
|
||||
}
|
||||
|
||||
func signURL(scheme, url, keyID string, p *Policy, customPolicy bool, privKey *rsa.PrivateKey) (string, error) {
|
||||
// Validation URL elements
|
||||
if err := validateURL(url); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
b64Signature, b64Policy, err := p.Sign(privKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// build and return signed URL
|
||||
builtURL := buildSignedURL(url, keyID, p, customPolicy, b64Policy, b64Signature)
|
||||
if scheme == "rtmp" {
|
||||
return buildRTMPURL(builtURL)
|
||||
}
|
||||
|
||||
return builtURL, nil
|
||||
}
|
||||
|
||||
func buildSignedURL(baseURL, keyID string, p *Policy, customPolicy bool, b64Policy, b64Signature []byte) string {
|
||||
pred := "?"
|
||||
if strings.Contains(baseURL, "?") {
|
||||
pred = "&"
|
||||
}
|
||||
signedURL := baseURL + pred
|
||||
|
||||
if customPolicy {
|
||||
signedURL += "Policy=" + string(b64Policy)
|
||||
} else {
|
||||
signedURL += fmt.Sprintf("Expires=%d", p.Statements[0].Condition.DateLessThan.UTC().Unix())
|
||||
}
|
||||
signedURL += fmt.Sprintf("&Signature=%s&Key-Pair-Id=%s", string(b64Signature), keyID)
|
||||
|
||||
return signedURL
|
||||
}
|
||||
|
||||
func buildRTMPURL(u string) (string, error) {
|
||||
parsed, err := url.Parse(u)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to parse rtmp signed URL, err: %s", err)
|
||||
}
|
||||
|
||||
rtmpURL := strings.TrimLeft(parsed.Path, "/")
|
||||
if parsed.RawQuery != "" {
|
||||
rtmpURL = fmt.Sprintf("%s?%s", rtmpURL, parsed.RawQuery)
|
||||
}
|
||||
|
||||
return rtmpURL, nil
|
||||
}
|
||||
|
||||
func cleanURLScheme(u string) (scheme, cleanedURL string, err error) {
|
||||
parts := strings.SplitN(u, "://", 2)
|
||||
if len(parts) != 2 {
|
||||
return "", "", fmt.Errorf("invalid URL, missing scheme and domain/path")
|
||||
}
|
||||
scheme = strings.Replace(parts[0], "*", "", 1)
|
||||
cleanedURL = fmt.Sprintf("%s://%s", scheme, parts[1])
|
||||
|
||||
return strings.ToLower(scheme), cleanedURL, nil
|
||||
}
|
||||
|
||||
var illegalQueryParms = []string{"Expires", "Policy", "Signature", "Key-Pair-Id"}
|
||||
|
||||
func validateURL(u string) error {
|
||||
parsed, err := url.Parse(u)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse URL, err: %s", err.Error())
|
||||
}
|
||||
|
||||
if parsed.Scheme == "" {
|
||||
return fmt.Errorf("URL missing valid scheme, %s", u)
|
||||
}
|
||||
|
||||
q := parsed.Query()
|
||||
for _, p := range illegalQueryParms {
|
||||
if _, ok := q[p]; ok {
|
||||
return fmt.Errorf("%s cannot be a query parameter for a signed URL", p)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue