Этот коммит содержится в:
Christopher Speller
2016-09-23 10:17:51 -04:00
коммит произвёл GitHub
родитель 6d62d65b2d
Коммит 2ca0e8f9a0
366 изменённых файлов: 31573 добавлений и 16566 удалений

944
vendor/golang.org/x/crypto/acme/acme.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,944 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package acme provides an implementation of the
// Automatic Certificate Management Environment (ACME) spec.
// See https://tools.ietf.org/html/draft-ietf-acme-acme-02 for details.
//
// Most common scenarios will want to use autocert subdirectory instead,
// which provides automatic access to certificates from Let's Encrypt
// and any other ACME-based CA.
//
// This package is a work in progress and makes no API stability promises.
package acme
import (
"bytes"
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"encoding/hex"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"io"
"io/ioutil"
"math/big"
"net/http"
"strconv"
"strings"
"sync"
"time"
"golang.org/x/net/context"
"golang.org/x/net/context/ctxhttp"
)
// LetsEncryptURL is the Directory endpoint of Let's Encrypt CA.
const LetsEncryptURL = "https://acme-v01.api.letsencrypt.org/directory"
const (
maxChainLen = 5 // max depth and breadth of a certificate chain
maxCertSize = 1 << 20 // max size of a certificate, in bytes
)
// CertOption is an optional argument type for Client methods which manipulate
// certificate data.
type CertOption interface {
privateCertOpt()
}
// WithKey creates an option holding a private/public key pair.
// The private part signs a certificate, and the public part represents the signee.
func WithKey(key crypto.Signer) CertOption {
return &certOptKey{key}
}
type certOptKey struct {
key crypto.Signer
}
func (*certOptKey) privateCertOpt() {}
// WithTemplate creates an option for specifying a certificate template.
// See x509.CreateCertificate for template usage details.
//
// In TLSSNIxChallengeCert methods, the template is also used as parent,
// resulting in a self-signed certificate.
// The DNSNames field of t is always overwritten for tls-sni challenge certs.
func WithTemplate(t *x509.Certificate) CertOption {
return (*certOptTemplate)(t)
}
type certOptTemplate x509.Certificate
func (*certOptTemplate) privateCertOpt() {}
// Client is an ACME client.
// The only required field is Key. An example of creating a client with a new key
// is as follows:
//
// key, err := rsa.GenerateKey(rand.Reader, 2048)
// if err != nil {
// log.Fatal(err)
// }
// client := &Client{Key: key}
//
type Client struct {
// Key is the account key used to register with a CA and sign requests.
// Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey.
Key crypto.Signer
// HTTPClient optionally specifies an HTTP client to use
// instead of http.DefaultClient.
HTTPClient *http.Client
// DirectoryURL points to the CA directory endpoint.
// If empty, LetsEncryptURL is used.
// Mutating this value after a successful call of Client's Discover method
// will have no effect.
DirectoryURL string
dirMu sync.Mutex // guards writes to dir
dir *Directory // cached result of Client's Discover method
}
// Discover performs ACME server discovery using c.DirectoryURL.
//
// It caches successful result. So, subsequent calls will not result in
// a network round-trip. This also means mutating c.DirectoryURL after successful call
// of this method will have no effect.
func (c *Client) Discover(ctx context.Context) (Directory, error) {
c.dirMu.Lock()
defer c.dirMu.Unlock()
if c.dir != nil {
return *c.dir, nil
}
dirURL := c.DirectoryURL
if dirURL == "" {
dirURL = LetsEncryptURL
}
res, err := ctxhttp.Get(ctx, c.HTTPClient, dirURL)
if err != nil {
return Directory{}, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return Directory{}, responseError(res)
}
var v struct {
Reg string `json:"new-reg"`
Authz string `json:"new-authz"`
Cert string `json:"new-cert"`
Revoke string `json:"revoke-cert"`
Meta struct {
Terms string `json:"terms-of-service"`
Website string `json:"website"`
CAA []string `json:"caa-identities"`
}
}
if json.NewDecoder(res.Body).Decode(&v); err != nil {
return Directory{}, err
}
c.dir = &Directory{
RegURL: v.Reg,
AuthzURL: v.Authz,
CertURL: v.Cert,
RevokeURL: v.Revoke,
Terms: v.Meta.Terms,
Website: v.Meta.Website,
CAA: v.Meta.CAA,
}
return *c.dir, nil
}
// CreateCert requests a new certificate using the Certificate Signing Request csr encoded in DER format.
// The exp argument indicates the desired certificate validity duration. CA may issue a certificate
// with a different duration.
// If the bundle argument is true, the returned value will also contain the CA (issuer) certificate chain.
//
// In the case where CA server does not provide the issued certificate in the response,
// CreateCert will poll certURL using c.FetchCert, which will result in additional round-trips.
// In such scenario the caller can cancel the polling with ctx.
//
// CreateCert returns an error if the CA's response or chain was unreasonably large.
// Callers are encouraged to parse the returned value to ensure the certificate is valid and has the expected features.
func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration, bundle bool) (der [][]byte, certURL string, err error) {
if _, err := c.Discover(ctx); err != nil {
return nil, "", err
}
req := struct {
Resource string `json:"resource"`
CSR string `json:"csr"`
NotBefore string `json:"notBefore,omitempty"`
NotAfter string `json:"notAfter,omitempty"`
}{
Resource: "new-cert",
CSR: base64.RawURLEncoding.EncodeToString(csr),
}
now := timeNow()
req.NotBefore = now.Format(time.RFC3339)
if exp > 0 {
req.NotAfter = now.Add(exp).Format(time.RFC3339)
}
res, err := postJWS(ctx, c.HTTPClient, c.Key, c.dir.CertURL, req)
if err != nil {
return nil, "", err
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
return nil, "", responseError(res)
}
curl := res.Header.Get("location") // cert permanent URL
if res.ContentLength == 0 {
// no cert in the body; poll until we get it
cert, err := c.FetchCert(ctx, curl, bundle)
return cert, curl, err
}
// slurp issued cert and CA chain, if requested
cert, err := responseCert(ctx, c.HTTPClient, res, bundle)
return cert, curl, err
}
// FetchCert retrieves already issued certificate from the given url, in DER format.
// It retries the request until the certificate is successfully retrieved,
// context is cancelled by the caller or an error response is received.
//
// The returned value will also contain the CA (issuer) certificate if the bundle argument is true.
//
// FetchCert returns an error if the CA's response or chain was unreasonably large.
// Callers are encouraged to parse the returned value to ensure the certificate is valid
// and has expected features.
func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) {
for {
res, err := ctxhttp.Get(ctx, c.HTTPClient, url)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode == http.StatusOK {
return responseCert(ctx, c.HTTPClient, res, bundle)
}
if res.StatusCode > 299 {
return nil, responseError(res)
}
d := retryAfter(res.Header.Get("retry-after"), 3*time.Second)
select {
case <-time.After(d):
// retry
case <-ctx.Done():
return nil, ctx.Err()
}
}
}
// RevokeCert revokes a previously issued certificate cert, provided in DER format.
//
// The key argument, used to sign the request, must be authorized
// to revoke the certificate. It's up to the CA to decide which keys are authorized.
// For instance, the key pair of the certificate may be authorized.
// If the key is nil, c.Key is used instead.
func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error {
if _, err := c.Discover(ctx); err != nil {
return err
}
body := &struct {
Resource string `json:"resource"`
Cert string `json:"certificate"`
Reason int `json:"reason"`
}{
Resource: "revoke-cert",
Cert: base64.RawURLEncoding.EncodeToString(cert),
Reason: int(reason),
}
if key == nil {
key = c.Key
}
res, err := postJWS(ctx, c.HTTPClient, key, c.dir.RevokeURL, body)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return responseError(res)
}
return nil
}
// AcceptTOS always returns true to indicate the acceptance of a CA's Terms of Service
// during account registration. See Register method of Client for more details.
func AcceptTOS(tosURL string) bool { return true }
// Register creates a new account registration by following the "new-reg" flow.
// It returns registered account. The a argument is not modified.
//
// The registration may require the caller to agree to the CA's Terms of Service (TOS).
// If so, and the account has not indicated the acceptance of the terms (see Account for details),
// Register calls prompt with a TOS URL provided by the CA. Prompt should report
// whether the caller agrees to the terms. To always accept the terms, the caller can use AcceptTOS.
func (c *Client) Register(ctx context.Context, a *Account, prompt func(tosURL string) bool) (*Account, error) {
if _, err := c.Discover(ctx); err != nil {
return nil, err
}
var err error
if a, err = c.doReg(ctx, c.dir.RegURL, "new-reg", a); err != nil {
return nil, err
}
var accept bool
if a.CurrentTerms != "" && a.CurrentTerms != a.AgreedTerms {
accept = prompt(a.CurrentTerms)
}
if accept {
a.AgreedTerms = a.CurrentTerms
a, err = c.UpdateReg(ctx, a)
}
return a, err
}
// GetReg retrieves an existing registration.
// The url argument is an Account URI.
func (c *Client) GetReg(ctx context.Context, url string) (*Account, error) {
a, err := c.doReg(ctx, url, "reg", nil)
if err != nil {
return nil, err
}
a.URI = url
return a, nil
}
// UpdateReg updates an existing registration.
// It returns an updated account copy. The provided account is not modified.
func (c *Client) UpdateReg(ctx context.Context, a *Account) (*Account, error) {
uri := a.URI
a, err := c.doReg(ctx, uri, "reg", a)
if err != nil {
return nil, err
}
a.URI = uri
return a, nil
}
// Authorize performs the initial step in an authorization flow.
// The caller will then need to choose from and perform a set of returned
// challenges using c.Accept in order to successfully complete authorization.
//
// If an authorization has been previously granted, the CA may return
// a valid authorization (Authorization.Status is StatusValid). If so, the caller
// need not fulfill any challenge and can proceed to requesting a certificate.
func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization, error) {
if _, err := c.Discover(ctx); err != nil {
return nil, err
}
type authzID struct {
Type string `json:"type"`
Value string `json:"value"`
}
req := struct {
Resource string `json:"resource"`
Identifier authzID `json:"identifier"`
}{
Resource: "new-authz",
Identifier: authzID{Type: "dns", Value: domain},
}
res, err := postJWS(ctx, c.HTTPClient, c.Key, c.dir.AuthzURL, req)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
return nil, responseError(res)
}
var v wireAuthz
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, fmt.Errorf("acme: invalid response: %v", err)
}
if v.Status != StatusPending && v.Status != StatusValid {
return nil, fmt.Errorf("acme: unexpected status: %s", v.Status)
}
return v.authorization(res.Header.Get("Location")), nil
}
// GetAuthorization retrieves an authorization identified by the given URL.
//
// If a caller needs to poll an authorization until its status is final,
// see the WaitAuthorization method.
func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error) {
res, err := ctxhttp.Get(ctx, c.HTTPClient, url)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
return nil, responseError(res)
}
var v wireAuthz
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, fmt.Errorf("acme: invalid response: %v", err)
}
return v.authorization(url), nil
}
// RevokeAuthorization relinquishes an existing authorization identified
// by the given URL.
// The url argument is an Authorization.URI value.
//
// If successful, the caller will be required to obtain a new authorization
// using the Authorize method before being able to request a new certificate
// for the domain associated with the authorization.
//
// It does not revoke existing certificates.
func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
req := struct {
Resource string `json:"resource"`
Delete bool `json:"delete"`
}{
Resource: "authz",
Delete: true,
}
res, err := postJWS(ctx, c.HTTPClient, c.Key, url, req)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return responseError(res)
}
return nil
}
// WaitAuthorization polls an authorization at the given URL
// until it is in one of the final states, StatusValid or StatusInvalid,
// or the context is done.
//
// It returns a non-nil Authorization only if its Status is StatusValid.
// In all other cases WaitAuthorization returns an error.
// If the Status is StatusInvalid, the returned error is ErrAuthorizationFailed.
func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error) {
var count int
sleep := func(v string, inc int) error {
count += inc
d := backoff(count, 10*time.Second)
d = retryAfter(v, d)
wakeup := time.NewTimer(d)
defer wakeup.Stop()
select {
case <-ctx.Done():
return ctx.Err()
case <-wakeup.C:
return nil
}
}
for {
res, err := ctxhttp.Get(ctx, c.HTTPClient, url)
if err != nil {
return nil, err
}
retry := res.Header.Get("retry-after")
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
res.Body.Close()
if err := sleep(retry, 1); err != nil {
return nil, err
}
continue
}
var raw wireAuthz
err = json.NewDecoder(res.Body).Decode(&raw)
res.Body.Close()
if err != nil {
if err := sleep(retry, 0); err != nil {
return nil, err
}
continue
}
if raw.Status == StatusValid {
return raw.authorization(url), nil
}
if raw.Status == StatusInvalid {
return nil, ErrAuthorizationFailed
}
if err := sleep(retry, 0); err != nil {
return nil, err
}
}
}
// GetChallenge retrieves the current status of an challenge.
//
// A client typically polls a challenge status using this method.
func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) {
res, err := ctxhttp.Get(ctx, c.HTTPClient, url)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
return nil, responseError(res)
}
v := wireChallenge{URI: url}
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, fmt.Errorf("acme: invalid response: %v", err)
}
return v.challenge(), nil
}
// Accept informs the server that the client accepts one of its challenges
// previously obtained with c.Authorize.
//
// The server will then perform the validation asynchronously.
func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error) {
auth, err := keyAuth(c.Key.Public(), chal.Token)
if err != nil {
return nil, err
}
req := struct {
Resource string `json:"resource"`
Type string `json:"type"`
Auth string `json:"keyAuthorization"`
}{
Resource: "challenge",
Type: chal.Type,
Auth: auth,
}
res, err := postJWS(ctx, c.HTTPClient, c.Key, chal.URI, req)
if err != nil {
return nil, err
}
defer res.Body.Close()
// Note: the protocol specifies 200 as the expected response code, but
// letsencrypt seems to be returning 202.
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
return nil, responseError(res)
}
var v wireChallenge
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, fmt.Errorf("acme: invalid response: %v", err)
}
return v.challenge(), nil
}
// DNS01ChallengeRecord returns a DNS record value for a dns-01 challenge response.
// A TXT record containing the returned value must be provisioned under
// "_acme-challenge" name of the domain being validated.
//
// The token argument is a Challenge.Token value.
func (c *Client) DNS01ChallengeRecord(token string) (string, error) {
ka, err := keyAuth(c.Key.Public(), token)
if err != nil {
return "", err
}
b := sha256.Sum256([]byte(ka))
return base64.RawURLEncoding.EncodeToString(b[:]), nil
}
// HTTP01ChallengeResponse returns the response for an http-01 challenge.
// Servers should respond with the value to HTTP requests at the URL path
// provided by HTTP01ChallengePath to validate the challenge and prove control
// over a domain name.
//
// The token argument is a Challenge.Token value.
func (c *Client) HTTP01ChallengeResponse(token string) (string, error) {
return keyAuth(c.Key.Public(), token)
}
// HTTP01ChallengePath returns the URL path at which the response for an http-01 challenge
// should be provided by the servers.
// The response value can be obtained with HTTP01ChallengeResponse.
//
// The token argument is a Challenge.Token value.
func (c *Client) HTTP01ChallengePath(token string) string {
return "/.well-known/acme-challenge/" + token
}
// TLSSNI01ChallengeCert creates a certificate for TLS-SNI-01 challenge response.
// Servers can present the certificate to validate the challenge and prove control
// over a domain name.
//
// The implementation is incomplete in that the returned value is a single certificate,
// computed only for Z0 of the key authorization. ACME CAs are expected to update
// their implementations to use the newer version, TLS-SNI-02.
// For more details on TLS-SNI-01 see https://tools.ietf.org/html/draft-ietf-acme-acme-01#section-7.3.
//
// The token argument is a Challenge.Token value.
// If a WithKey option is provided, its private part signs the returned cert,
// and the public part is used to specify the signee.
// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
//
// The returned certificate is valid for the next 24 hours and must be presented only when
// the server name of the client hello matches exactly the returned name value.
func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
ka, err := keyAuth(c.Key.Public(), token)
if err != nil {
return tls.Certificate{}, "", err
}
b := sha256.Sum256([]byte(ka))
h := hex.EncodeToString(b[:])
name = fmt.Sprintf("%s.%s.acme.invalid", h[:32], h[32:])
cert, err = tlsChallengeCert([]string{name}, opt)
if err != nil {
return tls.Certificate{}, "", err
}
return cert, name, nil
}
// TLSSNI02ChallengeCert creates a certificate for TLS-SNI-02 challenge response.
// Servers can present the certificate to validate the challenge and prove control
// over a domain name. For more details on TLS-SNI-02 see
// https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-7.3.
//
// The token argument is a Challenge.Token value.
// If a WithKey option is provided, its private part signs the returned cert,
// and the public part is used to specify the signee.
// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
//
// The returned certificate is valid for the next 24 hours and must be presented only when
// the server name in the client hello matches exactly the returned name value.
func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
b := sha256.Sum256([]byte(token))
h := hex.EncodeToString(b[:])
sanA := fmt.Sprintf("%s.%s.token.acme.invalid", h[:32], h[32:])
ka, err := keyAuth(c.Key.Public(), token)
if err != nil {
return tls.Certificate{}, "", err
}
b = sha256.Sum256([]byte(ka))
h = hex.EncodeToString(b[:])
sanB := fmt.Sprintf("%s.%s.ka.acme.invalid", h[:32], h[32:])
cert, err = tlsChallengeCert([]string{sanA, sanB}, opt)
if err != nil {
return tls.Certificate{}, "", err
}
return cert, sanA, nil
}
// doReg sends all types of registration requests.
// The type of request is identified by typ argument, which is a "resource"
// in the ACME spec terms.
//
// A non-nil acct argument indicates whether the intention is to mutate data
// of the Account. Only Contact and Agreement of its fields are used
// in such cases.
func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Account) (*Account, error) {
req := struct {
Resource string `json:"resource"`
Contact []string `json:"contact,omitempty"`
Agreement string `json:"agreement,omitempty"`
}{
Resource: typ,
}
if acct != nil {
req.Contact = acct.Contact
req.Agreement = acct.AgreedTerms
}
res, err := postJWS(ctx, c.HTTPClient, c.Key, url, req)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode < 200 || res.StatusCode > 299 {
return nil, responseError(res)
}
var v struct {
Contact []string
Agreement string
Authorizations string
Certificates string
}
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, fmt.Errorf("acme: invalid response: %v", err)
}
var tos string
if v := linkHeader(res.Header, "terms-of-service"); len(v) > 0 {
tos = v[0]
}
var authz string
if v := linkHeader(res.Header, "next"); len(v) > 0 {
authz = v[0]
}
return &Account{
URI: res.Header.Get("Location"),
Contact: v.Contact,
AgreedTerms: v.Agreement,
CurrentTerms: tos,
Authz: authz,
Authorizations: v.Authorizations,
Certificates: v.Certificates,
}, nil
}
func responseCert(ctx context.Context, client *http.Client, res *http.Response, bundle bool) ([][]byte, error) {
b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
if err != nil {
return nil, fmt.Errorf("acme: response stream: %v", err)
}
if len(b) > maxCertSize {
return nil, errors.New("acme: certificate is too big")
}
cert := [][]byte{b}
if !bundle {
return cert, nil
}
// Append CA chain cert(s).
// At least one is required according to the spec:
// https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-6.3.1
up := linkHeader(res.Header, "up")
if len(up) == 0 {
return nil, errors.New("acme: rel=up link not found")
}
if len(up) > maxChainLen {
return nil, errors.New("acme: rel=up link is too large")
}
for _, url := range up {
cc, err := chainCert(ctx, client, url, 0)
if err != nil {
return nil, err
}
cert = append(cert, cc...)
}
return cert, nil
}
// responseError creates an error of Error type from resp.
func responseError(resp *http.Response) error {
// don't care if ReadAll returns an error:
// json.Unmarshal will fail in that case anyway
b, _ := ioutil.ReadAll(resp.Body)
e := struct {
Status int
Type string
Detail string
}{
Status: resp.StatusCode,
}
if err := json.Unmarshal(b, &e); err != nil {
// this is not a regular error response:
// populate detail with anything we received,
// e.Status will already contain HTTP response code value
e.Detail = string(b)
if e.Detail == "" {
e.Detail = resp.Status
}
}
return &Error{
StatusCode: e.Status,
ProblemType: e.Type,
Detail: e.Detail,
Header: resp.Header,
}
}
// chainCert fetches CA certificate chain recursively by following "up" links.
// Each recursive call increments the depth by 1, resulting in an error
// if the recursion level reaches maxChainLen.
//
// First chainCert call starts with depth of 0.
func chainCert(ctx context.Context, client *http.Client, url string, depth int) ([][]byte, error) {
if depth >= maxChainLen {
return nil, errors.New("acme: certificate chain is too deep")
}
res, err := ctxhttp.Get(ctx, client, url)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, responseError(res)
}
b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
if err != nil {
return nil, err
}
if len(b) > maxCertSize {
return nil, errors.New("acme: certificate is too big")
}
chain := [][]byte{b}
uplink := linkHeader(res.Header, "up")
if len(uplink) > maxChainLen {
return nil, errors.New("acme: certificate chain is too large")
}
for _, up := range uplink {
cc, err := chainCert(ctx, client, up, depth+1)
if err != nil {
return nil, err
}
chain = append(chain, cc...)
}
return chain, nil
}
// postJWS signs the body with the given key and POSTs it to the provided url.
// The body argument must be JSON-serializable.
func postJWS(ctx context.Context, client *http.Client, key crypto.Signer, url string, body interface{}) (*http.Response, error) {
nonce, err := fetchNonce(ctx, client, url)
if err != nil {
return nil, err
}
b, err := jwsEncodeJSON(body, key, nonce)
if err != nil {
return nil, err
}
return ctxhttp.Post(ctx, client, url, "application/jose+json", bytes.NewReader(b))
}
func fetchNonce(ctx context.Context, client *http.Client, url string) (string, error) {
resp, err := ctxhttp.Head(ctx, client, url)
if err != nil {
return "", nil
}
defer resp.Body.Close()
enc := resp.Header.Get("replay-nonce")
if enc == "" {
return "", errors.New("acme: nonce not found")
}
return enc, nil
}
// linkHeader returns URI-Reference values of all Link headers
// with relation-type rel.
// See https://tools.ietf.org/html/rfc5988#section-5 for details.
func linkHeader(h http.Header, rel string) []string {
var links []string
for _, v := range h["Link"] {
parts := strings.Split(v, ";")
for _, p := range parts {
p = strings.TrimSpace(p)
if !strings.HasPrefix(p, "rel=") {
continue
}
if v := strings.Trim(p[4:], `"`); v == rel {
links = append(links, strings.Trim(parts[0], "<>"))
}
}
}
return links
}
// retryAfter parses a Retry-After HTTP header value,
// trying to convert v into an int (seconds) or use http.ParseTime otherwise.
// It returns d if v cannot be parsed.
func retryAfter(v string, d time.Duration) time.Duration {
if i, err := strconv.Atoi(v); err == nil {
return time.Duration(i) * time.Second
}
t, err := http.ParseTime(v)
if err != nil {
return d
}
return t.Sub(timeNow())
}
// backoff computes a duration after which an n+1 retry iteration should occur
// using truncated exponential backoff algorithm.
//
// The n argument is always bounded between 0 and 30.
// The max argument defines upper bound for the returned value.
func backoff(n int, max time.Duration) time.Duration {
if n < 0 {
n = 0
}
if n > 30 {
n = 30
}
var d time.Duration
if x, err := rand.Int(rand.Reader, big.NewInt(1000)); err == nil {
d = time.Duration(x.Int64()) * time.Millisecond
}
d += time.Duration(1<<uint(n)) * time.Second
if d > max {
return max
}
return d
}
// keyAuth generates a key authorization string for a given token.
func keyAuth(pub crypto.PublicKey, token string) (string, error) {
th, err := JWKThumbprint(pub)
if err != nil {
return "", err
}
return fmt.Sprintf("%s.%s", token, th), nil
}
// tlsChallengeCert creates a temporary certificate for TLS-SNI challenges
// with the given SANs and auto-generated public/private key pair.
// To create a cert with a custom key pair, specify WithKey option.
func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
var (
key crypto.Signer
tmpl *x509.Certificate
)
for _, o := range opt {
switch o := o.(type) {
case *certOptKey:
if key != nil {
return tls.Certificate{}, errors.New("acme: duplicate key option")
}
key = o.key
case *certOptTemplate:
var t = *(*x509.Certificate)(o) // shallow copy is ok
tmpl = &t
default:
// package's fault, if we let this happen:
panic(fmt.Sprintf("unsupported option type %T", o))
}
}
if key == nil {
var err error
if key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader); err != nil {
return tls.Certificate{}, err
}
}
if tmpl == nil {
tmpl = &x509.Certificate{
SerialNumber: big.NewInt(1),
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
BasicConstraintsValid: true,
KeyUsage: x509.KeyUsageKeyEncipherment,
}
}
tmpl.DNSNames = san
der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, key.Public(), key)
if err != nil {
return tls.Certificate{}, err
}
return tls.Certificate{
Certificate: [][]byte{der},
PrivateKey: key,
}, nil
}
// encodePEM returns b encoded as PEM with block of type typ.
func encodePEM(typ string, b []byte) []byte {
pb := &pem.Block{Type: typ, Bytes: b}
return pem.EncodeToMemory(pb)
}
// timeNow is useful for testing for fixed current time.
var timeNow = time.Now

Просмотреть файл

@@ -5,7 +5,10 @@
package acme
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/base64"
@@ -16,6 +19,7 @@ import (
"net/http"
"net/http/httptest"
"reflect"
"sort"
"strings"
"testing"
"time"
@@ -58,21 +62,22 @@ func TestDiscover(t *testing.T) {
}`, reg, authz, cert, revoke)
}))
defer ts.Close()
ep, err := (&Client{}).Discover(ts.URL)
c := Client{DirectoryURL: ts.URL}
dir, err := c.Discover(context.Background())
if err != nil {
t.Fatal(err)
}
if ep.RegURL != reg {
t.Errorf("RegURL = %q; want %q", ep.RegURL, reg)
if dir.RegURL != reg {
t.Errorf("dir.RegURL = %q; want %q", dir.RegURL, reg)
}
if ep.AuthzURL != authz {
t.Errorf("authzURL = %q; want %q", ep.AuthzURL, authz)
if dir.AuthzURL != authz {
t.Errorf("dir.AuthzURL = %q; want %q", dir.AuthzURL, authz)
}
if ep.CertURL != cert {
t.Errorf("certURL = %q; want %q", ep.CertURL, cert)
if dir.CertURL != cert {
t.Errorf("dir.CertURL = %q; want %q", dir.CertURL, cert)
}
if ep.RevokeURL != revoke {
t.Errorf("revokeURL = %q; want %q", ep.RevokeURL, revoke)
if dir.RevokeURL != revoke {
t.Errorf("dir.RevokeURL = %q; want %q", dir.RevokeURL, revoke)
}
}
@@ -109,17 +114,22 @@ func TestRegister(t *testing.T) {
w.Header().Add("Link", `<https://ca.tld/acme/terms>;rel="terms-of-service"`)
w.WriteHeader(http.StatusCreated)
b, _ := json.Marshal(contacts)
fmt.Fprintf(w, `{
"key":%q,
"contact":%s
}`, testKeyThumbprint, b)
fmt.Fprintf(w, `{"contact": %s}`, b)
}))
defer ts.Close()
c := Client{Key: testKey}
prompt := func(url string) bool {
const terms = "https://ca.tld/acme/terms"
if url != terms {
t.Errorf("prompt url = %q; want %q", url, terms)
}
return false
}
c := Client{Key: testKeyEC, dir: &Directory{RegURL: ts.URL}}
a := &Account{Contact: contacts}
var err error
if a, err = c.Register(ts.URL, a); err != nil {
if a, err = c.Register(context.Background(), a, prompt); err != nil {
t.Fatal(err)
}
if a.URI != "https://ca.tld/acme/reg/1" {
@@ -172,18 +182,14 @@ func TestUpdateReg(t *testing.T) {
w.Header().Add("Link", fmt.Sprintf(`<%s>;rel="terms-of-service"`, terms))
w.WriteHeader(http.StatusOK)
b, _ := json.Marshal(contacts)
fmt.Fprintf(w, `{
"key":%q,
"contact":%s,
"agreement":%q
}`, testKeyThumbprint, b, terms)
fmt.Fprintf(w, `{"contact":%s, "agreement":%q}`, b, terms)
}))
defer ts.Close()
c := Client{Key: testKey}
a := &Account{Contact: contacts, AgreedTerms: terms}
c := Client{Key: testKeyEC}
a := &Account{URI: ts.URL, Contact: contacts, AgreedTerms: terms}
var err error
if a, err = c.UpdateReg(ts.URL, a); err != nil {
if a, err = c.UpdateReg(context.Background(), a); err != nil {
t.Fatal(err)
}
if a.Authz != "https://ca.tld/acme/new-authz" {
@@ -195,6 +201,9 @@ func TestUpdateReg(t *testing.T) {
if a.CurrentTerms != terms {
t.Errorf("a.CurrentTerms = %q; want %q", a.CurrentTerms, terms)
}
if a.URI != ts.URL {
t.Errorf("a.URI = %q; want %q", a.URI, ts.URL)
}
}
func TestGetReg(t *testing.T) {
@@ -234,16 +243,12 @@ func TestGetReg(t *testing.T) {
w.Header().Add("Link", fmt.Sprintf(`<%s>;rel="terms-of-service"`, newTerms))
w.WriteHeader(http.StatusOK)
b, _ := json.Marshal(contacts)
fmt.Fprintf(w, `{
"key":%q,
"contact":%s,
"agreement":%q
}`, testKeyThumbprint, b, terms)
fmt.Fprintf(w, `{"contact":%s, "agreement":%q}`, b, terms)
}))
defer ts.Close()
c := Client{Key: testKey}
a, err := c.GetReg(ts.URL)
c := Client{Key: testKeyEC}
a, err := c.GetReg(context.Background(), ts.URL)
if err != nil {
t.Fatal(err)
}
@@ -256,6 +261,9 @@ func TestGetReg(t *testing.T) {
if a.CurrentTerms != newTerms {
t.Errorf("a.CurrentTerms = %q; want %q", a.CurrentTerms, newTerms)
}
if a.URI != ts.URL {
t.Errorf("a.URI = %q; want %q", a.URI, ts.URL)
}
}
func TestAuthorize(t *testing.T) {
@@ -311,8 +319,8 @@ func TestAuthorize(t *testing.T) {
}))
defer ts.Close()
cl := Client{Key: testKey}
auth, err := cl.Authorize(ts.URL, "example.com")
cl := Client{Key: testKeyEC, dir: &Directory{AuthzURL: ts.URL}}
auth, err := cl.Authorize(context.Background(), "example.com")
if err != nil {
t.Fatal(err)
}
@@ -362,7 +370,24 @@ func TestAuthorize(t *testing.T) {
}
}
func TestPollAuthz(t *testing.T) {
func TestAuthorizeValid(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "HEAD" {
w.Header().Set("replay-nonce", "nonce")
return
}
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`{"status":"valid"}`))
}))
defer ts.Close()
client := Client{Key: testKey, dir: &Directory{AuthzURL: ts.URL}}
_, err := client.Authorize(context.Background(), "example.com")
if err != nil {
t.Errorf("err = %v", err)
}
}
func TestGetAuthorization(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
t.Errorf("r.Method = %q; want GET", r.Method)
@@ -390,8 +415,8 @@ func TestPollAuthz(t *testing.T) {
}))
defer ts.Close()
cl := Client{Key: testKey}
auth, err := cl.GetAuthz(ts.URL)
cl := Client{Key: testKeyEC}
auth, err := cl.GetAuthorization(context.Background(), ts.URL)
if err != nil {
t.Fatal(err)
}
@@ -438,6 +463,129 @@ func TestPollAuthz(t *testing.T) {
}
}
func TestWaitAuthorization(t *testing.T) {
var count int
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
count++
w.Header().Set("retry-after", "0")
if count > 1 {
fmt.Fprintf(w, `{"status":"valid"}`)
return
}
fmt.Fprintf(w, `{"status":"pending"}`)
}))
defer ts.Close()
type res struct {
authz *Authorization
err error
}
done := make(chan res)
defer close(done)
go func() {
var client Client
a, err := client.WaitAuthorization(context.Background(), ts.URL)
done <- res{a, err}
}()
select {
case <-time.After(5 * time.Second):
t.Fatal("WaitAuthz took too long to return")
case res := <-done:
if res.err != nil {
t.Fatalf("res.err = %v", res.err)
}
if res.authz == nil {
t.Fatal("res.authz is nil")
}
}
}
func TestWaitAuthorizationInvalid(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `{"status":"invalid"}`)
}))
defer ts.Close()
res := make(chan error)
defer close(res)
go func() {
var client Client
_, err := client.WaitAuthorization(context.Background(), ts.URL)
res <- err
}()
select {
case <-time.After(3 * time.Second):
t.Fatal("WaitAuthz took too long to return")
case err := <-res:
if err == nil {
t.Error("err is nil")
}
}
}
func TestWaitAuthorizationCancel(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("retry-after", "60")
fmt.Fprintf(w, `{"status":"pending"}`)
}))
defer ts.Close()
res := make(chan error)
defer close(res)
go func() {
var client Client
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
defer cancel()
_, err := client.WaitAuthorization(ctx, ts.URL)
res <- err
}()
select {
case <-time.After(time.Second):
t.Fatal("WaitAuthz took too long to return")
case err := <-res:
if err == nil {
t.Error("err is nil")
}
}
}
func TestRevokeAuthorization(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "HEAD" {
w.Header().Set("replay-nonce", "nonce")
return
}
switch r.URL.Path {
case "/1":
var req struct {
Resource string
Delete bool
}
decodeJWSRequest(t, &req, r)
if req.Resource != "authz" {
t.Errorf("req.Resource = %q; want authz", req.Resource)
}
if !req.Delete {
t.Errorf("req.Delete is false")
}
case "/2":
w.WriteHeader(http.StatusInternalServerError)
}
}))
defer ts.Close()
client := &Client{Key: testKey}
ctx := context.Background()
if err := client.RevokeAuthorization(ctx, ts.URL+"/1"); err != nil {
t.Errorf("err = %v", err)
}
if client.RevokeAuthorization(ctx, ts.URL+"/2") == nil {
t.Error("nil error")
}
}
func TestPollChallenge(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
@@ -453,8 +601,8 @@ func TestPollChallenge(t *testing.T) {
}))
defer ts.Close()
cl := Client{Key: testKey}
chall, err := cl.GetChallenge(ts.URL)
cl := Client{Key: testKeyEC}
chall, err := cl.GetChallenge(context.Background(), ts.URL)
if err != nil {
t.Fatal(err)
}
@@ -497,7 +645,7 @@ func TestAcceptChallenge(t *testing.T) {
if j.Type != "http-01" {
t.Errorf(`type = %q; want "http-01"`, j.Type)
}
keyAuth := "token1." + testKeyThumbprint
keyAuth := "token1." + testKeyECThumbprint
if j.Auth != keyAuth {
t.Errorf(`keyAuthorization = %q; want %q`, j.Auth, keyAuth)
}
@@ -514,8 +662,8 @@ func TestAcceptChallenge(t *testing.T) {
}))
defer ts.Close()
cl := Client{Key: testKey}
c, err := cl.Accept(&Challenge{
cl := Client{Key: testKeyEC}
c, err := cl.Accept(context.Background(), &Challenge{
URI: ts.URL,
Token: "token1",
Type: "http-01",
@@ -582,7 +730,7 @@ func TestNewCert(t *testing.T) {
BasicConstraintsValid: true,
}
sampleCert, err := x509.CreateCertificate(rand.Reader, &template, &template, &testKey.PublicKey, testKey)
sampleCert, err := x509.CreateCertificate(rand.Reader, &template, &template, &testKeyEC.PublicKey, testKeyEC)
if err != nil {
t.Fatalf("Error creating certificate: %v", err)
}
@@ -600,13 +748,13 @@ func TestNewCert(t *testing.T) {
Organization: []string{"goacme"},
},
}
csrb, err := x509.CreateCertificateRequest(rand.Reader, &csr, testKey)
csrb, err := x509.CreateCertificateRequest(rand.Reader, &csr, testKeyEC)
if err != nil {
t.Fatal(err)
}
c := Client{Key: testKey}
cert, certURL, err := c.CreateCert(context.Background(), ts.URL, csrb, notAfter.Sub(notBefore), false)
c := Client{Key: testKeyEC, dir: &Directory{CertURL: ts.URL}}
cert, certURL, err := c.CreateCert(context.Background(), csrb, notAfter.Sub(notBefore), false)
if err != nil {
t.Fatal(err)
}
@@ -619,15 +767,22 @@ func TestNewCert(t *testing.T) {
}
func TestFetchCert(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte{1})
var count byte
var ts *httptest.Server
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
count++
if count < 3 {
up := fmt.Sprintf("<%s>;rel=up", ts.URL)
w.Header().Set("link", up)
}
w.Write([]byte{count})
}))
defer ts.Close()
res, err := (&Client{}).FetchCert(context.Background(), ts.URL, false)
res, err := (&Client{}).FetchCert(context.Background(), ts.URL, true)
if err != nil {
t.Fatalf("FetchCert: %v", err)
}
cert := [][]byte{{1}}
cert := [][]byte{{1}, {2}, {3}}
if !reflect.DeepEqual(res, cert) {
t.Errorf("res = %v; want %v", res, cert)
}
@@ -675,6 +830,88 @@ func TestFetchCertCancel(t *testing.T) {
}
}
func TestFetchCertDepth(t *testing.T) {
var count byte
var ts *httptest.Server
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
count++
if count > maxChainLen+1 {
t.Errorf("count = %d; want at most %d", count, maxChainLen+1)
w.WriteHeader(http.StatusInternalServerError)
}
w.Header().Set("link", fmt.Sprintf("<%s>;rel=up", ts.URL))
w.Write([]byte{count})
}))
defer ts.Close()
_, err := (&Client{}).FetchCert(context.Background(), ts.URL, true)
if err == nil {
t.Errorf("err is nil")
}
}
func TestFetchCertBreadth(t *testing.T) {
var ts *httptest.Server
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
for i := 0; i < maxChainLen+1; i++ {
w.Header().Add("link", fmt.Sprintf("<%s>;rel=up", ts.URL))
}
w.Write([]byte{1})
}))
defer ts.Close()
_, err := (&Client{}).FetchCert(context.Background(), ts.URL, true)
if err == nil {
t.Errorf("err is nil")
}
}
func TestFetchCertSize(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
b := bytes.Repeat([]byte{1}, maxCertSize+1)
w.Write(b)
}))
defer ts.Close()
_, err := (&Client{}).FetchCert(context.Background(), ts.URL, false)
if err == nil {
t.Errorf("err is nil")
}
}
func TestRevokeCert(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "HEAD" {
w.Header().Set("replay-nonce", "nonce")
return
}
var req struct {
Resource string
Certificate string
Reason int
}
decodeJWSRequest(t, &req, r)
if req.Resource != "revoke-cert" {
t.Errorf("req.Resource = %q; want revoke-cert", req.Resource)
}
if req.Reason != 1 {
t.Errorf("req.Reason = %d; want 1", req.Reason)
}
// echo -n cert | base64 | tr -d '=' | tr '/+' '_-'
cert := "Y2VydA"
if req.Certificate != cert {
t.Errorf("req.Certificate = %q; want %q", req.Certificate, cert)
}
}))
defer ts.Close()
client := &Client{
Key: testKeyEC,
dir: &Directory{RevokeURL: ts.URL},
}
ctx := context.Background()
if err := client.RevokeCert(ctx, nil, []byte("cert"), CRLReasonKeyCompromise); err != nil {
t.Fatal(err)
}
}
func TestFetchNonce(t *testing.T) {
tests := []struct {
code int
@@ -695,7 +932,7 @@ func TestFetchNonce(t *testing.T) {
defer ts.Close()
for ; i < len(tests); i++ {
test := tests[i]
n, err := fetchNonce(http.DefaultClient, ts.URL)
n, err := fetchNonce(context.Background(), http.DefaultClient, ts.URL)
if n != test.nonce {
t.Errorf("%d: n=%q; want %q", i, n, test.nonce)
}
@@ -713,16 +950,20 @@ func TestLinkHeader(t *testing.T) {
`<https://example.com/acme/new-authz>;rel="next"`,
`<https://example.com/acme/recover-reg>; rel=recover`,
`<https://example.com/acme/terms>; foo=bar; rel="terms-of-service"`,
`<dup>;rel="next"`,
}}
tests := []struct{ in, out string }{
{"next", "https://example.com/acme/new-authz"},
{"recover", "https://example.com/acme/recover-reg"},
{"terms-of-service", "https://example.com/acme/terms"},
{"empty", ""},
tests := []struct {
rel string
out []string
}{
{"next", []string{"https://example.com/acme/new-authz", "dup"}},
{"recover", []string{"https://example.com/acme/recover-reg"}},
{"terms-of-service", []string{"https://example.com/acme/terms"}},
{"empty", nil},
}
for i, test := range tests {
if v := linkHeader(h, test.in); v != test.out {
t.Errorf("%d: parseLinkHeader(%q): %q; want %q", i, test.in, v, test.out)
if v := linkHeader(h, test.rel); !reflect.DeepEqual(v, test.out) {
t.Errorf("%d: linkHeader(%q): %v; want %v", i, test.rel, v, test.out)
}
}
}
@@ -757,3 +998,188 @@ func TestErrorResponse(t *testing.T) {
t.Errorf("v.Header = %+v; want %+v", v.Header, res.Header)
}
}
func TestTLSSNI01ChallengeCert(t *testing.T) {
const (
token = "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA"
// echo -n <token.testKeyECThumbprint> | shasum -a 256
san = "dbbd5eefe7b4d06eb9d1d9f5acb4c7cd.a27d320e4b30332f0b6cb441734ad7b0.acme.invalid"
)
client := &Client{Key: testKeyEC}
tlscert, name, err := client.TLSSNI01ChallengeCert(token)
if err != nil {
t.Fatal(err)
}
if n := len(tlscert.Certificate); n != 1 {
t.Fatalf("len(tlscert.Certificate) = %d; want 1", n)
}
cert, err := x509.ParseCertificate(tlscert.Certificate[0])
if err != nil {
t.Fatal(err)
}
if len(cert.DNSNames) != 1 || cert.DNSNames[0] != san {
t.Fatalf("cert.DNSNames = %v; want %q", cert.DNSNames, san)
}
if cert.DNSNames[0] != name {
t.Errorf("cert.DNSNames[0] != name: %q vs %q", cert.DNSNames[0], name)
}
}
func TestTLSSNI02ChallengeCert(t *testing.T) {
const (
token = "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA"
// echo -n evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA | shasum -a 256
sanA = "7ea0aaa69214e71e02cebb18bb867736.09b730209baabf60e43d4999979ff139.token.acme.invalid"
// echo -n <token.testKeyECThumbprint> | shasum -a 256
sanB = "dbbd5eefe7b4d06eb9d1d9f5acb4c7cd.a27d320e4b30332f0b6cb441734ad7b0.ka.acme.invalid"
)
client := &Client{Key: testKeyEC}
tlscert, name, err := client.TLSSNI02ChallengeCert(token)
if err != nil {
t.Fatal(err)
}
if n := len(tlscert.Certificate); n != 1 {
t.Fatalf("len(tlscert.Certificate) = %d; want 1", n)
}
cert, err := x509.ParseCertificate(tlscert.Certificate[0])
if err != nil {
t.Fatal(err)
}
names := []string{sanA, sanB}
if !reflect.DeepEqual(cert.DNSNames, names) {
t.Fatalf("cert.DNSNames = %v;\nwant %v", cert.DNSNames, names)
}
sort.Strings(cert.DNSNames)
i := sort.SearchStrings(cert.DNSNames, name)
if i >= len(cert.DNSNames) || cert.DNSNames[i] != name {
t.Errorf("%v doesn't have %q", cert.DNSNames, name)
}
}
func TestTLSChallengeCertOpt(t *testing.T) {
key, err := rsa.GenerateKey(rand.Reader, 512)
if err != nil {
t.Fatal(err)
}
tmpl := &x509.Certificate{
SerialNumber: big.NewInt(2),
Subject: pkix.Name{Organization: []string{"Test"}},
DNSNames: []string{"should-be-overwritten"},
}
opts := []CertOption{WithKey(key), WithTemplate(tmpl)}
client := &Client{Key: testKeyEC}
cert1, _, err := client.TLSSNI01ChallengeCert("token", opts...)
if err != nil {
t.Fatal(err)
}
cert2, _, err := client.TLSSNI02ChallengeCert("token", opts...)
if err != nil {
t.Fatal(err)
}
for i, tlscert := range []tls.Certificate{cert1, cert2} {
// verify generated cert private key
tlskey, ok := tlscert.PrivateKey.(*rsa.PrivateKey)
if !ok {
t.Errorf("%d: tlscert.PrivateKey is %T; want *rsa.PrivateKey", i, tlscert.PrivateKey)
continue
}
if tlskey.D.Cmp(key.D) != 0 {
t.Errorf("%d: tlskey.D = %v; want %v", i, tlskey.D, key.D)
}
// verify generated cert public key
x509Cert, err := x509.ParseCertificate(tlscert.Certificate[0])
if err != nil {
t.Errorf("%d: %v", i, err)
continue
}
tlspub, ok := x509Cert.PublicKey.(*rsa.PublicKey)
if !ok {
t.Errorf("%d: x509Cert.PublicKey is %T; want *rsa.PublicKey", i, x509Cert.PublicKey)
continue
}
if tlspub.N.Cmp(key.N) != 0 {
t.Errorf("%d: tlspub.N = %v; want %v", i, tlspub.N, key.N)
}
// verify template option
sn := big.NewInt(2)
if x509Cert.SerialNumber.Cmp(sn) != 0 {
t.Errorf("%d: SerialNumber = %v; want %v", i, x509Cert.SerialNumber, sn)
}
org := []string{"Test"}
if !reflect.DeepEqual(x509Cert.Subject.Organization, org) {
t.Errorf("%d: Subject.Organization = %+v; want %+v", i, x509Cert.Subject.Organization, org)
}
for _, v := range x509Cert.DNSNames {
if !strings.HasSuffix(v, ".acme.invalid") {
t.Errorf("%d: invalid DNSNames element: %q", i, v)
}
}
}
}
func TestHTTP01Challenge(t *testing.T) {
const (
token = "xxx"
// thumbprint is precomputed for testKeyEC in jws_test.go
value = token + "." + testKeyECThumbprint
urlpath = "/.well-known/acme-challenge/" + token
)
client := &Client{Key: testKeyEC}
val, err := client.HTTP01ChallengeResponse(token)
if err != nil {
t.Fatal(err)
}
if val != value {
t.Errorf("val = %q; want %q", val, value)
}
if path := client.HTTP01ChallengePath(token); path != urlpath {
t.Errorf("path = %q; want %q", path, urlpath)
}
}
func TestDNS01ChallengeRecord(t *testing.T) {
// echo -n xxx.<testKeyECThumbprint> | \
// openssl dgst -binary -sha256 | \
// base64 | tr -d '=' | tr '/+' '_-'
const value = "8DERMexQ5VcdJ_prpPiA0mVdp7imgbCgjsG4SqqNMIo"
client := &Client{Key: testKeyEC}
val, err := client.DNS01ChallengeRecord("xxx")
if err != nil {
t.Fatal(err)
}
if val != value {
t.Errorf("val = %q; want %q", val, value)
}
}
func TestBackoff(t *testing.T) {
tt := []struct{ min, max time.Duration }{
{time.Second, 2 * time.Second},
{2 * time.Second, 3 * time.Second},
{4 * time.Second, 5 * time.Second},
{8 * time.Second, 9 * time.Second},
}
for i, test := range tt {
d := backoff(i, time.Minute)
if d < test.min || test.max < d {
t.Errorf("%d: d = %v; want between %v and %v", i, d, test.min, test.max)
}
}
min, max := time.Second, 2*time.Second
if d := backoff(-1, time.Minute); d < min || max < d {
t.Errorf("d = %v; want between %v and %v", d, min, max)
}
bound := 10 * time.Second
if d := backoff(100, bound); d != bound {
t.Errorf("d = %v; want %v", d, bound)
}
}

776
vendor/golang.org/x/crypto/acme/autocert/autocert.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,776 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package autocert provides automatic access to certificates from Let's Encrypt
// and any other ACME-based CA.
//
// This package is a work in progress and makes no API stability promises.
package autocert
import (
"bytes"
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"errors"
"fmt"
"io"
mathrand "math/rand"
"net/http"
"strconv"
"strings"
"sync"
"time"
"golang.org/x/crypto/acme"
"golang.org/x/net/context"
)
// pseudoRand is safe for concurrent use.
var pseudoRand *lockedMathRand
func init() {
src := mathrand.NewSource(timeNow().UnixNano())
pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
}
// AcceptTOS always returns true to indicate the acceptance of a CA Terms of Service
// during account registration.
func AcceptTOS(tosURL string) bool { return true }
// HostPolicy specifies which host names the Manager is allowed to respond to.
// It returns a non-nil error if the host should be rejected.
// The returned error is accessible via tls.Conn.Handshake and its callers.
// See Manager's HostPolicy field and GetCertificate method docs for more details.
type HostPolicy func(ctx context.Context, host string) error
// HostWhitelist returns a policy where only the specified host names are allowed.
// Only exact matches are currently supported. Subdomains, regexp or wildcard
// will not match.
func HostWhitelist(hosts ...string) HostPolicy {
whitelist := make(map[string]bool, len(hosts))
for _, h := range hosts {
whitelist[h] = true
}
return func(_ context.Context, host string) error {
if !whitelist[host] {
return errors.New("acme/autocert: host not configured")
}
return nil
}
}
// defaultHostPolicy is used when Manager.HostPolicy is not set.
func defaultHostPolicy(context.Context, string) error {
return nil
}
// Manager is a stateful certificate manager built on top of acme.Client.
// It obtains and refreshes certificates automatically,
// as well as providing them to a TLS server via tls.Config.
//
// A simple usage example:
//
// m := autocert.Manager{
// Prompt: autocert.AcceptTOS,
// HostPolicy: autocert.HostWhitelist("example.org"),
// }
// s := &http.Server{
// Addr: ":https",
// TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
// }
// s.ListenAndServeTLS("", "")
//
// To preserve issued certificates and improve overall performance,
// use a cache implementation of Cache. For instance, DirCache.
type Manager struct {
// Prompt specifies a callback function to conditionally accept a CA's Terms of Service (TOS).
// The registration may require the caller to agree to the CA's TOS.
// If so, Manager calls Prompt with a TOS URL provided by the CA. Prompt should report
// whether the caller agrees to the terms.
//
// To always accept the terms, the callers can use AcceptTOS.
Prompt func(tosURL string) bool
// Cache optionally stores and retrieves previously-obtained certificates.
// If nil, certs will only be cached for the lifetime of the Manager.
//
// Manager passes the Cache certificates data encoded in PEM, with private/public
// parts combined in a single Cache.Put call, private key first.
Cache Cache
// HostPolicy controls which domains the Manager will attempt
// to retrieve new certificates for. It does not affect cached certs.
//
// If non-nil, HostPolicy is called before requesting a new cert.
// If nil, all hosts are currently allowed. This is not recommended,
// as it opens a potential attack where clients connect to a server
// by IP address and pretend to be asking for an incorrect host name.
// Manager will attempt to obtain a certificate for that host, incorrectly,
// eventually reaching the CA's rate limit for certificate requests
// and making it impossible to obtain actual certificates.
//
// See GetCertificate for more details.
HostPolicy HostPolicy
// RenewBefore optionally specifies how early certificates should
// be renewed before they expire.
//
// If zero, they're renewed 1 week before expiration.
RenewBefore time.Duration
// Client is used to perform low-level operations, such as account registration
// and requesting new certificates.
// If Client is nil, a zero-value acme.Client is used with acme.LetsEncryptURL
// directory endpoint and a newly-generated ECDSA P-256 key.
//
// Mutating the field after the first call of GetCertificate method will have no effect.
Client *acme.Client
// Email optionally specifies a contact email address.
// This is used by CAs, such as Let's Encrypt, to notify about problems
// with issued certificates.
//
// If the Client's account key is already registered, Email is not used.
Email string
clientMu sync.Mutex
client *acme.Client // initialized by acmeClient method
stateMu sync.Mutex
state map[string]*certState // keyed by domain name
// tokenCert is keyed by token domain name, which matches server name
// of ClientHello. Keys always have ".acme.invalid" suffix.
tokenCertMu sync.RWMutex
tokenCert map[string]*tls.Certificate
// renewal tracks the set of domains currently running renewal timers.
// It is keyed by domain name.
renewalMu sync.Mutex
renewal map[string]*domainRenewal
}
// GetCertificate implements the tls.Config.GetCertificate hook.
// It provides a TLS certificate for hello.ServerName host, including answering
// *.acme.invalid (TLS-SNI) challenges. All other fields of hello are ignored.
//
// If m.HostPolicy is non-nil, GetCertificate calls the policy before requesting
// a new cert. A non-nil error returned from m.HostPolicy halts TLS negotiation.
// The error is propagated back to the caller of GetCertificate and is user-visible.
// This does not affect cached certs. See HostPolicy field description for more details.
func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
name := hello.ServerName
if name == "" {
return nil, errors.New("acme/autocert: missing server name")
}
// check whether this is a token cert requested for TLS-SNI challenge
if strings.HasSuffix(name, ".acme.invalid") {
m.tokenCertMu.RLock()
defer m.tokenCertMu.RUnlock()
if cert := m.tokenCert[name]; cert != nil {
return cert, nil
}
if cert, err := m.cacheGet(name); err == nil {
return cert, nil
}
// TODO: cache error results?
return nil, fmt.Errorf("acme/autocert: no token cert for %q", name)
}
// regular domain
cert, err := m.cert(name)
if err == nil {
return cert, nil
}
if err != ErrCacheMiss {
return nil, err
}
// first-time
ctx := context.Background() // TODO: use a deadline?
if err := m.hostPolicy()(ctx, name); err != nil {
return nil, err
}
cert, err = m.createCert(ctx, name)
if err != nil {
return nil, err
}
m.cachePut(name, cert)
return cert, nil
}
// cert returns an existing certificate either from m.state or cache.
// If a certificate is found in cache but not in m.state, the latter will be filled
// with the cached value.
func (m *Manager) cert(name string) (*tls.Certificate, error) {
m.stateMu.Lock()
if s, ok := m.state[name]; ok {
m.stateMu.Unlock()
s.RLock()
defer s.RUnlock()
return s.tlscert()
}
defer m.stateMu.Unlock()
cert, err := m.cacheGet(name)
if err != nil {
return nil, err
}
signer, ok := cert.PrivateKey.(crypto.Signer)
if !ok {
return nil, errors.New("acme/autocert: private key cannot sign")
}
if m.state == nil {
m.state = make(map[string]*certState)
}
s := &certState{
key: signer,
cert: cert.Certificate,
leaf: cert.Leaf,
}
m.state[name] = s
go m.renew(name, s.key, s.leaf.NotAfter)
return cert, nil
}
// cacheGet always returns a valid certificate, or an error otherwise.
func (m *Manager) cacheGet(domain string) (*tls.Certificate, error) {
if m.Cache == nil {
return nil, ErrCacheMiss
}
// TODO: might want to define a cache timeout on m
ctx := context.Background()
data, err := m.Cache.Get(ctx, domain)
if err != nil {
return nil, err
}
// private
priv, pub := pem.Decode(data)
if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
return nil, errors.New("acme/autocert: no private key found in cache")
}
privKey, err := parsePrivateKey(priv.Bytes)
if err != nil {
return nil, err
}
// public
var pubDER [][]byte
for len(pub) > 0 {
var b *pem.Block
b, pub = pem.Decode(pub)
if b == nil {
break
}
pubDER = append(pubDER, b.Bytes)
}
if len(pub) > 0 {
return nil, errors.New("acme/autocert: invalid public key")
}
// verify and create TLS cert
leaf, err := validCert(domain, pubDER, privKey)
if err != nil {
return nil, err
}
tlscert := &tls.Certificate{
Certificate: pubDER,
PrivateKey: privKey,
Leaf: leaf,
}
return tlscert, nil
}
func (m *Manager) cachePut(domain string, tlscert *tls.Certificate) error {
if m.Cache == nil {
return nil
}
// contains PEM-encoded data
var buf bytes.Buffer
// private
switch key := tlscert.PrivateKey.(type) {
case *ecdsa.PrivateKey:
if err := encodeECDSAKey(&buf, key); err != nil {
return err
}
case *rsa.PrivateKey:
b := x509.MarshalPKCS1PrivateKey(key)
pb := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: b}
if err := pem.Encode(&buf, pb); err != nil {
return err
}
default:
return errors.New("acme/autocert: unknown private key type")
}
// public
for _, b := range tlscert.Certificate {
pb := &pem.Block{Type: "CERTIFICATE", Bytes: b}
if err := pem.Encode(&buf, pb); err != nil {
return err
}
}
// TODO: might want to define a cache timeout on m
ctx := context.Background()
return m.Cache.Put(ctx, domain, buf.Bytes())
}
func encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {
b, err := x509.MarshalECPrivateKey(key)
if err != nil {
return err
}
pb := &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
return pem.Encode(w, pb)
}
// createCert starts the domain ownership verification and returns a certificate
// for that domain upon success.
//
// If the domain is already being verified, it waits for the existing verification to complete.
// Either way, createCert blocks for the duration of the whole process.
func (m *Manager) createCert(ctx context.Context, domain string) (*tls.Certificate, error) {
// TODO: maybe rewrite this whole piece using sync.Once
state, err := m.certState(domain)
if err != nil {
return nil, err
}
// state may exist if another goroutine is already working on it
// in which case just wait for it to finish
if !state.locked {
state.RLock()
defer state.RUnlock()
return state.tlscert()
}
// We are the first; state is locked.
// Unblock the readers when domain ownership is verified
// and the we got the cert or the process failed.
defer state.Unlock()
state.locked = false
der, leaf, err := m.authorizedCert(ctx, state.key, domain)
if err != nil {
return nil, err
}
state.cert = der
state.leaf = leaf
go m.renew(domain, state.key, state.leaf.NotAfter)
return state.tlscert()
}
// certState returns a new or existing certState.
// If a new certState is returned, state.exist is false and the state is locked.
// The returned error is non-nil only in the case where a new state could not be created.
func (m *Manager) certState(domain string) (*certState, error) {
m.stateMu.Lock()
defer m.stateMu.Unlock()
if m.state == nil {
m.state = make(map[string]*certState)
}
// existing state
if state, ok := m.state[domain]; ok {
return state, nil
}
// new locked state
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return nil, err
}
state := &certState{
key: key,
locked: true,
}
state.Lock() // will be unlocked by m.certState caller
m.state[domain] = state
return state, nil
}
// authorizedCert starts domain ownership verification process and requests a new cert upon success.
// The key argument is the certificate private key.
func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain string) (der [][]byte, leaf *x509.Certificate, err error) {
// TODO: make m.verify retry or retry m.verify calls here
if err := m.verify(ctx, domain); err != nil {
return nil, nil, err
}
client, err := m.acmeClient(ctx)
if err != nil {
return nil, nil, err
}
csr, err := certRequest(key, domain)
if err != nil {
return nil, nil, err
}
der, _, err = client.CreateCert(ctx, csr, 0, true)
if err != nil {
return nil, nil, err
}
leaf, err = validCert(domain, der, key)
if err != nil {
return nil, nil, err
}
return der, leaf, nil
}
// verify starts a new identifier (domain) authorization flow.
// It prepares a challenge response and then blocks until the authorization
// is marked as "completed" by the CA (either succeeded or failed).
//
// verify returns nil iff the verification was successful.
func (m *Manager) verify(ctx context.Context, domain string) error {
client, err := m.acmeClient(ctx)
if err != nil {
return err
}
// start domain authorization and get the challenge
authz, err := client.Authorize(ctx, domain)
if err != nil {
return err
}
// maybe don't need to at all
if authz.Status == acme.StatusValid {
return nil
}
// pick a challenge: prefer tls-sni-02 over tls-sni-01
// TODO: consider authz.Combinations
var chal *acme.Challenge
for _, c := range authz.Challenges {
if c.Type == "tls-sni-02" {
chal = c
break
}
if c.Type == "tls-sni-01" {
chal = c
}
}
if chal == nil {
return errors.New("acme/autocert: no supported challenge type found")
}
// create a token cert for the challenge response
var (
cert tls.Certificate
name string
)
switch chal.Type {
case "tls-sni-01":
cert, name, err = client.TLSSNI01ChallengeCert(chal.Token)
case "tls-sni-02":
cert, name, err = client.TLSSNI02ChallengeCert(chal.Token)
default:
err = fmt.Errorf("acme/autocert: unknown challenge type %q", chal.Type)
}
if err != nil {
return err
}
m.putTokenCert(name, &cert)
defer func() {
// verification has ended at this point
// don't need token cert anymore
go m.deleteTokenCert(name)
}()
// ready to fulfill the challenge
if _, err := client.Accept(ctx, chal); err != nil {
return err
}
// wait for the CA to validate
_, err = client.WaitAuthorization(ctx, authz.URI)
return err
}
// putTokenCert stores the cert under the named key in both m.tokenCert map
// and m.Cache.
func (m *Manager) putTokenCert(name string, cert *tls.Certificate) {
m.tokenCertMu.Lock()
defer m.tokenCertMu.Unlock()
if m.tokenCert == nil {
m.tokenCert = make(map[string]*tls.Certificate)
}
m.tokenCert[name] = cert
m.cachePut(name, cert)
}
// deleteTokenCert removes the token certificate for the specified domain name
// from both m.tokenCert map and m.Cache.
func (m *Manager) deleteTokenCert(name string) {
m.tokenCertMu.Lock()
defer m.tokenCertMu.Unlock()
delete(m.tokenCert, name)
if m.Cache != nil {
m.Cache.Delete(context.Background(), name)
}
}
// renew starts a cert renewal timer loop, one per domain.
//
// The loop is scheduled in two cases:
// - a cert was fetched from cache for the first time (wasn't in m.state)
// - a new cert was created by m.createCert
//
// The key argument is a certificate private key.
// The exp argument is the cert expiration time (NotAfter).
func (m *Manager) renew(domain string, key crypto.Signer, exp time.Time) {
m.renewalMu.Lock()
defer m.renewalMu.Unlock()
if m.renewal[domain] != nil {
// another goroutine is already on it
return
}
if m.renewal == nil {
m.renewal = make(map[string]*domainRenewal)
}
dr := &domainRenewal{m: m, domain: domain, key: key}
m.renewal[domain] = dr
dr.start(exp)
}
// stopRenew stops all currently running cert renewal timers.
// The timers are not restarted during the lifetime of the Manager.
func (m *Manager) stopRenew() {
m.renewalMu.Lock()
defer m.renewalMu.Unlock()
for name, dr := range m.renewal {
delete(m.renewal, name)
dr.stop()
}
}
func (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {
const keyName = "acme_account.key"
genKey := func() (*ecdsa.PrivateKey, error) {
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
}
if m.Cache == nil {
return genKey()
}
data, err := m.Cache.Get(ctx, keyName)
if err == ErrCacheMiss {
key, err := genKey()
if err != nil {
return nil, err
}
var buf bytes.Buffer
if err := encodeECDSAKey(&buf, key); err != nil {
return nil, err
}
if err := m.Cache.Put(ctx, keyName, buf.Bytes()); err != nil {
return nil, err
}
return key, nil
}
if err != nil {
return nil, err
}
priv, _ := pem.Decode(data)
if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
return nil, errors.New("acme/autocert: invalid account key found in cache")
}
return parsePrivateKey(priv.Bytes)
}
func (m *Manager) acmeClient(ctx context.Context) (*acme.Client, error) {
m.clientMu.Lock()
defer m.clientMu.Unlock()
if m.client != nil {
return m.client, nil
}
client := m.Client
if client == nil {
client = &acme.Client{DirectoryURL: acme.LetsEncryptURL}
}
if client.Key == nil {
var err error
client.Key, err = m.accountKey(ctx)
if err != nil {
return nil, err
}
}
var contact []string
if m.Email != "" {
contact = []string{"mailto:" + m.Email}
}
a := &acme.Account{Contact: contact}
_, err := client.Register(ctx, a, m.Prompt)
if ae, ok := err.(*acme.Error); err == nil || ok && ae.StatusCode == http.StatusConflict {
// conflict indicates the key is already registered
m.client = client
err = nil
}
return m.client, err
}
func (m *Manager) hostPolicy() HostPolicy {
if m.HostPolicy != nil {
return m.HostPolicy
}
return defaultHostPolicy
}
func (m *Manager) renewBefore() time.Duration {
if m.RenewBefore > maxRandRenew {
return m.RenewBefore
}
return 7 * 24 * time.Hour // 1 week
}
// certState is ready when its mutex is unlocked for reading.
type certState struct {
sync.RWMutex
locked bool // locked for read/write
key crypto.Signer // private key for cert
cert [][]byte // DER encoding
leaf *x509.Certificate // parsed cert[0]; always non-nil if cert != nil
}
// tlscert creates a tls.Certificate from s.key and s.cert.
// Callers should wrap it in s.RLock() and s.RUnlock().
func (s *certState) tlscert() (*tls.Certificate, error) {
if s.key == nil {
return nil, errors.New("acme/autocert: missing signer")
}
if len(s.cert) == 0 {
return nil, errors.New("acme/autocert: missing certificate")
}
return &tls.Certificate{
PrivateKey: s.key,
Certificate: s.cert,
Leaf: s.leaf,
}, nil
}
// certRequest creates a certificate request for the given common name cn
// and optional SANs.
func certRequest(key crypto.Signer, cn string, san ...string) ([]byte, error) {
req := &x509.CertificateRequest{
Subject: pkix.Name{CommonName: cn},
DNSNames: san,
}
return x509.CreateCertificateRequest(rand.Reader, req, key)
}
// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
//
// Inspired by parsePrivateKey in crypto/tls/tls.go.
func parsePrivateKey(der []byte) (crypto.Signer, error) {
if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
return key, nil
}
if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
switch key := key.(type) {
case *rsa.PrivateKey:
return key, nil
case *ecdsa.PrivateKey:
return key, nil
default:
return nil, errors.New("acme/autocert: unknown private key type in PKCS#8 wrapping")
}
}
if key, err := x509.ParseECPrivateKey(der); err == nil {
return key, nil
}
return nil, errors.New("acme/autocert: failed to parse private key")
}
// validCert parses a cert chain provided as der argument and verifies the leaf, der[0],
// corresponds to the private key, as well as the domain match and expiration dates.
// It doesn't do any revocation checking.
//
// The returned value is the verified leaf cert.
func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certificate, err error) {
// parse public part(s)
var n int
for _, b := range der {
n += len(b)
}
pub := make([]byte, n)
n = 0
for _, b := range der {
n += copy(pub[n:], b)
}
x509Cert, err := x509.ParseCertificates(pub)
if len(x509Cert) == 0 {
return nil, errors.New("acme/autocert: no public key found")
}
// verify the leaf is not expired and matches the domain name
leaf = x509Cert[0]
now := timeNow()
if now.Before(leaf.NotBefore) {
return nil, errors.New("acme/autocert: certificate is not valid yet")
}
if now.After(leaf.NotAfter) {
return nil, errors.New("acme/autocert: expired certificate")
}
if err := leaf.VerifyHostname(domain); err != nil {
return nil, err
}
// ensure the leaf corresponds to the private key
switch pub := leaf.PublicKey.(type) {
case *rsa.PublicKey:
prv, ok := key.(*rsa.PrivateKey)
if !ok {
return nil, errors.New("acme/autocert: private key type does not match public key type")
}
if pub.N.Cmp(prv.N) != 0 {
return nil, errors.New("acme/autocert: private key does not match public key")
}
case *ecdsa.PublicKey:
prv, ok := key.(*ecdsa.PrivateKey)
if !ok {
return nil, errors.New("acme/autocert: private key type does not match public key type")
}
if pub.X.Cmp(prv.X) != 0 || pub.Y.Cmp(prv.Y) != 0 {
return nil, errors.New("acme/autocert: private key does not match public key")
}
default:
return nil, errors.New("acme/autocert: unknown public key algorithm")
}
return leaf, nil
}
func retryAfter(v string) time.Duration {
if i, err := strconv.Atoi(v); err == nil {
return time.Duration(i) * time.Second
}
if t, err := http.ParseTime(v); err == nil {
return t.Sub(timeNow())
}
return time.Second
}
type lockedMathRand struct {
sync.Mutex
rnd *mathrand.Rand
}
func (r *lockedMathRand) int63n(max int64) int64 {
r.Lock()
n := r.rnd.Int63n(max)
r.Unlock()
return n
}
// for easier testing
var timeNow = time.Now

390
vendor/golang.org/x/crypto/acme/autocert/autocert_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,390 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package autocert
import (
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/base64"
"encoding/json"
"fmt"
"html/template"
"io"
"math/big"
"net/http"
"net/http/httptest"
"reflect"
"testing"
"time"
"golang.org/x/crypto/acme"
"golang.org/x/net/context"
)
var discoTmpl = template.Must(template.New("disco").Parse(`{
"new-reg": "{{.}}/new-reg",
"new-authz": "{{.}}/new-authz",
"new-cert": "{{.}}/new-cert"
}`))
var authzTmpl = template.Must(template.New("authz").Parse(`{
"status": "pending",
"challenges": [
{
"uri": "{{.}}/challenge/1",
"type": "tls-sni-01",
"token": "token-01"
},
{
"uri": "{{.}}/challenge/2",
"type": "tls-sni-02",
"token": "token-02"
}
]
}`))
type memCache map[string][]byte
func (m memCache) Get(ctx context.Context, key string) ([]byte, error) {
v, ok := m[key]
if !ok {
return nil, ErrCacheMiss
}
return v, nil
}
func (m memCache) Put(ctx context.Context, key string, data []byte) error {
m[key] = data
return nil
}
func (m memCache) Delete(ctx context.Context, key string) error {
delete(m, key)
return nil
}
func dummyCert(pub interface{}, san ...string) ([]byte, error) {
return dateDummyCert(pub, time.Now(), time.Now().Add(90*24*time.Hour), san...)
}
func dateDummyCert(pub interface{}, start, end time.Time, san ...string) ([]byte, error) {
// use EC key to run faster on 386
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return nil, err
}
t := &x509.Certificate{
SerialNumber: big.NewInt(1),
NotBefore: start,
NotAfter: end,
BasicConstraintsValid: true,
KeyUsage: x509.KeyUsageKeyEncipherment,
DNSNames: san,
}
if pub == nil {
pub = &key.PublicKey
}
return x509.CreateCertificate(rand.Reader, t, t, pub, key)
}
func decodePayload(v interface{}, r io.Reader) error {
var req struct{ Payload string }
if err := json.NewDecoder(r).Decode(&req); err != nil {
return err
}
payload, err := base64.RawURLEncoding.DecodeString(req.Payload)
if err != nil {
return err
}
return json.Unmarshal(payload, v)
}
func TestGetCertificate(t *testing.T) {
const domain = "example.org"
man := &Manager{Prompt: AcceptTOS}
defer man.stopRenew()
// echo token-02 | shasum -a 256
// then divide result in 2 parts separated by dot
tokenCertName := "4e8eb87631187e9ff2153b56b13a4dec.13a35d002e485d60ff37354b32f665d9.token.acme.invalid"
verifyTokenCert := func() {
hello := &tls.ClientHelloInfo{ServerName: tokenCertName}
_, err := man.GetCertificate(hello)
if err != nil {
t.Errorf("verifyTokenCert: GetCertificate(%q): %v", tokenCertName, err)
return
}
}
// ACME CA server stub
var ca *httptest.Server
ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("replay-nonce", "nonce")
if r.Method == "HEAD" {
// a nonce request
return
}
switch r.URL.Path {
// discovery
case "/":
if err := discoTmpl.Execute(w, ca.URL); err != nil {
t.Fatalf("discoTmpl: %v", err)
}
// client key registration
case "/new-reg":
w.Write([]byte("{}"))
// domain authorization
case "/new-authz":
w.Header().Set("location", ca.URL+"/authz/1")
w.WriteHeader(http.StatusCreated)
if err := authzTmpl.Execute(w, ca.URL); err != nil {
t.Fatalf("authzTmpl: %v", err)
}
// accept tls-sni-02 challenge
case "/challenge/2":
verifyTokenCert()
w.Write([]byte("{}"))
// authorization status
case "/authz/1":
w.Write([]byte(`{"status": "valid"}`))
// cert request
case "/new-cert":
var req struct {
CSR string `json:"csr"`
}
decodePayload(&req, r.Body)
b, _ := base64.RawURLEncoding.DecodeString(req.CSR)
csr, err := x509.ParseCertificateRequest(b)
if err != nil {
t.Fatalf("new-cert: CSR: %v", err)
}
der, err := dummyCert(csr.PublicKey, domain)
if err != nil {
t.Fatalf("new-cert: dummyCert: %v", err)
}
chainUp := fmt.Sprintf("<%s/ca-cert>; rel=up", ca.URL)
w.Header().Set("link", chainUp)
w.WriteHeader(http.StatusCreated)
w.Write(der)
// CA chain cert
case "/ca-cert":
der, err := dummyCert(nil, "ca")
if err != nil {
t.Fatalf("ca-cert: dummyCert: %v", err)
}
w.Write(der)
default:
t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
}
}))
defer ca.Close()
// use EC key to run faster on 386
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
man.Client = &acme.Client{
Key: key,
DirectoryURL: ca.URL,
}
// simulate tls.Config.GetCertificate
var tlscert *tls.Certificate
done := make(chan struct{})
go func() {
hello := &tls.ClientHelloInfo{ServerName: domain}
tlscert, err = man.GetCertificate(hello)
close(done)
}()
select {
case <-time.After(time.Minute):
t.Fatal("man.GetCertificate took too long to return")
case <-done:
}
if err != nil {
t.Fatalf("man.GetCertificate: %v", err)
}
// verify the tlscert is the same we responded with from the CA stub
if len(tlscert.Certificate) == 0 {
t.Fatal("len(tlscert.Certificate) is 0")
}
cert, err := x509.ParseCertificate(tlscert.Certificate[0])
if err != nil {
t.Fatalf("x509.ParseCertificate: %v", err)
}
if len(cert.DNSNames) == 0 || cert.DNSNames[0] != domain {
t.Errorf("cert.DNSNames = %v; want %q", cert.DNSNames, domain)
}
// make sure token cert was removed
done = make(chan struct{})
go func() {
for {
hello := &tls.ClientHelloInfo{ServerName: tokenCertName}
if _, err := man.GetCertificate(hello); err != nil {
break
}
time.Sleep(100 * time.Millisecond)
}
close(done)
}()
select {
case <-time.After(5 * time.Second):
t.Error("token cert was not removed")
case <-done:
}
}
func TestAccountKeyCache(t *testing.T) {
cache := make(memCache)
m := Manager{Cache: cache}
ctx := context.Background()
k1, err := m.accountKey(ctx)
if err != nil {
t.Fatal(err)
}
k2, err := m.accountKey(ctx)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(k1, k2) {
t.Errorf("account keys don't match: k1 = %#v; k2 = %#v", k1, k2)
}
}
func TestCache(t *testing.T) {
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
tmpl := &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: "example.org"},
NotAfter: time.Now().Add(time.Hour),
}
pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &privKey.PublicKey, privKey)
if err != nil {
t.Fatal(err)
}
tlscert := &tls.Certificate{
Certificate: [][]byte{pub},
PrivateKey: privKey,
}
cache := make(memCache)
man := &Manager{Cache: cache}
defer man.stopRenew()
if err := man.cachePut("example.org", tlscert); err != nil {
t.Fatalf("man.cachePut: %v", err)
}
res, err := man.cacheGet("example.org")
if err != nil {
t.Fatalf("man.cacheGet: %v", err)
}
if res == nil {
t.Fatal("res is nil")
}
}
func TestHostWhitelist(t *testing.T) {
policy := HostWhitelist("example.com", "example.org", "*.example.net")
tt := []struct {
host string
allow bool
}{
{"example.com", true},
{"example.org", true},
{"one.example.com", false},
{"two.example.org", false},
{"three.example.net", false},
{"dummy", false},
}
for i, test := range tt {
err := policy(nil, test.host)
if err != nil && test.allow {
t.Errorf("%d: policy(%q): %v; want nil", i, test.host, err)
}
if err == nil && !test.allow {
t.Errorf("%d: policy(%q): nil; want an error", i, test.host)
}
}
}
func TestValidCert(t *testing.T) {
key1, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
key2, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
key3, err := rsa.GenerateKey(rand.Reader, 512)
if err != nil {
t.Fatal(err)
}
cert1, err := dummyCert(key1.Public(), "example.org")
if err != nil {
t.Fatal(err)
}
cert2, err := dummyCert(key2.Public(), "example.org")
if err != nil {
t.Fatal(err)
}
cert3, err := dummyCert(key3.Public(), "example.org")
if err != nil {
t.Fatal(err)
}
now := time.Now()
early, err := dateDummyCert(key1.Public(), now.Add(time.Hour), now.Add(2*time.Hour), "example.org")
if err != nil {
t.Fatal(err)
}
expired, err := dateDummyCert(key1.Public(), now.Add(-2*time.Hour), now.Add(-time.Hour), "example.org")
if err != nil {
t.Fatal(err)
}
tt := []struct {
domain string
key crypto.Signer
cert [][]byte
ok bool
}{
{"example.org", key1, [][]byte{cert1}, true},
{"example.org", key3, [][]byte{cert3}, true},
{"example.org", key1, [][]byte{cert1, cert2, cert3}, true},
{"example.org", key1, [][]byte{cert1, {1}}, false},
{"example.org", key1, [][]byte{{1}}, false},
{"example.org", key1, [][]byte{cert2}, false},
{"example.org", key2, [][]byte{cert1}, false},
{"example.org", key1, [][]byte{cert3}, false},
{"example.org", key3, [][]byte{cert1}, false},
{"example.net", key1, [][]byte{cert1}, false},
{"example.org", key1, [][]byte{early}, false},
{"example.org", key1, [][]byte{expired}, false},
}
for i, test := range tt {
leaf, err := validCert(test.domain, test.cert, test.key)
if err != nil && test.ok {
t.Errorf("%d: err = %v", i, err)
}
if err == nil && !test.ok {
t.Errorf("%d: err is nil", i)
}
if err == nil && test.ok && leaf == nil {
t.Errorf("%d: leaf is nil", i)
}
}
}

130
vendor/golang.org/x/crypto/acme/autocert/cache.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,130 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package autocert
import (
"errors"
"io/ioutil"
"os"
"path/filepath"
"golang.org/x/net/context"
)
// ErrCacheMiss is returned when a certificate is not found in cache.
var ErrCacheMiss = errors.New("acme/autocert: certificate cache miss")
// Cache is used by Manager to store and retrieve previously obtained certificates
// as opaque data.
//
// The key argument of the methods refers to a domain name but need not be an FQDN.
// Cache implementations should not rely on the key naming pattern.
type Cache interface {
// Get returns a certificate data for the specified key.
// If there's no such key, Get returns ErrCacheMiss.
Get(ctx context.Context, key string) ([]byte, error)
// Put stores the data in the cache under the specified key.
// Inderlying implementations may use any data storage format,
// as long as the reverse operation, Get, results in the original data.
Put(ctx context.Context, key string, data []byte) error
// Delete removes a certificate data from the cache under the specified key.
// If there's no such key in the cache, Delete returns nil.
Delete(ctx context.Context, key string) error
}
// DirCache implements Cache using a directory on the local filesystem.
// If the directory does not exist, it will be created with 0700 permissions.
type DirCache string
// Get reads a certificate data from the specified file name.
func (d DirCache) Get(ctx context.Context, name string) ([]byte, error) {
name = filepath.Join(string(d), name)
var (
data []byte
err error
done = make(chan struct{})
)
go func() {
data, err = ioutil.ReadFile(name)
close(done)
}()
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-done:
}
if os.IsNotExist(err) {
return nil, ErrCacheMiss
}
return data, err
}
// Put writes the certificate data to the specified file name.
// The file will be created with 0600 permissions.
func (d DirCache) Put(ctx context.Context, name string, data []byte) error {
if err := os.MkdirAll(string(d), 0700); err != nil {
return err
}
done := make(chan struct{})
var err error
go func() {
defer close(done)
var tmp string
if tmp, err = d.writeTempFile(name, data); err != nil {
return
}
// prevent overwriting the file if the context was cancelled
if ctx.Err() != nil {
return // no need to set err
}
name = filepath.Join(string(d), name)
err = os.Rename(tmp, name)
}()
select {
case <-ctx.Done():
return ctx.Err()
case <-done:
}
return err
}
// Delete removes the specified file name.
func (d DirCache) Delete(ctx context.Context, name string) error {
name = filepath.Join(string(d), name)
var (
err error
done = make(chan struct{})
)
go func() {
err = os.Remove(name)
close(done)
}()
select {
case <-ctx.Done():
return ctx.Err()
case <-done:
}
if err != nil && !os.IsNotExist(err) {
return err
}
return nil
}
// writeTempFile writes b to a temporary file, closes the file and returns its path.
func (d DirCache) writeTempFile(prefix string, b []byte) (string, error) {
// TempFile uses 0600 permissions
f, err := ioutil.TempFile(string(d), prefix)
if err != nil {
return "", err
}
if _, err := f.Write(b); err != nil {
f.Close()
return "", err
}
return f.Name(), f.Close()
}

58
vendor/golang.org/x/crypto/acme/autocert/cache_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,58 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package autocert
import (
"io/ioutil"
"os"
"path/filepath"
"reflect"
"testing"
"golang.org/x/net/context"
)
// make sure DirCache satisfies Cache interface
var _ Cache = DirCache("/")
func TestDirCache(t *testing.T) {
dir, err := ioutil.TempDir("", "autocert")
if err != nil {
t.Fatal(err)
}
dir = filepath.Join(dir, "certs") // a nonexistent dir
cache := DirCache(dir)
ctx := context.Background()
// test cache miss
if _, err := cache.Get(ctx, "nonexistent"); err != ErrCacheMiss {
t.Errorf("get: %v; want ErrCacheMiss", err)
}
// test put/get
b1 := []byte{1}
if err := cache.Put(ctx, "dummy", b1); err != nil {
t.Fatalf("put: %v", err)
}
b2, err := cache.Get(ctx, "dummy")
if err != nil {
t.Fatalf("get: %v", err)
}
if !reflect.DeepEqual(b1, b2) {
t.Errorf("b1 = %v; want %v", b1, b2)
}
name := filepath.Join(dir, "dummy")
if _, err := os.Stat(name); err != nil {
t.Error(err)
}
// test delete
if err := cache.Delete(ctx, "dummy"); err != nil {
t.Fatalf("delete: %v", err)
}
if _, err := cache.Get(ctx, "dummy"); err != ErrCacheMiss {
t.Errorf("get: %v; want ErrCacheMiss", err)
}
}

125
vendor/golang.org/x/crypto/acme/autocert/renewal.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,125 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package autocert
import (
"crypto"
"sync"
"time"
"golang.org/x/net/context"
)
// maxRandRenew is a maximum deviation from Manager.RenewBefore.
const maxRandRenew = time.Hour
// domainRenewal tracks the state used by the periodic timers
// renewing a single domain's cert.
type domainRenewal struct {
m *Manager
domain string
key crypto.Signer
timerMu sync.Mutex
timer *time.Timer
}
// start starts a cert renewal timer at the time
// defined by the certificate expiration time exp.
//
// If the timer is already started, calling start is a noop.
func (dr *domainRenewal) start(exp time.Time) {
dr.timerMu.Lock()
defer dr.timerMu.Unlock()
if dr.timer != nil {
return
}
dr.timer = time.AfterFunc(dr.next(exp), dr.renew)
}
// stop stops the cert renewal timer.
// If the timer is already stopped, calling stop is a noop.
func (dr *domainRenewal) stop() {
dr.timerMu.Lock()
defer dr.timerMu.Unlock()
if dr.timer == nil {
return
}
dr.timer.Stop()
dr.timer = nil
}
// renew is called periodically by a timer.
// The first renew call is kicked off by dr.start.
func (dr *domainRenewal) renew() {
dr.timerMu.Lock()
defer dr.timerMu.Unlock()
if dr.timer == nil {
return
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()
// TODO: rotate dr.key at some point?
next, err := dr.do(ctx)
if err != nil {
next = maxRandRenew / 2
next += time.Duration(pseudoRand.int63n(int64(next)))
}
dr.timer = time.AfterFunc(next, dr.renew)
testDidRenewLoop(next, err)
}
// do is similar to Manager.createCert but it doesn't lock a Manager.state item.
// Instead, it requests a new certificate independently and, upon success,
// replaces dr.m.state item with a new one and updates cache for the given domain.
//
// It may return immediately if the expiration date of the currently cached cert
// is far enough in the future.
//
// The returned value is a time interval after which the renewal should occur again.
func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {
// a race is likely unavoidable in a distributed environment
// but we try nonetheless
if tlscert, err := dr.m.cacheGet(dr.domain); err == nil {
next := dr.next(tlscert.Leaf.NotAfter)
if next > dr.m.renewBefore()+maxRandRenew {
return next, nil
}
}
der, leaf, err := dr.m.authorizedCert(ctx, dr.key, dr.domain)
if err != nil {
return 0, err
}
state := &certState{
key: dr.key,
cert: der,
leaf: leaf,
}
tlscert, err := state.tlscert()
if err != nil {
return 0, err
}
dr.m.cachePut(dr.domain, tlscert)
dr.m.stateMu.Lock()
defer dr.m.stateMu.Unlock()
// m.state is guaranteed to be non-nil at this point
dr.m.state[dr.domain] = state
return dr.next(leaf.NotAfter), nil
}
func (dr *domainRenewal) next(expiry time.Time) time.Duration {
d := expiry.Sub(timeNow()) - dr.m.renewBefore()
// add a bit of randomness to renew deadline
n := pseudoRand.int63n(int64(maxRandRenew))
d -= time.Duration(n)
if d < 0 {
return 0
}
return d
}
var testDidRenewLoop = func(next time.Duration, err error) {}

190
vendor/golang.org/x/crypto/acme/autocert/renewal_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,190 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package autocert
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
"golang.org/x/crypto/acme"
)
func TestRenewalNext(t *testing.T) {
now := time.Now()
timeNow = func() time.Time { return now }
defer func() { timeNow = time.Now }()
man := &Manager{RenewBefore: 7 * 24 * time.Hour}
defer man.stopRenew()
tt := []struct {
expiry time.Time
min, max time.Duration
}{
{now.Add(90 * 24 * time.Hour), 83*24*time.Hour - maxRandRenew, 83 * 24 * time.Hour},
{now.Add(time.Hour), 0, 1},
{now, 0, 1},
{now.Add(-time.Hour), 0, 1},
}
dr := &domainRenewal{m: man}
for i, test := range tt {
next := dr.next(test.expiry)
if next < test.min || test.max < next {
t.Errorf("%d: next = %v; want between %v and %v", i, next, test.min, test.max)
}
}
}
func TestRenewFromCache(t *testing.T) {
const domain = "example.org"
// ACME CA server stub
var ca *httptest.Server
ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("replay-nonce", "nonce")
if r.Method == "HEAD" {
// a nonce request
return
}
switch r.URL.Path {
// discovery
case "/":
if err := discoTmpl.Execute(w, ca.URL); err != nil {
t.Fatalf("discoTmpl: %v", err)
}
// client key registration
case "/new-reg":
w.Write([]byte("{}"))
// domain authorization
case "/new-authz":
w.Header().Set("location", ca.URL+"/authz/1")
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`{"status": "valid"}`))
// cert request
case "/new-cert":
var req struct {
CSR string `json:"csr"`
}
decodePayload(&req, r.Body)
b, _ := base64.RawURLEncoding.DecodeString(req.CSR)
csr, err := x509.ParseCertificateRequest(b)
if err != nil {
t.Fatalf("new-cert: CSR: %v", err)
}
der, err := dummyCert(csr.PublicKey, domain)
if err != nil {
t.Fatalf("new-cert: dummyCert: %v", err)
}
chainUp := fmt.Sprintf("<%s/ca-cert>; rel=up", ca.URL)
w.Header().Set("link", chainUp)
w.WriteHeader(http.StatusCreated)
w.Write(der)
// CA chain cert
case "/ca-cert":
der, err := dummyCert(nil, "ca")
if err != nil {
t.Fatalf("ca-cert: dummyCert: %v", err)
}
w.Write(der)
default:
t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
}
}))
defer ca.Close()
// use EC key to run faster on 386
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
man := &Manager{
Prompt: AcceptTOS,
Cache: make(memCache),
RenewBefore: 24 * time.Hour,
Client: &acme.Client{
Key: key,
DirectoryURL: ca.URL,
},
}
defer man.stopRenew()
// cache an almost expired cert
now := time.Now()
cert, err := dateDummyCert(key.Public(), now.Add(-2*time.Hour), now.Add(time.Minute), domain)
if err != nil {
t.Fatal(err)
}
tlscert := &tls.Certificate{PrivateKey: key, Certificate: [][]byte{cert}}
if err := man.cachePut(domain, tlscert); err != nil {
t.Fatal(err)
}
// veriy the renewal happened
defer func() {
testDidRenewLoop = func(next time.Duration, err error) {}
}()
done := make(chan struct{})
testDidRenewLoop = func(next time.Duration, err error) {
defer close(done)
if err != nil {
t.Errorf("testDidRenewLoop: %v", err)
}
// Next should be about 90 days:
// dummyCert creates 90days expiry + account for man.RenewBefore.
// Previous expiration was within 1 min.
future := 88 * 24 * time.Hour
if next < future {
t.Errorf("testDidRenewLoop: next = %v; want >= %v", next, future)
}
// ensure the new cert is cached
after := time.Now().Add(future)
tlscert, err := man.cacheGet(domain)
if err != nil {
t.Fatalf("man.cacheGet: %v", err)
}
if !tlscert.Leaf.NotAfter.After(after) {
t.Errorf("cache leaf.NotAfter = %v; want > %v", tlscert.Leaf.NotAfter, after)
}
// verify the old cert is also replaced in memory
man.stateMu.Lock()
defer man.stateMu.Unlock()
s := man.state[domain]
if s == nil {
t.Fatalf("m.state[%q] is nil", domain)
}
tlscert, err = s.tlscert()
if err != nil {
t.Fatalf("s.tlscert: %v", err)
}
if !tlscert.Leaf.NotAfter.After(after) {
t.Errorf("state leaf.NotAfter = %v; want > %v", tlscert.Leaf.NotAfter, after)
}
}
// trigger renew
hello := &tls.ClientHelloInfo{ServerName: domain}
if _, err := man.GetCertificate(hello); err != nil {
t.Fatal(err)
}
// wait for renew loop
select {
case <-time.After(10 * time.Second):
t.Fatal("renew took too long to occur")
case <-done:
}
}

473
vendor/golang.org/x/crypto/acme/internal/acme/acme.go сгенерированный поставляемый
Просмотреть файл

@@ -1,473 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package acme provides an ACME client implementation.
// See https://ietf-wg-acme.github.io/acme/ for details.
//
// This package is a work in progress and makes no API stability promises.
package acme
import (
"bytes"
"crypto/rsa"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"strings"
"time"
"golang.org/x/net/context"
)
// Client is an ACME client.
type Client struct {
// HTTPClient optionally specifies an HTTP client to use
// instead of http.DefaultClient.
HTTPClient *http.Client
// Key is the account key used to register with a CA
// and sign requests.
Key *rsa.PrivateKey
}
// Discover performs ACME server discovery using the provided discovery endpoint URL.
func (c *Client) Discover(url string) (*Directory, error) {
res, err := c.httpClient().Get(url)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, responseError(res)
}
var v struct {
Reg string `json:"new-reg"`
Authz string `json:"new-authz"`
Cert string `json:"new-cert"`
Revoke string `json:"revoke-cert"`
Meta struct {
Terms string `json:"terms-of-service"`
Website string `json:"website"`
CAA []string `json:"caa-identities"`
}
}
if json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, err
}
return &Directory{
RegURL: v.Reg,
AuthzURL: v.Authz,
CertURL: v.Cert,
RevokeURL: v.Revoke,
Terms: v.Meta.Terms,
Website: v.Meta.Website,
CAA: v.Meta.CAA,
}, nil
}
// CreateCert requests a new certificate.
// In the case where CA server does not provide the issued certificate in the response,
// CreateCert will poll certURL using c.FetchCert, which will result in additional round-trips.
// In such scenario the caller can cancel the polling with ctx.
//
// If the bundle is true, the returned value will also contain CA (the issuer) certificate.
// The url argument is an Directory.CertURL value, typically obtained from c.Discover.
// The csr is a DER encoded certificate signing request.
func (c *Client) CreateCert(ctx context.Context, url string, csr []byte, exp time.Duration, bundle bool) (der [][]byte, certURL string, err error) {
req := struct {
Resource string `json:"resource"`
CSR string `json:"csr"`
NotBefore string `json:"notBefore,omitempty"`
NotAfter string `json:"notAfter,omitempty"`
}{
Resource: "new-cert",
CSR: base64.RawURLEncoding.EncodeToString(csr),
}
now := timeNow()
req.NotBefore = now.Format(time.RFC3339)
if exp > 0 {
req.NotAfter = now.Add(exp).Format(time.RFC3339)
}
res, err := c.postJWS(url, req)
if err != nil {
return nil, "", err
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
return nil, "", responseError(res)
}
curl := res.Header.Get("location") // cert permanent URL
if res.ContentLength == 0 {
// no cert in the body; poll until we get it
cert, err := c.FetchCert(ctx, curl, bundle)
return cert, curl, err
}
// slurp issued cert and ca, if requested
cert, err := responseCert(c.httpClient(), res, bundle)
return cert, curl, err
}
// FetchCert retrieves already issued certificate from the given url, in DER format.
// It retries the request until the certificate is successfully retrieved,
// context is cancelled by the caller or an error response is received.
//
// The returned value will also contain CA (the issuer) certificate if bundle == true.
//
// http.DefaultClient is used if client argument is nil.
func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) {
for {
res, err := c.httpClient().Get(url)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode == http.StatusOK {
return responseCert(c.httpClient(), res, bundle)
}
if res.StatusCode > 299 {
return nil, responseError(res)
}
d, err := retryAfter(res.Header.Get("retry-after"))
if err != nil {
d = 3 * time.Second
}
select {
case <-time.After(d):
// retry
case <-ctx.Done():
return nil, ctx.Err()
}
}
}
// Register creates a new account registration by following the "new-reg" flow.
// It returns registered account. The a argument is not modified.
//
// The url argument is typically an Directory.RegURL obtained from c.Discover.
func (c *Client) Register(url string, a *Account) (*Account, error) {
return c.doReg(url, "new-reg", a)
}
// GetReg retrieves an existing registration.
// The url argument is an Account.URI, typically obtained from c.Register.
func (c *Client) GetReg(url string) (*Account, error) {
a := &Account{URI: url}
return c.doReg(url, "reg", a)
}
// UpdateReg updates an existing registration.
// It returns an updated account copy. The provided account is not modified.
//
// The url argument is an Account.URI, usually obtained with c.Register.
func (c *Client) UpdateReg(url string, a *Account) (*Account, error) {
return c.doReg(url, "reg", a)
}
// Authorize performs the initial step in an authorization flow.
// The caller will then need to choose from and perform a set of returned
// challenges using c.Accept in order to successfully complete authorization.
//
// The url argument is an authz URL, usually obtained with c.Register.
func (c *Client) Authorize(url, domain string) (*Authorization, error) {
type authzID struct {
Type string `json:"type"`
Value string `json:"value"`
}
req := struct {
Resource string `json:"resource"`
Identifier authzID `json:"identifier"`
}{
Resource: "new-authz",
Identifier: authzID{Type: "dns", Value: domain},
}
res, err := c.postJWS(url, req)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
return nil, responseError(res)
}
var v wireAuthz
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, fmt.Errorf("Decode: %v", err)
}
if v.Status != StatusPending {
return nil, fmt.Errorf("Unexpected status: %s", v.Status)
}
return v.authorization(res.Header.Get("Location")), nil
}
// GetAuthz retrieves the current status of an authorization flow.
//
// A client typically polls an authz status using this method.
func (c *Client) GetAuthz(url string) (*Authorization, error) {
res, err := c.httpClient().Get(url)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
return nil, responseError(res)
}
var v wireAuthz
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, fmt.Errorf("Decode: %v", err)
}
return v.authorization(url), nil
}
// GetChallenge retrieves the current status of an challenge.
//
// A client typically polls a challenge status using this method.
func (c *Client) GetChallenge(url string) (*Challenge, error) {
res, err := c.httpClient().Get(url)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
return nil, responseError(res)
}
v := wireChallenge{URI: url}
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, fmt.Errorf("Decode: %v", err)
}
return v.challenge(), nil
}
// Accept informs the server that the client accepts one of its challenges
// previously obtained with c.Authorize.
//
// The server will then perform the validation asynchronously.
func (c *Client) Accept(chal *Challenge) (*Challenge, error) {
req := struct {
Resource string `json:"resource"`
Type string `json:"type"`
Auth string `json:"keyAuthorization"`
}{
Resource: "challenge",
Type: chal.Type,
Auth: keyAuth(&c.Key.PublicKey, chal.Token),
}
res, err := c.postJWS(chal.URI, req)
if err != nil {
return nil, err
}
defer res.Body.Close()
// Note: the protocol specifies 200 as the expected response code, but
// letsencrypt seems to be returning 202.
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
return nil, responseError(res)
}
var v wireChallenge
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, fmt.Errorf("Decode: %v", err)
}
return v.challenge(), nil
}
// HTTP01Handler creates a new handler which responds to a http-01 challenge.
// The token argument is a Challenge.Token value.
func (c *Client) HTTP01Handler(token string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.HasSuffix(r.URL.Path, token) {
w.WriteHeader(http.StatusNotFound)
return
}
w.Header().Set("content-type", "text/plain")
w.Write([]byte(keyAuth(&c.Key.PublicKey, token)))
})
}
func (c *Client) httpClient() *http.Client {
if c.HTTPClient != nil {
return c.HTTPClient
}
return http.DefaultClient
}
// postJWS signs body and posts it to the provided url.
// The body argument must be JSON-serializable.
func (c *Client) postJWS(url string, body interface{}) (*http.Response, error) {
nonce, err := fetchNonce(c.httpClient(), url)
if err != nil {
return nil, err
}
b, err := jwsEncodeJSON(body, c.Key, nonce)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", url, bytes.NewReader(b))
if err != nil {
return nil, err
}
return c.httpClient().Do(req)
}
// doReg sends all types of registration requests.
// The type of request is identified by typ argument, which is a "resource"
// in the ACME spec terms.
//
// A non-nil acct argument indicates whether the intention is to mutate data
// of the Account. Only Contact and Agreement of its fields are used
// in such cases.
//
// The fields of acct will be populate with the server response
// and may be overwritten.
func (c *Client) doReg(url string, typ string, acct *Account) (*Account, error) {
req := struct {
Resource string `json:"resource"`
Contact []string `json:"contact,omitempty"`
Agreement string `json:"agreement,omitempty"`
}{
Resource: typ,
}
if acct != nil {
req.Contact = acct.Contact
req.Agreement = acct.AgreedTerms
}
res, err := c.postJWS(url, req)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode < 200 || res.StatusCode > 299 {
return nil, responseError(res)
}
var v struct {
Contact []string
Agreement string
Authorizations string
Certificates string
}
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, fmt.Errorf("Decode: %v", err)
}
return &Account{
URI: res.Header.Get("Location"),
Contact: v.Contact,
AgreedTerms: v.Agreement,
CurrentTerms: linkHeader(res.Header, "terms-of-service"),
Authz: linkHeader(res.Header, "next"),
Authorizations: v.Authorizations,
Certificates: v.Certificates,
}, nil
}
func responseCert(client *http.Client, res *http.Response, bundle bool) ([][]byte, error) {
b, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, fmt.Errorf("ReadAll: %v", err)
}
cert := [][]byte{b}
if !bundle {
return cert, nil
}
// append ca cert
up := linkHeader(res.Header, "up")
if up == "" {
return nil, errors.New("rel=up link not found")
}
res, err = client.Get(up)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, responseError(res)
}
b, err = ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
return append(cert, b), nil
}
// responseError creates an error of Error type from resp.
func responseError(resp *http.Response) error {
// don't care if ReadAll returns an error:
// json.Unmarshal will fail in that case anyway
b, _ := ioutil.ReadAll(resp.Body)
e := struct {
Status int
Type string
Detail string
}{
Status: resp.StatusCode,
}
if err := json.Unmarshal(b, &e); err != nil {
// this is not a regular error response:
// populate detail with anything we received,
// e.Status will already contain HTTP response code value
e.Detail = string(b)
if e.Detail == "" {
e.Detail = resp.Status
}
}
return &Error{
StatusCode: e.Status,
ProblemType: e.Type,
Detail: e.Detail,
Header: resp.Header,
}
}
func fetchNonce(client *http.Client, url string) (string, error) {
resp, err := client.Head(url)
if err != nil {
return "", nil
}
defer resp.Body.Close()
enc := resp.Header.Get("replay-nonce")
if enc == "" {
return "", errors.New("nonce not found")
}
return enc, nil
}
func linkHeader(h http.Header, rel string) string {
for _, v := range h["Link"] {
parts := strings.Split(v, ";")
for _, p := range parts {
p = strings.TrimSpace(p)
if !strings.HasPrefix(p, "rel=") {
continue
}
if v := strings.Trim(p[4:], `"`); v == rel {
return strings.Trim(parts[0], "<>")
}
}
}
return ""
}
func retryAfter(v string) (time.Duration, error) {
if i, err := strconv.Atoi(v); err == nil {
return time.Duration(i) * time.Second, nil
}
t, err := http.ParseTime(v)
if err != nil {
return 0, err
}
return t.Sub(timeNow()), nil
}
// keyAuth generates a key authorization string for a given token.
func keyAuth(pub *rsa.PublicKey, token string) string {
return fmt.Sprintf("%s.%s", token, JWKThumbprint(pub))
}
// timeNow is useful for testing for fixed current time.
var timeNow = time.Now

67
vendor/golang.org/x/crypto/acme/internal/acme/jws.go сгенерированный поставляемый
Просмотреть файл

@@ -1,67 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package acme
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"math/big"
)
// jwsEncodeJSON signs claimset using provided key and a nonce.
// The result is serialized in JSON format.
// See https://tools.ietf.org/html/rfc7515#section-7.
func jwsEncodeJSON(claimset interface{}, key *rsa.PrivateKey, nonce string) ([]byte, error) {
jwk := jwkEncode(&key.PublicKey)
phead := fmt.Sprintf(`{"alg":"RS256","jwk":%s,"nonce":%q}`, jwk, nonce)
phead = base64.RawURLEncoding.EncodeToString([]byte(phead))
cs, err := json.Marshal(claimset)
if err != nil {
return nil, err
}
payload := base64.RawURLEncoding.EncodeToString(cs)
h := sha256.New()
h.Write([]byte(phead + "." + payload))
sig, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, h.Sum(nil))
if err != nil {
return nil, err
}
enc := struct {
Protected string `json:"protected"`
Payload string `json:"payload"`
Sig string `json:"signature"`
}{
Protected: phead,
Payload: payload,
Sig: base64.RawURLEncoding.EncodeToString(sig),
}
return json.Marshal(&enc)
}
// jwkEncode encodes public part of an RSA key into a JWK.
// The result is also suitable for creating a JWK thumbprint.
func jwkEncode(pub *rsa.PublicKey) string {
n := pub.N
e := big.NewInt(int64(pub.E))
// fields order is important
// see https://tools.ietf.org/html/rfc7638#section-3.3 for details
return fmt.Sprintf(`{"e":"%s","kty":"RSA","n":"%s"}`,
base64.RawURLEncoding.EncodeToString(e.Bytes()),
base64.RawURLEncoding.EncodeToString(n.Bytes()),
)
}
// JWKThumbprint creates a JWK thumbprint out of pub
// as specified in https://tools.ietf.org/html/rfc7638.
func JWKThumbprint(pub *rsa.PublicKey) string {
jwk := jwkEncode(pub)
b := sha256.Sum256([]byte(jwk))
return base64.RawURLEncoding.EncodeToString(b[:])
}

153
vendor/golang.org/x/crypto/acme/jws.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,153 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package acme
import (
"crypto"
"crypto/ecdsa"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
_ "crypto/sha512" // need for EC keys
"encoding/base64"
"encoding/json"
"fmt"
"math/big"
)
// jwsEncodeJSON signs claimset using provided key and a nonce.
// The result is serialized in JSON format.
// See https://tools.ietf.org/html/rfc7515#section-7.
func jwsEncodeJSON(claimset interface{}, key crypto.Signer, nonce string) ([]byte, error) {
jwk, err := jwkEncode(key.Public())
if err != nil {
return nil, err
}
alg, sha := jwsHasher(key)
if alg == "" || !sha.Available() {
return nil, ErrUnsupportedKey
}
phead := fmt.Sprintf(`{"alg":%q,"jwk":%s,"nonce":%q}`, alg, jwk, nonce)
phead = base64.RawURLEncoding.EncodeToString([]byte(phead))
cs, err := json.Marshal(claimset)
if err != nil {
return nil, err
}
payload := base64.RawURLEncoding.EncodeToString(cs)
hash := sha.New()
hash.Write([]byte(phead + "." + payload))
sig, err := jwsSign(key, sha, hash.Sum(nil))
if err != nil {
return nil, err
}
enc := struct {
Protected string `json:"protected"`
Payload string `json:"payload"`
Sig string `json:"signature"`
}{
Protected: phead,
Payload: payload,
Sig: base64.RawURLEncoding.EncodeToString(sig),
}
return json.Marshal(&enc)
}
// jwkEncode encodes public part of an RSA or ECDSA key into a JWK.
// The result is also suitable for creating a JWK thumbprint.
// https://tools.ietf.org/html/rfc7517
func jwkEncode(pub crypto.PublicKey) (string, error) {
switch pub := pub.(type) {
case *rsa.PublicKey:
// https://tools.ietf.org/html/rfc7518#section-6.3.1
n := pub.N
e := big.NewInt(int64(pub.E))
// Field order is important.
// See https://tools.ietf.org/html/rfc7638#section-3.3 for details.
return fmt.Sprintf(`{"e":"%s","kty":"RSA","n":"%s"}`,
base64.RawURLEncoding.EncodeToString(e.Bytes()),
base64.RawURLEncoding.EncodeToString(n.Bytes()),
), nil
case *ecdsa.PublicKey:
// https://tools.ietf.org/html/rfc7518#section-6.2.1
p := pub.Curve.Params()
n := p.BitSize / 8
if p.BitSize%8 != 0 {
n++
}
x := pub.X.Bytes()
if n > len(x) {
x = append(make([]byte, n-len(x)), x...)
}
y := pub.Y.Bytes()
if n > len(y) {
y = append(make([]byte, n-len(y)), y...)
}
// Field order is important.
// See https://tools.ietf.org/html/rfc7638#section-3.3 for details.
return fmt.Sprintf(`{"crv":"%s","kty":"EC","x":"%s","y":"%s"}`,
p.Name,
base64.RawURLEncoding.EncodeToString(x),
base64.RawURLEncoding.EncodeToString(y),
), nil
}
return "", ErrUnsupportedKey
}
// jwsSign signs the digest using the given key.
// It returns ErrUnsupportedKey if the key type is unknown.
// The hash is used only for RSA keys.
func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) {
switch key := key.(type) {
case *rsa.PrivateKey:
return key.Sign(rand.Reader, digest, hash)
case *ecdsa.PrivateKey:
r, s, err := ecdsa.Sign(rand.Reader, key, digest)
if err != nil {
return nil, err
}
rb, sb := r.Bytes(), s.Bytes()
size := key.Params().BitSize / 8
if size%8 > 0 {
size++
}
sig := make([]byte, size*2)
copy(sig[size-len(rb):], rb)
copy(sig[size*2-len(sb):], sb)
return sig, nil
}
return nil, ErrUnsupportedKey
}
// jwsHasher indicates suitable JWS algorithm name and a hash function
// to use for signing a digest with the provided key.
// It returns ("", 0) if the key is not supported.
func jwsHasher(key crypto.Signer) (string, crypto.Hash) {
switch key := key.(type) {
case *rsa.PrivateKey:
return "RS256", crypto.SHA256
case *ecdsa.PrivateKey:
switch key.Params().Name {
case "P-256":
return "ES256", crypto.SHA256
case "P-384":
return "ES384", crypto.SHA384
case "P-512":
return "ES512", crypto.SHA512
}
}
return "", 0
}
// JWKThumbprint creates a JWK thumbprint out of pub
// as specified in https://tools.ietf.org/html/rfc7638.
func JWKThumbprint(pub crypto.PublicKey) (string, error) {
jwk, err := jwkEncode(pub)
if err != nil {
return "", err
}
b := sha256.Sum256([]byte(jwk))
return base64.RawURLEncoding.EncodeToString(b[:]), nil
}

Просмотреть файл

@@ -5,6 +5,8 @@
package acme
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
@@ -47,7 +49,29 @@ EQeIP6dZtv8IMgtGIb91QX9pXvP0aznzQKwYIA8nZgoENCPfiMTPiEDT9e/0lObO
// This thumbprint is for the testKey defined above.
const testKeyThumbprint = "6nicxzh6WETQlrvdchkz-U3e3DOQZ4heJKU63rfqMqQ"
var testKey *rsa.PrivateKey
const (
// openssl ecparam -name secp256k1 -genkey -noout
testKeyECPEM = `
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIK07hGLr0RwyUdYJ8wbIiBS55CjnkMD23DWr+ccnypWLoAoGCCqGSM49
AwEHoUQDQgAE5lhEug5xK4xBDZ2nAbaxLtaLiv85bxJ7ePd1dkO23HThqIrvawF5
QAaS/RNouybCiRhRjI3EaxLkQwgrCw0gqQ==
-----END EC PRIVATE KEY-----
`
// 1. opnessl ec -in key.pem -noout -text
// 2. remove first byte, 04 (the header); the rest is X and Y
// 3. covert each with: echo <val> | xxd -r -p | base64 | tr -d '=' | tr '/+' '_-'
testKeyECPubX = "5lhEug5xK4xBDZ2nAbaxLtaLiv85bxJ7ePd1dkO23HQ"
testKeyECPubY = "4aiK72sBeUAGkv0TaLsmwokYUYyNxGsS5EMIKwsNIKk"
// echo -n '{"crv":"P-256","kty":"EC","x":"<testKeyECPubX>","y":"<testKeyECPubY>"}' | \
// openssl dgst -binary -sha256 | base64 | tr -d '=' | tr '/+' '_-'
testKeyECThumbprint = "zedj-Bd1Zshp8KLePv2MB-lJ_Hagp7wAwdkA0NUTniU"
)
var (
testKey *rsa.PrivateKey
testKeyEC *ecdsa.PrivateKey
)
func init() {
d, _ := pem.Decode([]byte(testKeyPEM))
@@ -59,6 +83,14 @@ func init() {
if err != nil {
panic(err.Error())
}
if d, _ = pem.Decode([]byte(testKeyECPEM)); d == nil {
panic("no block found in testKeyECPEM")
}
testKeyEC, err = x509.ParseECPrivateKey(d.Bytes)
if err != nil {
panic(err.Error())
}
}
func TestJWSEncodeJSON(t *testing.T) {
@@ -108,7 +140,55 @@ func TestJWSEncodeJSON(t *testing.T) {
}
}
func TestJWKThumbprint(t *testing.T) {
func TestJWSEncodeJSONEC(t *testing.T) {
claims := struct{ Msg string }{"Hello JWS"}
b, err := jwsEncodeJSON(claims, testKeyEC, "nonce")
if err != nil {
t.Fatal(err)
}
var jws struct{ Protected, Payload, Signature string }
if err := json.Unmarshal(b, &jws); err != nil {
t.Fatal(err)
}
if b, err = base64.RawURLEncoding.DecodeString(jws.Protected); err != nil {
t.Fatalf("jws.Protected: %v", err)
}
var head struct {
Alg string
Nonce string
JWK struct {
Crv string
Kty string
X string
Y string
} `json:"jwk"`
}
if err := json.Unmarshal(b, &head); err != nil {
t.Fatalf("jws.Protected: %v", err)
}
if head.Alg != "ES256" {
t.Errorf("head.Alg = %q; want ES256", head.Alg)
}
if head.Nonce != "nonce" {
t.Errorf("head.Nonce = %q; want nonce", head.Nonce)
}
if head.JWK.Crv != "P-256" {
t.Errorf("head.JWK.Crv = %q; want P-256", head.JWK.Crv)
}
if head.JWK.Kty != "EC" {
t.Errorf("head.JWK.Kty = %q; want EC", head.JWK.Kty)
}
if head.JWK.X != testKeyECPubX {
t.Errorf("head.JWK.X = %q; want %q", head.JWK.X, testKeyECPubX)
}
if head.JWK.Y != testKeyECPubY {
t.Errorf("head.JWK.Y = %q; want %q", head.JWK.Y, testKeyECPubY)
}
}
func TestJWKThumbprintRSA(t *testing.T) {
// Key example from RFC 7638
const base64N = "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAt" +
"VT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn6" +
@@ -119,21 +199,68 @@ func TestJWKThumbprint(t *testing.T) {
const base64E = "AQAB"
const expected = "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs"
bytes, err := base64.RawURLEncoding.DecodeString(base64N)
b, err := base64.RawURLEncoding.DecodeString(base64N)
if err != nil {
t.Fatalf("Error parsing example key N: %v", err)
}
n := new(big.Int).SetBytes(bytes)
n := new(big.Int).SetBytes(b)
bytes, err = base64.RawURLEncoding.DecodeString(base64E)
b, err = base64.RawURLEncoding.DecodeString(base64E)
if err != nil {
t.Fatalf("Error parsing example key E: %v", err)
}
e := new(big.Int).SetBytes(bytes)
e := new(big.Int).SetBytes(b)
pub := &rsa.PublicKey{N: n, E: int(e.Uint64())}
th := JWKThumbprint(pub)
th, err := JWKThumbprint(pub)
if err != nil {
t.Error(err)
}
if th != expected {
t.Errorf("th = %q; want %q", th, expected)
t.Errorf("thumbprint = %q; want %q", th, expected)
}
}
func TestJWKThumbprintEC(t *testing.T) {
// Key example from RFC 7520
// expected was computed with
// echo -n '{"crv":"P-521","kty":"EC","x":"<base64X>","y":"<base64Y>"}' | \
// openssl dgst -binary -sha256 | \
// base64 | \
// tr -d '=' | tr '/+' '_-'
const (
base64X = "AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9A5RkT" +
"KqjqvjyekWF-7ytDyRXYgCF5cj0Kt"
base64Y = "AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVySsUda" +
"QkAgDPrwQrJmbnX9cwlGfP-HqHZR1"
expected = "dHri3SADZkrush5HU_50AoRhcKFryN-PI6jPBtPL55M"
)
b, err := base64.RawURLEncoding.DecodeString(base64X)
if err != nil {
t.Fatalf("Error parsing example key X: %v", err)
}
x := new(big.Int).SetBytes(b)
b, err = base64.RawURLEncoding.DecodeString(base64Y)
if err != nil {
t.Fatalf("Error parsing example key Y: %v", err)
}
y := new(big.Int).SetBytes(b)
pub := &ecdsa.PublicKey{Curve: elliptic.P521(), X: x, Y: y}
th, err := JWKThumbprint(pub)
if err != nil {
t.Error(err)
}
if th != expected {
t.Errorf("thumbprint = %q; want %q", th, expected)
}
}
func TestJWKThumbprintErrUnsupportedKey(t *testing.T) {
_, err := JWKThumbprint(struct{}{})
if err != ErrUnsupportedKey {
t.Errorf("err = %q; want %q", err, ErrUnsupportedKey)
}
}

Просмотреть файл

@@ -1,6 +1,7 @@
package acme
import (
"errors"
"fmt"
"net/http"
)
@@ -15,6 +16,50 @@ const (
StatusRevoked = "revoked"
)
// CRLReasonCode identifies the reason for a certificate revocation.
type CRLReasonCode int
// CRL reason codes as defined in RFC 5280.
const (
CRLReasonUnspecified CRLReasonCode = 0
CRLReasonKeyCompromise CRLReasonCode = 1
CRLReasonCACompromise CRLReasonCode = 2
CRLReasonAffiliationChanged CRLReasonCode = 3
CRLReasonSuperseded CRLReasonCode = 4
CRLReasonCessationOfOperation CRLReasonCode = 5
CRLReasonCertificateHold CRLReasonCode = 6
CRLReasonRemoveFromCRL CRLReasonCode = 8
CRLReasonPrivilegeWithdrawn CRLReasonCode = 9
CRLReasonAACompromise CRLReasonCode = 10
)
var (
// ErrAuthorizationFailed indicates that an authorization for an identifier
// did not succeed.
ErrAuthorizationFailed = errors.New("acme: identifier authorization failed")
// ErrUnsupportedKey is returned when an unsupported key type is encountered.
ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")
)
// Error is an ACME error, defined in Problem Details for HTTP APIs doc
// http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.
type Error struct {
// StatusCode is The HTTP status code generated by the origin server.
StatusCode int
// ProblemType is a URI reference that identifies the problem type,
// typically in a "urn:acme:error:xxx" form.
ProblemType string
// Detail is a human-readable explanation specific to this occurrence of the problem.
Detail string
// Header is the original server error response headers.
Header http.Header
}
func (e *Error) Error() string {
return fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail)
}
// Account is a user account. It is associated with a private key.
type Account struct {
// URI is the account unique ID, which is also a URL used to retrieve
@@ -25,7 +70,8 @@ type Account struct {
Contact []string
// The terms user has agreed to.
// Zero value indicates that the user hasn't agreed yet.
// A value not matching CurrentTerms indicates that the user hasn't agreed
// to the actual Terms of Service of the CA.
AgreedTerms string
// Actual terms of a CA.
@@ -116,24 +162,6 @@ type AuthzID struct {
Value string // The identifier itself, e.g. "example.org".
}
// Error is an ACME error, defined in Problem Details for HTTP APIs doc
// http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.
type Error struct {
// StatusCode is The HTTP status code generated by the origin server.
StatusCode int
// ProblemType is a URI reference that identifies the problem type,
// typically in a "urn:acme:error:xxx" form.
ProblemType string
// Detail is a human-readable explanation specific to this occurrence of the problem.
Detail string
// Header is the original server error response headers.
Header http.Header
}
func (e *Error) Error() string {
return fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail)
}
// wireAuthz is ACME JSON representation of Authorization objects.
type wireAuthz struct {
Status string

2
vendor/golang.org/x/crypto/blowfish/cipher.go сгенерированный поставляемый
Просмотреть файл

@@ -39,7 +39,7 @@ func NewCipher(key []byte) (*Cipher, error) {
// NewSaltedCipher creates a returns a Cipher that folds a salt into its key
// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is
// sufficient and desirable. For bcrypt compatiblity, the key can be over 56
// sufficient and desirable. For bcrypt compatibility, the key can be over 56
// bytes.
func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
if len(salt) == 0 {

5
vendor/golang.org/x/crypto/nacl/box/box.go сгенерированный поставляемый
Просмотреть файл

@@ -13,15 +13,16 @@ example, by using nonce 1 for the first message, nonce 2 for the second
message, etc. Nonces are long enough that randomly generated nonces have
negligible risk of collision.
This package is interoperable with NaCl: http://nacl.cr.yp.to/box.html.
This package is interoperable with NaCl: https://nacl.cr.yp.to/box.html.
*/
package box // import "golang.org/x/crypto/nacl/box"
import (
"io"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/nacl/secretbox"
"golang.org/x/crypto/salsa20/salsa"
"io"
)
// Overhead is the number of bytes of overhead when boxing a message.

53
vendor/golang.org/x/crypto/nacl/secretbox/example_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,53 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package secretbox_test
import (
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"golang.org/x/crypto/nacl/secretbox"
)
func Example() {
// Load your secret key from a safe place and reuse it across multiple
// Seal calls. (Obviously don't use this example key for anything
// real.) If you want to convert a passphrase to a key, use a suitable
// package like bcrypt or scrypt.
secretKeyBytes, err := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574")
if err != nil {
panic(err)
}
var secretKey [32]byte
copy(secretKey[:], secretKeyBytes)
// You must use a different nonce for each message you encrypt with the
// same key. Since the nonce here is 192 bits long, a random value
// provides a sufficiently small probability of repeats.
var nonce [24]byte
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
panic(err)
}
// This encrypts "hello world" and appends the result to the nonce.
encrypted := secretbox.Seal(nonce[:], []byte("hello world"), &nonce, &secretKey)
// When you decrypt, you must use the same nonce and key you used to
// encrypt the message. One way to achieve this is to store the nonce
// alongside the encrypted message. Above, we stored the nonce in the first
// 24 bytes of the encrypted text.
var decryptNonce [24]byte
copy(decryptNonce[:], encrypted[:24])
decrypted, ok := secretbox.Open([]byte{}, encrypted[24:], &decryptNonce, &secretKey)
if !ok {
panic("decryption error")
}
fmt.Println(string(decrypted))
// Output: hello world
}

2
vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go сгенерированный поставляемый
Просмотреть файл

@@ -13,7 +13,7 @@ example, by using nonce 1 for the first message, nonce 2 for the second
message, etc. Nonces are long enough that randomly generated nonces have
negligible risk of collision.
This package is interoperable with NaCl: http://nacl.cr.yp.to/secretbox.html.
This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
*/
package secretbox // import "golang.org/x/crypto/nacl/secretbox"

12
vendor/golang.org/x/crypto/ocsp/ocsp.go сгенерированный поставляемый
Просмотреть файл

@@ -30,11 +30,11 @@ var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1}
type ResponseStatus int
const (
Success ResponseStatus = 0
Malformed ResponseStatus = 1
InternalError ResponseStatus = 2
TryLater ResponseStatus = 3
// Status code four is ununsed in OCSP. See
Success ResponseStatus = 0
Malformed ResponseStatus = 1
InternalError ResponseStatus = 2
TryLater ResponseStatus = 3
// Status code four is unused in OCSP. See
// https://tools.ietf.org/html/rfc6960#section-4.2.1
SignatureRequired ResponseStatus = 5
Unauthorized ResponseStatus = 6
@@ -114,7 +114,7 @@ type basicResponse struct {
type responseData struct {
Raw asn1.RawContent
Version int `asn1:"optional,default:1,explicit,tag:0"`
Version int `asn1:"optional,default:0,explicit,tag:0"`
RawResponderName asn1.RawValue `asn1:"optional,explicit,tag:1"`
KeyHash []byte `asn1:"optional,explicit,tag:2"`
ProducedAt time.Time `asn1:"generalized"`

6
vendor/golang.org/x/crypto/openpgp/keys.go сгенерированный поставляемый
Просмотреть файл

@@ -504,6 +504,12 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
},
}
// If the user passes in a DefaultHash via packet.Config,
// set the PreferredHash for the SelfSignature.
if config != nil && config.DefaultHash != 0 {
e.Identities[uid.Id].SelfSignature.PreferredHash = []uint8{hashToHashId(config.DefaultHash)}
}
e.Subkeys = make([]Subkey, 1)
e.Subkeys[0] = Subkey{
PublicKey: packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey),

34
vendor/golang.org/x/crypto/openpgp/keys_test.go сгенерированный поставляемый
Просмотреть файл

@@ -2,6 +2,7 @@ package openpgp
import (
"bytes"
"crypto"
"strings"
"testing"
"time"
@@ -271,6 +272,39 @@ func TestIdVerification(t *testing.T) {
}
}
func TestNewEntityWithPreferredHash(t *testing.T) {
c := &packet.Config{
DefaultHash: crypto.SHA256,
}
entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", c)
if err != nil {
t.Fatal(err)
}
for _, identity := range entity.Identities {
if len(identity.SelfSignature.PreferredHash) == 0 {
t.Fatal("didn't find a preferred hash in self signature")
}
ph := hashToHashId(c.DefaultHash)
if identity.SelfSignature.PreferredHash[0] != ph {
t.Fatalf("Expected preferred hash to be %d, got %d", ph, identity.SelfSignature.PreferredHash[0])
}
}
}
func TestNewEntityWithoutPreferredHash(t *testing.T) {
entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", nil)
if err != nil {
t.Fatal(err)
}
for _, identity := range entity.Identities {
if len(identity.SelfSignature.PreferredHash) != 0 {
t.Fatal("Expected preferred hash to be empty but got length %d", len(identity.SelfSignature.PreferredHash))
}
}
}
const expiringKeyHex = "988d0451d1ec5d010400ba3385721f2dc3f4ab096b2ee867ab77213f0a27a8538441c35d2fa225b08798a1439a66a5150e6bdc3f40f5d28d588c712394c632b6299f77db8c0d48d37903fb72ebd794d61be6aa774688839e5fdecfe06b2684cc115d240c98c66cb1ef22ae84e3aa0c2b0c28665c1e7d4d044e7f270706193f5223c8d44e0d70b7b8da830011010001b40f4578706972792074657374206b657988be041301020028050251d1ec5d021b03050900278d00060b090807030206150802090a0b0416020301021e01021780000a091072589ad75e237d8c033503fd10506d72837834eb7f994117740723adc39227104b0d326a1161871c0b415d25b4aedef946ca77ea4c05af9c22b32cf98be86ab890111fced1ee3f75e87b7cc3c00dc63bbc85dfab91c0dc2ad9de2c4d13a34659333a85c6acc1a669c5e1d6cecb0cf1e56c10e72d855ae177ddc9e766f9b2dda57ccbb75f57156438bbdb4e42b88d0451d1ec5d0104009c64906559866c5cb61578f5846a94fcee142a489c9b41e67b12bb54cfe86eb9bc8566460f9a720cb00d6526fbccfd4f552071a8e3f7744b1882d01036d811ee5a3fb91a1c568055758f43ba5d2c6a9676b012f3a1a89e47bbf624f1ad571b208f3cc6224eb378f1645dd3d47584463f9eadeacfd1ce6f813064fbfdcc4b5a53001101000188a504180102000f021b0c050251d1f06b050900093e89000a091072589ad75e237d8c20e00400ab8310a41461425b37889c4da28129b5fae6084fafbc0a47dd1adc74a264c6e9c9cc125f40462ee1433072a58384daef88c961c390ed06426a81b464a53194c4e291ddd7e2e2ba3efced01537d713bd111f48437bde2363446200995e8e0d4e528dda377fd1e8f8ede9c8e2198b393bd86852ce7457a7e3daf74d510461a5b77b88d0451d1ece8010400b3a519f83ab0010307e83bca895170acce8964a044190a2b368892f7a244758d9fc193482648acb1fb9780d28cc22d171931f38bb40279389fc9bf2110876d4f3db4fcfb13f22f7083877fe56592b3b65251312c36f83ffcb6d313c6a17f197dd471f0712aad15a8537b435a92471ba2e5b0c72a6c72536c3b567c558d7b6051001101000188a504180102000f021b0c050251d1f07b050900279091000a091072589ad75e237d8ce69e03fe286026afacf7c97ee20673864d4459a2240b5655219950643c7dba0ac384b1d4359c67805b21d98211f7b09c2a0ccf6410c8c04d4ff4a51293725d8d6570d9d8bb0e10c07d22357caeb49626df99c180be02d77d1fe8ed25e7a54481237646083a9f89a11566cd20b9e995b1487c5f9e02aeb434f3a1897cd416dd0a87861838da3e9e"
const subkeyUsageHex = "988d04533a52bc010400d26af43085558f65b9e7dbc90cb9238015259aed5e954637adcfa2181548b2d0b60c65f1f42ec5081cbf1bc0a8aa4900acfb77070837c58f26012fbce297d70afe96e759ad63531f0037538e70dbf8e384569b9720d99d8eb39d8d0a2947233ed242436cb6ac7dfe74123354b3d0119b5c235d3dd9c9d6c004f8ffaf67ad8583001101000188b7041f010200210502533b8552170c8001ce094aa433f7040bb2ddf0be3893cb843d0fe70c020700000a0910a42704b92866382aa98404009d63d916a27543da4221c60087c33f1c44bec9998c5438018ed370cca4962876c748e94b73eb39c58eb698063f3fd6346d58dd2a11c0247934c4a9d71f24754f7468f96fb24c3e791dd2392b62f626148ad724189498cbf993db2df7c0cdc2d677c35da0f16cb16c9ce7c33b4de65a4a91b1d21a130ae9cc26067718910ef8e2b417556d627261203c756d627261407379642e65642e61753e88b80413010200220502533a52bc021b03060b090807030206150802090a0b0416020301021e01021780000a0910a42704b92866382a47840400c0c2bd04f5fca586de408b395b3c280a278259c93eaaa8b79a53b97003f8ed502a8a00446dd9947fb462677e4fcac0dac2f0701847d15130aadb6cd9e0705ea0cf5f92f129136c7be21a718d46c8e641eb7f044f2adae573e11ae423a0a9ca51324f03a8a2f34b91fa40c3cc764bee4dccadedb54c768ba0469b683ea53f1c29b88d04533a52bc01040099c92a5d6f8b744224da27bc2369127c35269b58bec179de6bbc038f749344222f85a31933224f26b70243c4e4b2d242f0c4777eaef7b5502f9dad6d8bf3aaeb471210674b74de2d7078af497d55f5cdad97c7bedfbc1b41e8065a97c9c3d344b21fc81d27723af8e374bc595da26ea242dccb6ae497be26eea57e563ed517e90011010001889f0418010200090502533a52bc021b0c000a0910a42704b92866382afa1403ff70284c2de8a043ff51d8d29772602fa98009b7861c540535f874f2c230af8caf5638151a636b21f8255003997ccd29747fdd06777bb24f9593bd7d98a3e887689bf902f999915fcc94625ae487e5d13e6616f89090ebc4fdc7eb5cad8943e4056995bb61c6af37f8043016876a958ec7ebf39c43d20d53b7f546cfa83e8d2604b88d04533b8283010400c0b529316dbdf58b4c54461e7e669dc11c09eb7f73819f178ccd4177b9182b91d138605fcf1e463262fabefa73f94a52b5e15d1904635541c7ea540f07050ce0fb51b73e6f88644cec86e91107c957a114f69554548a85295d2b70bd0b203992f76eb5d493d86d9eabcaa7ef3fc7db7e458438db3fcdb0ca1cc97c638439a9170011010001889f0418010200090502533b8283021b0c000a0910a42704b92866382adc6d0400cfff6258485a21675adb7a811c3e19ebca18851533f75a7ba317950b9997fda8d1a4c8c76505c08c04b6c2cc31dc704d33da36a21273f2b388a1a706f7c3378b66d887197a525936ed9a69acb57fe7f718133da85ec742001c5d1864e9c6c8ea1b94f1c3759cebfd93b18606066c063a63be86085b7e37bdbc65f9a915bf084bb901a204533b85cd110400aed3d2c52af2b38b5b67904b0ef73d6dd7aef86adb770e2b153cd22489654dcc91730892087bb9856ae2d9f7ed1eb48f214243fe86bfe87b349ebd7c30e630e49c07b21fdabf78b7a95c8b7f969e97e3d33f2e074c63552ba64a2ded7badc05ce0ea2be6d53485f6900c7860c7aa76560376ce963d7271b9b54638a4028b573f00a0d8854bfcdb04986141568046202192263b9b67350400aaa1049dbc7943141ef590a70dcb028d730371d92ea4863de715f7f0f16d168bd3dc266c2450457d46dcbbf0b071547e5fbee7700a820c3750b236335d8d5848adb3c0da010e998908dfd93d961480084f3aea20b247034f8988eccb5546efaa35a92d0451df3aaf1aee5aa36a4c4d462c760ecd9cebcabfbe1412b1f21450f203fd126687cd486496e971a87fd9e1a8a765fe654baa219a6871ab97768596ab05c26c1aeea8f1a2c72395a58dbc12ef9640d2b95784e974a4d2d5a9b17c25fedacfe551bda52602de8f6d2e48443f5dd1a2a2a8e6a5e70ecdb88cd6e766ad9745c7ee91d78cc55c3d06536b49c3fee6c3d0b6ff0fb2bf13a314f57c953b8f4d93bf88e70418010200090502533b85cd021b0200520910a42704b92866382a47200419110200060502533b85cd000a091042ce2c64bc0ba99214b2009e26b26852c8b13b10c35768e40e78fbbb48bd084100a0c79d9ea0844fa5853dd3c85ff3ecae6f2c9dd6c557aa04008bbbc964cd65b9b8299d4ebf31f41cc7264b8cf33a00e82c5af022331fac79efc9563a822497ba012953cefe2629f1242fcdcb911dbb2315985bab060bfd58261ace3c654bdbbe2e8ed27a46e836490145c86dc7bae15c011f7e1ffc33730109b9338cd9f483e7cef3d2f396aab5bd80efb6646d7e778270ee99d934d187dd98"
const revokedKeyHex = "988d045331ce82010400c4fdf7b40a5477f206e6ee278eaef888ca73bf9128a9eef9f2f1ddb8b7b71a4c07cfa241f028a04edb405e4d916c61d6beabc333813dc7b484d2b3c52ee233c6a79b1eea4e9cc51596ba9cd5ac5aeb9df62d86ea051055b79d03f8a4fa9f38386f5bd17529138f3325d46801514ea9047977e0829ed728e68636802796801be10011010001889f04200102000905025331d0e3021d03000a0910a401d9f09a34f7c042aa040086631196405b7e6af71026b88e98012eab44aa9849f6ef3fa930c7c9f23deaedba9db1538830f8652fb7648ec3fcade8dbcbf9eaf428e83c6cbcc272201bfe2fbb90d41963397a7c0637a1a9d9448ce695d9790db2dc95433ad7be19eb3de72dacf1d6db82c3644c13eae2a3d072b99bb341debba012c5ce4006a7d34a1f4b94b444526567205265766f6b657220283c52656727732022424d204261726973746122204b657920262530305c303e5c29203c72656740626d626172697374612e636f2e61753e88b704130102002205025331ce82021b03060b090807030206150802090a0b0416020301021e01021780000a0910a401d9f09a34f7c0019c03f75edfbeb6a73e7225ad3cc52724e2872e04260d7daf0d693c170d8c4b243b8767bc7785763533febc62ec2600c30603c433c095453ede59ff2fcabeb84ce32e0ed9d5cf15ffcbc816202b64370d4d77c1e9077d74e94a16fb4fa2e5bec23a56d7a73cf275f91691ae1801a976fcde09e981a2f6327ac27ea1fecf3185df0d56889c04100102000605025331cfb5000a0910fe9645554e8266b64b4303fc084075396674fb6f778d302ac07cef6bc0b5d07b66b2004c44aef711cbac79617ef06d836b4957522d8772dd94bf41a2f4ac8b1ee6d70c57503f837445a74765a076d07b829b8111fc2a918423ddb817ead7ca2a613ef0bfb9c6b3562aec6c3cf3c75ef3031d81d95f6563e4cdcc9960bcb386c5d757b104fcca5fe11fc709df884604101102000605025331cfe7000a09107b15a67f0b3ddc0317f6009e360beea58f29c1d963a22b962b80788c3fa6c84e009d148cfde6b351469b8eae91187eff07ad9d08fcaab88d045331ce820104009f25e20a42b904f3fa555530fe5c46737cf7bd076c35a2a0d22b11f7e0b61a69320b768f4a80fe13980ce380d1cfc4a0cd8fbe2d2e2ef85416668b77208baa65bf973fe8e500e78cc310d7c8705cdb34328bf80e24f0385fce5845c33bc7943cf6b11b02348a23da0bf6428e57c05135f2dc6bd7c1ce325d666d5a5fd2fd5e410011010001889f04180102000905025331ce82021b0c000a0910a401d9f09a34f7c0418003fe34feafcbeaef348a800a0d908a7a6809cc7304017d820f70f0474d5e23cb17e38b67dc6dca282c6ca00961f4ec9edf2738d0f087b1d81e4871ef08e1798010863afb4eac4c44a376cb343be929c5be66a78cfd4456ae9ec6a99d97f4e1c3ff3583351db2147a65c0acef5c003fb544ab3a2e2dc4d43646f58b811a6c3a369d1f"

2
vendor/golang.org/x/crypto/openpgp/packet/signature.go сгенерированный поставляемый
Просмотреть файл

@@ -553,7 +553,7 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e
func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, config *Config) error {
h, err := userIdSignatureHash(id, pub, sig.Hash)
if err != nil {
return nil
return err
}
return sig.Sign(h, priv, config)
}

36
vendor/golang.org/x/crypto/openpgp/packet/signature_test.go сгенерированный поставляемый
Просмотреть файл

@@ -39,4 +39,40 @@ func TestSignatureReserialize(t *testing.T) {
}
}
func TestSignUserId(t *testing.T) {
sig := &Signature{
SigType: SigTypeGenericCert,
PubKeyAlgo: PubKeyAlgoRSA,
Hash: 0, // invalid hash function
}
packet, err := Read(readerFromHex(rsaPkDataHex))
if err != nil {
t.Fatalf("failed to deserialize public key: %v", err)
}
pubKey := packet.(*PublicKey)
packet, err = Read(readerFromHex(privKeyRSAHex))
if err != nil {
t.Fatalf("failed to deserialize private key: %v", err)
}
privKey := packet.(*PrivateKey)
err = sig.SignUserId("", pubKey, privKey, nil)
if err == nil {
t.Errorf("did not receive an error when expected")
}
sig.Hash = crypto.SHA256
err = privKey.Decrypt([]byte("testing"))
if err != nil {
t.Fatalf("failed to decrypt private key: %v", err)
}
err = sig.SignUserId("", pubKey, privKey, nil)
if err != nil {
t.Errorf("failed to sign user id: %v", err)
}
}
const signatureDataHex = "c2c05c04000102000605024cb45112000a0910ab105c91af38fb158f8d07ff5596ea368c5efe015bed6e78348c0f033c931d5f2ce5db54ce7f2a7e4b4ad64db758d65a7a71773edeab7ba2a9e0908e6a94a1175edd86c1d843279f045b021a6971a72702fcbd650efc393c5474d5b59a15f96d2eaad4c4c426797e0dcca2803ef41c6ff234d403eec38f31d610c344c06f2401c262f0993b2e66cad8a81ebc4322c723e0d4ba09fe917e8777658307ad8329adacba821420741009dfe87f007759f0982275d028a392c6ed983a0d846f890b36148c7358bdb8a516007fac760261ecd06076813831a36d0459075d1befa245ae7f7fb103d92ca759e9498fe60ef8078a39a3beda510deea251ea9f0a7f0df6ef42060f20780360686f3e400e"

2
vendor/golang.org/x/crypto/openpgp/write.go сгенерированный поставляемый
Просмотреть файл

@@ -231,7 +231,7 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint
}
cipher := packet.CipherFunction(candidateCiphers[0])
// If the cipher specifed by config is a candidate, we'll use that.
// If the cipher specified by config is a candidate, we'll use that.
configuredCipher := config.Cipher()
for _, c := range candidateCiphers {
cipherFunc := packet.CipherFunction(c)

2
vendor/golang.org/x/crypto/scrypt/scrypt.go сгенерированный поставляемый
Просмотреть файл

@@ -218,7 +218,7 @@ func smix(b []byte, r, N int, v, xy []uint32) {
// For example, you can get a derived key for e.g. AES-256 (which needs a
// 32-byte key) by doing:
//
// dk := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32)
// dk, err := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32)
//
// The recommended parameters for interactive logins as of 2009 are N=16384,
// r=8, p=1. They should be increased as memory latency and CPU parallelism

2
vendor/golang.org/x/crypto/sha3/keccakf.go сгенерированный поставляемый
Просмотреть файл

@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64 appengine gccgo
package sha3
// rc stores the round constants for use in the ι step.

13
vendor/golang.org/x/crypto/sha3/keccakf_amd64.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,13 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!appengine,!gccgo
package sha3
// This function is implemented in keccakf_amd64.s.
//go:noescape
func keccakF1600(a *[25]uint64)

392
vendor/golang.org/x/crypto/sha3/keccakf_amd64.s сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,392 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!appengine,!gccgo
// This code was translated into a form compatible with 6a from the public
// domain sources at https://github.com/gvanas/KeccakCodePackage
// Offsets in state
#define _ba (0*8)
#define _be (1*8)
#define _bi (2*8)
#define _bo (3*8)
#define _bu (4*8)
#define _ga (5*8)
#define _ge (6*8)
#define _gi (7*8)
#define _go (8*8)
#define _gu (9*8)
#define _ka (10*8)
#define _ke (11*8)
#define _ki (12*8)
#define _ko (13*8)
#define _ku (14*8)
#define _ma (15*8)
#define _me (16*8)
#define _mi (17*8)
#define _mo (18*8)
#define _mu (19*8)
#define _sa (20*8)
#define _se (21*8)
#define _si (22*8)
#define _so (23*8)
#define _su (24*8)
// Temporary registers
#define rT1 AX
// Round vars
#define rpState DI
#define rpStack SP
#define rDa BX
#define rDe CX
#define rDi DX
#define rDo R8
#define rDu R9
#define rBa R10
#define rBe R11
#define rBi R12
#define rBo R13
#define rBu R14
#define rCa SI
#define rCe BP
#define rCi rBi
#define rCo rBo
#define rCu R15
#define MOVQ_RBI_RCE MOVQ rBi, rCe
#define XORQ_RT1_RCA XORQ rT1, rCa
#define XORQ_RT1_RCE XORQ rT1, rCe
#define XORQ_RBA_RCU XORQ rBa, rCu
#define XORQ_RBE_RCU XORQ rBe, rCu
#define XORQ_RDU_RCU XORQ rDu, rCu
#define XORQ_RDA_RCA XORQ rDa, rCa
#define XORQ_RDE_RCE XORQ rDe, rCe
#define mKeccakRound(iState, oState, rc, B_RBI_RCE, G_RT1_RCA, G_RT1_RCE, G_RBA_RCU, K_RT1_RCA, K_RT1_RCE, K_RBA_RCU, M_RT1_RCA, M_RT1_RCE, M_RBE_RCU, S_RDU_RCU, S_RDA_RCA, S_RDE_RCE) \
/* Prepare round */ \
MOVQ rCe, rDa; \
ROLQ $1, rDa; \
\
MOVQ _bi(iState), rCi; \
XORQ _gi(iState), rDi; \
XORQ rCu, rDa; \
XORQ _ki(iState), rCi; \
XORQ _mi(iState), rDi; \
XORQ rDi, rCi; \
\
MOVQ rCi, rDe; \
ROLQ $1, rDe; \
\
MOVQ _bo(iState), rCo; \
XORQ _go(iState), rDo; \
XORQ rCa, rDe; \
XORQ _ko(iState), rCo; \
XORQ _mo(iState), rDo; \
XORQ rDo, rCo; \
\
MOVQ rCo, rDi; \
ROLQ $1, rDi; \
\
MOVQ rCu, rDo; \
XORQ rCe, rDi; \
ROLQ $1, rDo; \
\
MOVQ rCa, rDu; \
XORQ rCi, rDo; \
ROLQ $1, rDu; \
\
/* Result b */ \
MOVQ _ba(iState), rBa; \
MOVQ _ge(iState), rBe; \
XORQ rCo, rDu; \
MOVQ _ki(iState), rBi; \
MOVQ _mo(iState), rBo; \
MOVQ _su(iState), rBu; \
XORQ rDe, rBe; \
ROLQ $44, rBe; \
XORQ rDi, rBi; \
XORQ rDa, rBa; \
ROLQ $43, rBi; \
\
MOVQ rBe, rCa; \
MOVQ rc, rT1; \
ORQ rBi, rCa; \
XORQ rBa, rT1; \
XORQ rT1, rCa; \
MOVQ rCa, _ba(oState); \
\
XORQ rDu, rBu; \
ROLQ $14, rBu; \
MOVQ rBa, rCu; \
ANDQ rBe, rCu; \
XORQ rBu, rCu; \
MOVQ rCu, _bu(oState); \
\
XORQ rDo, rBo; \
ROLQ $21, rBo; \
MOVQ rBo, rT1; \
ANDQ rBu, rT1; \
XORQ rBi, rT1; \
MOVQ rT1, _bi(oState); \
\
NOTQ rBi; \
ORQ rBa, rBu; \
ORQ rBo, rBi; \
XORQ rBo, rBu; \
XORQ rBe, rBi; \
MOVQ rBu, _bo(oState); \
MOVQ rBi, _be(oState); \
B_RBI_RCE; \
\
/* Result g */ \
MOVQ _gu(iState), rBe; \
XORQ rDu, rBe; \
MOVQ _ka(iState), rBi; \
ROLQ $20, rBe; \
XORQ rDa, rBi; \
ROLQ $3, rBi; \
MOVQ _bo(iState), rBa; \
MOVQ rBe, rT1; \
ORQ rBi, rT1; \
XORQ rDo, rBa; \
MOVQ _me(iState), rBo; \
MOVQ _si(iState), rBu; \
ROLQ $28, rBa; \
XORQ rBa, rT1; \
MOVQ rT1, _ga(oState); \
G_RT1_RCA; \
\
XORQ rDe, rBo; \
ROLQ $45, rBo; \
MOVQ rBi, rT1; \
ANDQ rBo, rT1; \
XORQ rBe, rT1; \
MOVQ rT1, _ge(oState); \
G_RT1_RCE; \
\
XORQ rDi, rBu; \
ROLQ $61, rBu; \
MOVQ rBu, rT1; \
ORQ rBa, rT1; \
XORQ rBo, rT1; \
MOVQ rT1, _go(oState); \
\
ANDQ rBe, rBa; \
XORQ rBu, rBa; \
MOVQ rBa, _gu(oState); \
NOTQ rBu; \
G_RBA_RCU; \
\
ORQ rBu, rBo; \
XORQ rBi, rBo; \
MOVQ rBo, _gi(oState); \
\
/* Result k */ \
MOVQ _be(iState), rBa; \
MOVQ _gi(iState), rBe; \
MOVQ _ko(iState), rBi; \
MOVQ _mu(iState), rBo; \
MOVQ _sa(iState), rBu; \
XORQ rDi, rBe; \
ROLQ $6, rBe; \
XORQ rDo, rBi; \
ROLQ $25, rBi; \
MOVQ rBe, rT1; \
ORQ rBi, rT1; \
XORQ rDe, rBa; \
ROLQ $1, rBa; \
XORQ rBa, rT1; \
MOVQ rT1, _ka(oState); \
K_RT1_RCA; \
\
XORQ rDu, rBo; \
ROLQ $8, rBo; \
MOVQ rBi, rT1; \
ANDQ rBo, rT1; \
XORQ rBe, rT1; \
MOVQ rT1, _ke(oState); \
K_RT1_RCE; \
\
XORQ rDa, rBu; \
ROLQ $18, rBu; \
NOTQ rBo; \
MOVQ rBo, rT1; \
ANDQ rBu, rT1; \
XORQ rBi, rT1; \
MOVQ rT1, _ki(oState); \
\
MOVQ rBu, rT1; \
ORQ rBa, rT1; \
XORQ rBo, rT1; \
MOVQ rT1, _ko(oState); \
\
ANDQ rBe, rBa; \
XORQ rBu, rBa; \
MOVQ rBa, _ku(oState); \
K_RBA_RCU; \
\
/* Result m */ \
MOVQ _ga(iState), rBe; \
XORQ rDa, rBe; \
MOVQ _ke(iState), rBi; \
ROLQ $36, rBe; \
XORQ rDe, rBi; \
MOVQ _bu(iState), rBa; \
ROLQ $10, rBi; \
MOVQ rBe, rT1; \
MOVQ _mi(iState), rBo; \
ANDQ rBi, rT1; \
XORQ rDu, rBa; \
MOVQ _so(iState), rBu; \
ROLQ $27, rBa; \
XORQ rBa, rT1; \
MOVQ rT1, _ma(oState); \
M_RT1_RCA; \
\
XORQ rDi, rBo; \
ROLQ $15, rBo; \
MOVQ rBi, rT1; \
ORQ rBo, rT1; \
XORQ rBe, rT1; \
MOVQ rT1, _me(oState); \
M_RT1_RCE; \
\
XORQ rDo, rBu; \
ROLQ $56, rBu; \
NOTQ rBo; \
MOVQ rBo, rT1; \
ORQ rBu, rT1; \
XORQ rBi, rT1; \
MOVQ rT1, _mi(oState); \
\
ORQ rBa, rBe; \
XORQ rBu, rBe; \
MOVQ rBe, _mu(oState); \
\
ANDQ rBa, rBu; \
XORQ rBo, rBu; \
MOVQ rBu, _mo(oState); \
M_RBE_RCU; \
\
/* Result s */ \
MOVQ _bi(iState), rBa; \
MOVQ _go(iState), rBe; \
MOVQ _ku(iState), rBi; \
XORQ rDi, rBa; \
MOVQ _ma(iState), rBo; \
ROLQ $62, rBa; \
XORQ rDo, rBe; \
MOVQ _se(iState), rBu; \
ROLQ $55, rBe; \
\
XORQ rDu, rBi; \
MOVQ rBa, rDu; \
XORQ rDe, rBu; \
ROLQ $2, rBu; \
ANDQ rBe, rDu; \
XORQ rBu, rDu; \
MOVQ rDu, _su(oState); \
\
ROLQ $39, rBi; \
S_RDU_RCU; \
NOTQ rBe; \
XORQ rDa, rBo; \
MOVQ rBe, rDa; \
ANDQ rBi, rDa; \
XORQ rBa, rDa; \
MOVQ rDa, _sa(oState); \
S_RDA_RCA; \
\
ROLQ $41, rBo; \
MOVQ rBi, rDe; \
ORQ rBo, rDe; \
XORQ rBe, rDe; \
MOVQ rDe, _se(oState); \
S_RDE_RCE; \
\
MOVQ rBo, rDi; \
MOVQ rBu, rDo; \
ANDQ rBu, rDi; \
ORQ rBa, rDo; \
XORQ rBi, rDi; \
XORQ rBo, rDo; \
MOVQ rDi, _si(oState); \
MOVQ rDo, _so(oState) \
// func keccakF1600(state *[25]uint64)
TEXT ·keccakF1600(SB), 0, $200-8
MOVQ state+0(FP), rpState
SUBQ $(8*25), SP
// Convert the user state into an internal state
NOTQ _be(rpState)
NOTQ _bi(rpState)
NOTQ _go(rpState)
NOTQ _ki(rpState)
NOTQ _mi(rpState)
NOTQ _sa(rpState)
// Execute the KeccakF permutation
MOVQ _ba(rpState), rCa
MOVQ _be(rpState), rCe
MOVQ _bu(rpState), rCu
XORQ _ga(rpState), rCa
XORQ _ge(rpState), rCe
XORQ _gu(rpState), rCu
XORQ _ka(rpState), rCa
XORQ _ke(rpState), rCe
XORQ _ku(rpState), rCu
XORQ _ma(rpState), rCa
XORQ _me(rpState), rCe
XORQ _mu(rpState), rCu
XORQ _sa(rpState), rCa
XORQ _se(rpState), rCe
MOVQ _si(rpState), rDi
MOVQ _so(rpState), rDo
XORQ _su(rpState), rCu
mKeccakRound(rpState, rpStack, $0x0000000000000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x0000000000008082, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpState, rpStack, $0x800000000000808a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x8000000080008000, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpState, rpStack, $0x000000000000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x8000000000008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpState, rpStack, $0x000000000000008a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x0000000000000088, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpState, rpStack, $0x0000000080008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x000000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpState, rpStack, $0x000000008000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x800000000000008b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpState, rpStack, $0x8000000000008089, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x8000000000008003, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpState, rpStack, $0x8000000000008002, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x8000000000000080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpState, rpStack, $0x000000000000800a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x800000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x8000000000008080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpState, rpStack, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
mKeccakRound(rpStack, rpState, $0x8000000080008008, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP)
// Revert the internal state to the user state
NOTQ _be(rpState)
NOTQ _bi(rpState)
NOTQ _go(rpState)
NOTQ _ki(rpState)
NOTQ _mi(rpState)
NOTQ _sa(rpState)
ADDQ $(8*25), SP
RET

2
vendor/golang.org/x/crypto/sha3/sha3.go сгенерированный поставляемый
Просмотреть файл

@@ -42,7 +42,7 @@ type state struct {
storage [maxRate]byte
// Specific to SHA-3 and SHAKE.
fixedOutput bool // whether this is a fixed-ouput-length instance
fixedOutput bool // whether this is a fixed-output-length instance
outputLen int // the default output size in bytes
state spongeDirection // whether the sponge is absorbing or squeezing
}

55
vendor/golang.org/x/crypto/ssh/agent/client.go сгенерированный поставляемый
Просмотреть файл

@@ -25,6 +25,7 @@ import (
"math/big"
"sync"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/ssh"
)
@@ -423,6 +424,14 @@ type ecdsaKeyMsg struct {
Constraints []byte `ssh:"rest"`
}
type ed25519KeyMsg struct {
Type string `sshtype:"17|25"`
Pub []byte
Priv []byte
Comments string
Constraints []byte `ssh:"rest"`
}
// Insert adds a private key to the agent.
func (c *client) insertKey(s interface{}, comment string, constraints []byte) error {
var req []byte
@@ -464,6 +473,14 @@ func (c *client) insertKey(s interface{}, comment string, constraints []byte) er
Comments: comment,
Constraints: constraints,
})
case *ed25519.PrivateKey:
req = ssh.Marshal(ed25519KeyMsg{
Type: ssh.KeyAlgoED25519,
Pub: []byte(*k)[32:],
Priv: []byte(*k),
Comments: comment,
Constraints: constraints,
})
default:
return fmt.Errorf("agent: unsupported key type %T", s)
}
@@ -510,7 +527,16 @@ type ecdsaCertMsg struct {
Constraints []byte `ssh:"rest"`
}
// Insert adds a private key to the agent. If a certificate is given,
type ed25519CertMsg struct {
Type string `sshtype:"17|25"`
CertBytes []byte
Pub []byte
Priv []byte
Comments string
Constraints []byte `ssh:"rest"`
}
// Add adds a private key to the agent. If a certificate is given,
// that certificate is added instead as public key.
func (c *client) Add(key AddedKey) error {
var constraints []byte
@@ -554,17 +580,28 @@ func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string
})
case *dsa.PrivateKey:
req = ssh.Marshal(dsaCertMsg{
Type: cert.Type(),
CertBytes: cert.Marshal(),
X: k.X,
Comments: comment,
Type: cert.Type(),
CertBytes: cert.Marshal(),
X: k.X,
Comments: comment,
Constraints: constraints,
})
case *ecdsa.PrivateKey:
req = ssh.Marshal(ecdsaCertMsg{
Type: cert.Type(),
CertBytes: cert.Marshal(),
D: k.D,
Comments: comment,
Type: cert.Type(),
CertBytes: cert.Marshal(),
D: k.D,
Comments: comment,
Constraints: constraints,
})
case *ed25519.PrivateKey:
req = ssh.Marshal(ed25519CertMsg{
Type: cert.Type(),
CertBytes: cert.Marshal(),
Pub: []byte(*k)[32:],
Priv: []byte(*k),
Comments: comment,
Constraints: constraints,
})
default:
return fmt.Errorf("agent: unsupported key type %T", s)

42
vendor/golang.org/x/crypto/ssh/agent/client_test.go сгенерированный поставляемый
Просмотреть файл

@@ -14,6 +14,7 @@ import (
"path/filepath"
"strconv"
"testing"
"time"
"golang.org/x/crypto/ssh"
)
@@ -139,7 +140,7 @@ func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Ce
}
func TestAgent(t *testing.T) {
for _, keyType := range []string{"rsa", "dsa", "ecdsa"} {
for _, keyType := range []string{"rsa", "dsa", "ecdsa", "ed25519"} {
testAgent(t, testPrivateKeys[keyType], nil, 0)
}
}
@@ -285,3 +286,42 @@ func testLockAgent(agent Agent, t *testing.T) {
t.Errorf("Want 1 keys, got %v", keys)
}
}
func TestAgentLifetime(t *testing.T) {
agent, _, cleanup := startAgent(t)
defer cleanup()
for _, keyType := range []string{"rsa", "dsa", "ecdsa"} {
// Add private keys to the agent.
err := agent.Add(AddedKey{
PrivateKey: testPrivateKeys[keyType],
Comment: "comment",
LifetimeSecs: 1,
})
if err != nil {
t.Fatalf("add: %v", err)
}
// Add certs to the agent.
cert := &ssh.Certificate{
Key: testPublicKeys[keyType],
ValidBefore: ssh.CertTimeInfinity,
CertType: ssh.UserCert,
}
cert.SignCert(rand.Reader, testSigners[keyType])
err = agent.Add(AddedKey{
PrivateKey: testPrivateKeys[keyType],
Certificate: cert,
Comment: "comment",
LifetimeSecs: 1,
})
if err != nil {
t.Fatalf("add: %v", err)
}
}
time.Sleep(1100 * time.Millisecond)
if keys, err := agent.List(); err != nil {
t.Errorf("List: %v", err)
} else if len(keys) != 0 {
t.Errorf("Want 0 keys, got %v", len(keys))
}
}

35
vendor/golang.org/x/crypto/ssh/agent/server.go сгенерированный поставляемый
Просмотреть файл

@@ -16,6 +16,7 @@ import (
"log"
"math/big"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/ssh"
)
@@ -175,6 +176,15 @@ func parseRSAKey(req []byte) (*AddedKey, error) {
return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil
}
func parseEd25519Key(req []byte) (*AddedKey, error) {
var k ed25519KeyMsg
if err := ssh.Unmarshal(req, &k); err != nil {
return nil, err
}
priv := ed25519.PrivateKey(k.Priv)
return &AddedKey{PrivateKey: &priv, Comment: k.Comments}, nil
}
func parseDSAKey(req []byte) (*AddedKey, error) {
var k dsaKeyMsg
if err := ssh.Unmarshal(req, &k); err != nil {
@@ -219,6 +229,23 @@ func unmarshalECDSA(curveName string, keyBytes []byte, privScalar *big.Int) (pri
return priv, nil
}
func parseEd25519Cert(req []byte) (*AddedKey, error) {
var k ed25519CertMsg
if err := ssh.Unmarshal(req, &k); err != nil {
return nil, err
}
pubKey, err := ssh.ParsePublicKey(k.CertBytes)
if err != nil {
return nil, err
}
priv := ed25519.PrivateKey(k.Priv)
cert, ok := pubKey.(*ssh.Certificate)
if !ok {
return nil, errors.New("agent: bad ED25519 certificate")
}
return &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}, nil
}
func parseECDSAKey(req []byte) (*AddedKey, error) {
var k ecdsaKeyMsg
if err := ssh.Unmarshal(req, &k); err != nil {
@@ -230,7 +257,7 @@ func parseECDSAKey(req []byte) (*AddedKey, error) {
return nil, err
}
return &AddedKey{PrivateKey: &priv, Comment: k.Comments}, nil
return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil
}
func parseRSACert(req []byte) (*AddedKey, error) {
@@ -366,13 +393,17 @@ func (s *server) insertIdentity(req []byte) error {
case ssh.KeyAlgoDSA:
addedKey, err = parseDSAKey(req)
case ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521:
addedKey, err = parseECDSACert(req)
addedKey, err = parseECDSAKey(req)
case ssh.KeyAlgoED25519:
addedKey, err = parseEd25519Key(req)
case ssh.CertAlgoRSAv01:
addedKey, err = parseRSACert(req)
case ssh.CertAlgoDSAv01:
addedKey, err = parseDSACert(req)
case ssh.CertAlgoECDSA256v01, ssh.CertAlgoECDSA384v01, ssh.CertAlgoECDSA521v01:
addedKey, err = parseECDSACert(req)
case ssh.CertAlgoED25519v01:
addedKey, err = parseEd25519Cert(req)
default:
return fmt.Errorf("agent: not implemented: %q", record.Type)
}

21
vendor/golang.org/x/crypto/ssh/agent/server_test.go сгенерированный поставляемый
Просмотреть файл

@@ -150,9 +150,27 @@ func TestKeyTypes(t *testing.T) {
if err := addKeyToAgent(v); err != nil {
t.Errorf("error adding key type %s, %v", k, err)
}
if err := addCertToAgentSock(v, nil); err != nil {
t.Errorf("error adding key type %s, %v", k, err)
}
}
}
func addCertToAgentSock(key crypto.PrivateKey, cert *ssh.Certificate) error {
a, b, err := netPipe()
if err != nil {
return err
}
agentServer := NewKeyring()
go ServeAgent(agentServer, a)
agentClient := NewClient(b)
if err := agentClient.Add(AddedKey{PrivateKey: key, Certificate: cert}); err != nil {
return fmt.Errorf("add: %v", err)
}
return verifyKey(agentClient)
}
func addCertToAgent(key crypto.PrivateKey, cert *ssh.Certificate) error {
sshAgent := NewKeyring()
if err := sshAgent.Add(AddedKey{PrivateKey: key, Certificate: cert}); err != nil {
@@ -182,5 +200,8 @@ func TestCertTypes(t *testing.T) {
if err := addCertToAgent(testPrivateKeys[keyType], cert); err != nil {
t.Fatalf("%v", err)
}
if err := addCertToAgentSock(testPrivateKeys[keyType], cert); err != nil {
t.Fatalf("%v", err)
}
}
}

2
vendor/golang.org/x/crypto/ssh/agent/testdata_test.go сгенерированный поставляемый
Просмотреть файл

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places:
// IMPLEMENTATION NOTE: To avoid a package loop, this file is in three places:
// ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three
// instances.

2
vendor/golang.org/x/crypto/ssh/channel.go сгенерированный поставляемый
Просмотреть файл

@@ -67,6 +67,8 @@ type Channel interface {
// boolean, otherwise the return value will be false. Channel
// requests are out-of-band messages so they may be sent even
// if the data stream is closed or blocked by flow control.
// If the channel is closed before a reply is returned, io.EOF
// is returned.
SendRequest(name string, wantReply bool, payload []byte) (bool, error)
// Stderr returns an io.ReadWriter that writes to this channel

39
vendor/golang.org/x/crypto/ssh/cipher.go сгенерированный поставляемый
Просмотреть файл

@@ -7,6 +7,7 @@ package ssh
import (
"crypto/aes"
"crypto/cipher"
"crypto/des"
"crypto/rc4"
"crypto/subtle"
"encoding/binary"
@@ -121,6 +122,9 @@ var cipherModes = map[string]*streamCipherMode{
// You should expect that an active attacker can recover plaintext if
// you do.
aes128cbcID: {16, aes.BlockSize, 0, nil},
// 3des-cbc is insecure and is disabled by default.
tripledescbcID: {24, des.BlockSize, 0, nil},
}
// prefixLen is the length of the packet prefix that contains the packet length
@@ -368,12 +372,7 @@ type cbcCipher struct {
oracleCamouflage uint32
}
func newAESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
func newCBCCipher(c cipher.Block, iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
cbc := &cbcCipher{
mac: macModes[algs.MAC].new(macKey),
decrypter: cipher.NewCBCDecrypter(c, iv),
@@ -387,6 +386,34 @@ func newAESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCi
return cbc, nil
}
func newAESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
cbc, err := newCBCCipher(c, iv, key, macKey, algs)
if err != nil {
return nil, err
}
return cbc, nil
}
func newTripleDESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
c, err := des.NewTripleDESCipher(key)
if err != nil {
return nil, err
}
cbc, err := newCBCCipher(c, iv, key, macKey, algs)
if err != nil {
return nil, err
}
return cbc, nil
}
func maxUInt32(a, b int) uint32 {
if a > b {
return uint32(a)

2
vendor/golang.org/x/crypto/ssh/cipher_test.go сгенерированный поставляемый
Просмотреть файл

@@ -21,7 +21,7 @@ func TestDefaultCiphersExist(t *testing.T) {
}
func TestPacketCiphers(t *testing.T) {
// Still test aes128cbc cipher althought it's commented out.
// Still test aes128cbc cipher although it's commented out.
cipherModes[aes128cbcID] = &streamCipherMode{16, aes.BlockSize, 0, nil}
defer delete(cipherModes, aes128cbcID)

34
vendor/golang.org/x/crypto/ssh/client_auth.go сгенерированный поставляемый
Просмотреть файл

@@ -437,3 +437,37 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
}
}
}
type retryableAuthMethod struct {
authMethod AuthMethod
maxTries int
}
func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader) (ok bool, methods []string, err error) {
for i := 0; r.maxTries <= 0 || i < r.maxTries; i++ {
ok, methods, err = r.authMethod.auth(session, user, c, rand)
if ok || err != nil { // either success or error terminate
return ok, methods, err
}
}
return ok, methods, err
}
func (r *retryableAuthMethod) method() string {
return r.authMethod.method()
}
// RetryableAuthMethod is a decorator for other auth methods enabling them to
// be retried up to maxTries before considering that AuthMethod itself failed.
// If maxTries is <= 0, will retry indefinitely
//
// This is useful for interactive clients using challenge/response type
// authentication (e.g. Keyboard-Interactive, Password, etc) where the user
// could mistype their response resulting in the server issuing a
// SSH_MSG_USERAUTH_FAILURE (rfc4252 #8 [password] and rfc4256 #3.4
// [keyboard-interactive]); Without this decorator, the non-retryable
// AuthMethod would be removed from future consideration, and never tried again
// (and so the user would never be able to retry their entry).
func RetryableAuthMethod(auth AuthMethod, maxTries int) AuthMethod {
return &retryableAuthMethod{authMethod: auth, maxTries: maxTries}
}

81
vendor/golang.org/x/crypto/ssh/client_auth_test.go сгенерированный поставляемый
Просмотреть файл

@@ -9,6 +9,7 @@ import (
"crypto/rand"
"errors"
"fmt"
"os"
"strings"
"testing"
)
@@ -243,6 +244,9 @@ func TestClientUnsupportedCipher(t *testing.T) {
}
func TestClientUnsupportedKex(t *testing.T) {
if os.Getenv("GO_BUILDER_NAME") != "" {
t.Skip("skipping known-flaky test on the Go build dashboard; see golang.org/issue/15198")
}
config := &ClientConfig{
User: "testuser",
Auth: []AuthMethod{
@@ -296,7 +300,7 @@ func TestClientLoginCert(t *testing.T) {
t.Log("sign with wrong key")
cert.SignCert(rand.Reader, testSigners["dsa"])
if err := tryAuth(t, clientConfig); err == nil {
t.Errorf("cert login passed with non-authoritive key")
t.Errorf("cert login passed with non-authoritative key")
}
t.Log("host cert")
@@ -391,3 +395,78 @@ func TestPermissionsPassing(t *testing.T) {
func TestNoPermissionsPassing(t *testing.T) {
testPermissionsPassing(false, t)
}
func TestRetryableAuth(t *testing.T) {
n := 0
passwords := []string{"WRONG1", "WRONG2"}
config := &ClientConfig{
User: "testuser",
Auth: []AuthMethod{
RetryableAuthMethod(PasswordCallback(func() (string, error) {
p := passwords[n]
n++
return p, nil
}), 2),
PublicKeys(testSigners["rsa"]),
},
}
if err := tryAuth(t, config); err != nil {
t.Fatalf("unable to dial remote side: %s", err)
}
if n != 2 {
t.Fatalf("Did not try all passwords")
}
}
func ExampleRetryableAuthMethod(t *testing.T) {
user := "testuser"
NumberOfPrompts := 3
// Normally this would be a callback that prompts the user to answer the
// provided questions
Cb := func(user, instruction string, questions []string, echos []bool) (answers []string, err error) {
return []string{"answer1", "answer2"}, nil
}
config := &ClientConfig{
User: user,
Auth: []AuthMethod{
RetryableAuthMethod(KeyboardInteractiveChallenge(Cb), NumberOfPrompts),
},
}
if err := tryAuth(t, config); err != nil {
t.Fatalf("unable to dial remote side: %s", err)
}
}
// Test if username is received on server side when NoClientAuth is used
func TestClientAuthNone(t *testing.T) {
user := "testuser"
serverConfig := &ServerConfig{
NoClientAuth: true,
}
serverConfig.AddHostKey(testSigners["rsa"])
clientConfig := &ClientConfig{
User: user,
}
c1, c2, err := netPipe()
if err != nil {
t.Fatalf("netPipe: %v", err)
}
defer c1.Close()
defer c2.Close()
go NewClientConn(c2, "", clientConfig)
serverConn, err := newServer(c1, serverConfig)
if err != nil {
t.Fatal("newServer: %v", err)
}
if serverConn.User() != user {
t.Fatalf("server: got %q, want %q", serverConn.User(), user)
}
}

2
vendor/golang.org/x/crypto/ssh/common.go сгенерированный поставляемый
Просмотреть файл

@@ -44,7 +44,7 @@ var supportedKexAlgos = []string{
// of authenticating servers) in preference order.
var supportedHostKeyAlgos = []string{
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,
CertAlgoECDSA384v01, CertAlgoECDSA521v01,
CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,
KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
KeyAlgoRSA, KeyAlgoDSA,

1
vendor/golang.org/x/crypto/ssh/connection.go сгенерированный поставляемый
Просмотреть файл

@@ -23,7 +23,6 @@ func (e *OpenChannelError) Error() string {
// ConnMetadata holds metadata for the connection.
type ConnMetadata interface {
// User returns the user ID for this connection.
// It is empty if no authentication is used.
User() string
// SessionID returns the sesson hash, also denoted by H.

43
vendor/golang.org/x/crypto/ssh/handshake.go сгенерированный поставляемый
Просмотреть файл

@@ -174,15 +174,7 @@ func (t *handshakeTransport) readOnePacket() ([]byte, error) {
t.mu.Lock()
// By default, a key exchange is hidden from higher layers by
// translating it into msgIgnore.
successPacket := []byte{msgIgnore}
if t.sessionID == nil {
// sendKexInit() for the first kex waits for
// msgNewKeys so the authentication process is
// guaranteed to happen over an encrypted transport.
successPacket = []byte{msgNewKeys}
}
firstKex := t.sessionID == nil
err = t.enterKeyExchangeLocked(p)
if err != nil {
@@ -192,7 +184,7 @@ func (t *handshakeTransport) readOnePacket() ([]byte, error) {
}
if debugHandshake {
log.Printf("%s exited key exchange, err %v", t.id(), err)
log.Printf("%s exited key exchange (first %v), err %v", t.id(), firstKex, err)
}
// Unblock writers.
@@ -207,6 +199,17 @@ func (t *handshakeTransport) readOnePacket() ([]byte, error) {
}
t.readSinceKex = 0
// By default, a key exchange is hidden from higher layers by
// translating it into msgIgnore.
successPacket := []byte{msgIgnore}
if firstKex {
// sendKexInit() for the first kex waits for
// msgNewKeys so the authentication process is
// guaranteed to happen over an encrypted transport.
successPacket = []byte{msgNewKeys}
}
return successPacket, nil
}
@@ -225,16 +228,15 @@ const (
// close the underlying transport. This function is safe for
// concurrent use by multiple goroutines.
func (t *handshakeTransport) sendKexInit(isFirst keyChangeCategory) error {
var err error
t.mu.Lock()
// If this is the initial key change, but we already have a sessionID,
// then do nothing because the key exchange has already completed
// asynchronously.
if isFirst && t.sessionID != nil {
t.mu.Unlock()
return nil
if !isFirst || t.sessionID == nil {
_, _, err = t.sendKexInitLocked(isFirst)
}
_, _, err := t.sendKexInitLocked(isFirst)
t.mu.Unlock()
if err != nil {
return err
@@ -369,7 +371,16 @@ func (t *handshakeTransport) enterKeyExchangeLocked(otherInitPacket []byte) erro
}
// We don't send FirstKexFollows, but we handle receiving it.
if otherInit.FirstKexFollows && algs.kex != otherInit.KexAlgos[0] {
//
// RFC 4253 section 7 defines the kex and the agreement method for
// first_kex_packet_follows. It states that the guessed packet
// should be ignored if the "kex algorithm and/or the host
// key algorithm is guessed wrong (server and client have
// different preferred algorithm), or if any of the other
// algorithms cannot be agreed upon". The other algorithms have
// already been checked above so the kex algorithm and host key
// algorithm are checked here.
if otherInit.FirstKexFollows && (clientInit.KexAlgos[0] != serverInit.KexAlgos[0] || clientInit.ServerHostKeyAlgos[0] != serverInit.ServerHostKeyAlgos[0]) {
// other side sent a kex message for the wrong algorithm,
// which we have to ignore.
if _, err := t.conn.readPacket(); err != nil {

2
vendor/golang.org/x/crypto/ssh/keys.go сгенерированный поставляемый
Просмотреть файл

@@ -125,7 +125,7 @@ func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey
continue
}
// Strip out the begining of the known_host key.
// Strip out the beginning of the known_host key.
// This is either an optional marker or a (set of) hostname(s).
keyFields := bytes.Fields(in)
if len(keyFields) < 3 || len(keyFields) > 5 {

1
vendor/golang.org/x/crypto/ssh/server.go сгенерированный поставляемый
Просмотреть файл

@@ -284,7 +284,6 @@ userAuthLoop:
switch userAuthReq.Method {
case "none":
if config.NoClientAuth {
s.user = ""
authErr = nil
}
case "password":

33
vendor/golang.org/x/crypto/ssh/session.go сгенерированный поставляемый
Просмотреть файл

@@ -9,6 +9,7 @@ package ssh
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"io"
@@ -281,9 +282,10 @@ func (s *Session) Start(cmd string) error {
// copying stdin, stdout, and stderr, and exits with a zero exit
// status.
//
// If the command fails to run or doesn't complete successfully, the
// error is of type *ExitError. Other error types may be
// returned for I/O problems.
// If the remote server does not send an exit status, an error of type
// *ExitMissingError is returned. If the command completes
// unsuccessfully or is interrupted by a signal, the error is of type
// *ExitError. Other error types may be returned for I/O problems.
func (s *Session) Run(cmd string) error {
err := s.Start(cmd)
if err != nil {
@@ -370,9 +372,10 @@ func (s *Session) start() error {
// copying stdin, stdout, and stderr, and exits with a zero exit
// status.
//
// If the command fails to run or doesn't complete successfully, the
// error is of type *ExitError. Other error types may be
// returned for I/O problems.
// If the remote server does not send an exit status, an error of type
// *ExitMissingError is returned. If the command completes
// unsuccessfully or is interrupted by a signal, the error is of type
// *ExitError. Other error types may be returned for I/O problems.
func (s *Session) Wait() error {
if !s.started {
return errors.New("ssh: session not started")
@@ -400,8 +403,7 @@ func (s *Session) wait(reqs <-chan *Request) error {
for msg := range reqs {
switch msg.Type {
case "exit-status":
d := msg.Payload
wm.status = int(d[0])<<24 | int(d[1])<<16 | int(d[2])<<8 | int(d[3])
wm.status = int(binary.BigEndian.Uint32(msg.Payload))
case "exit-signal":
var sigval struct {
Signal string
@@ -431,16 +433,29 @@ func (s *Session) wait(reqs <-chan *Request) error {
if wm.status == -1 {
// exit-status was never sent from server
if wm.signal == "" {
return errors.New("wait: remote command exited without exit status or exit signal")
// signal was not sent either. RFC 4254
// section 6.10 recommends against this
// behavior, but it is allowed, so we let
// clients handle it.
return &ExitMissingError{}
}
wm.status = 128
if _, ok := signals[Signal(wm.signal)]; ok {
wm.status += signals[Signal(wm.signal)]
}
}
return &ExitError{wm}
}
// ExitMissingError is returned if a session is torn down cleanly, but
// the server sends no confirmation of the exit status.
type ExitMissingError struct{}
func (e *ExitMissingError) Error() string {
return "wait: remote command exited without exit status or exit signal"
}
func (s *Session) stdin() {
if s.stdinpipe {
return

8
vendor/golang.org/x/crypto/ssh/session_test.go сгенерированный поставляемый
Просмотреть файл

@@ -297,7 +297,6 @@ func TestUnknownExitSignal(t *testing.T) {
}
}
// Test WaitMsg is not returned if the channel closes abruptly.
func TestExitWithoutStatusOrSignal(t *testing.T) {
conn := dial(exitWithoutSignalOrStatus, t)
defer conn.Close()
@@ -313,11 +312,8 @@ func TestExitWithoutStatusOrSignal(t *testing.T) {
if err == nil {
t.Fatalf("expected command to fail but it didn't")
}
_, ok := err.(*ExitError)
if ok {
// you can't actually test for errors.errorString
// because it's not exported.
t.Fatalf("expected *errorString but got %T", err)
if _, ok := err.(*ExitMissingError); !ok {
t.Fatalf("got %T want *ExitMissingError", err)
}
}

9
vendor/golang.org/x/crypto/ssh/terminal/util.go сгенерированный поставляемый
Просмотреть файл

@@ -44,8 +44,13 @@ func MakeRaw(fd int) (*State, error) {
}
newState := oldState.termios
newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF
newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
// This attempts to replicate the behaviour documented for cfmakeraw in
// the termios(3) manpage.
newState.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON
newState.Oflag &^= syscall.OPOST
newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
newState.Cflag &^= syscall.CSIZE | syscall.PARENB
newState.Cflag |= syscall.CS8
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
return nil, err
}

10
vendor/golang.org/x/crypto/ssh/test/session_test.go сгенерированный поставляемый
Просмотреть файл

@@ -280,16 +280,16 @@ func TestCiphers(t *testing.T) {
var config ssh.Config
config.SetDefaults()
cipherOrder := config.Ciphers
// This cipher will not be tested when commented out in cipher.go it will
// These ciphers will not be tested when commented out in cipher.go it will
// fallback to the next available as per line 292.
cipherOrder = append(cipherOrder, "aes128-cbc")
cipherOrder = append(cipherOrder, "aes128-cbc", "3des-cbc")
for _, ciph := range cipherOrder {
server := newServer(t)
defer server.Shutdown()
conf := clientConfig()
conf.Ciphers = []string{ciph}
// Don't fail if sshd doesnt have the cipher.
// Don't fail if sshd doesn't have the cipher.
conf.Ciphers = append(conf.Ciphers, cipherOrder...)
conn, err := server.TryDial(conf)
if err == nil {
@@ -310,7 +310,7 @@ func TestMACs(t *testing.T) {
defer server.Shutdown()
conf := clientConfig()
conf.MACs = []string{mac}
// Don't fail if sshd doesnt have the MAC.
// Don't fail if sshd doesn't have the MAC.
conf.MACs = append(conf.MACs, macOrder...)
if conn, err := server.TryDial(conf); err == nil {
conn.Close()
@@ -328,7 +328,7 @@ func TestKeyExchanges(t *testing.T) {
server := newServer(t)
defer server.Shutdown()
conf := clientConfig()
// Don't fail if sshd doesnt have the kex.
// Don't fail if sshd doesn't have the kex.
conf.KeyExchanges = append([]string{kex}, kexOrder...)
conn, err := server.TryDial(conf)
if err == nil {

2
vendor/golang.org/x/crypto/ssh/test/testdata_test.go сгенерированный поставляемый
Просмотреть файл

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places:
// IMPLEMENTATION NOTE: To avoid a package loop, this file is in three places:
// ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three
// instances.

2
vendor/golang.org/x/crypto/ssh/testdata_test.go сгенерированный поставляемый
Просмотреть файл

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places:
// IMPLEMENTATION NOTE: To avoid a package loop, this file is in three places:
// ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three
// instances.

9
vendor/golang.org/x/crypto/ssh/transport.go сгенерированный поставляемый
Просмотреть файл

@@ -11,8 +11,9 @@ import (
)
const (
gcmCipherID = "aes128-gcm@openssh.com"
aes128cbcID = "aes128-cbc"
gcmCipherID = "aes128-gcm@openssh.com"
aes128cbcID = "aes128-cbc"
tripledescbcID = "3des-cbc"
)
// packetConn represents a transport that implements packet based
@@ -219,6 +220,10 @@ func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (pac
return newAESCBCCipher(iv, key, macKey, algs)
}
if algs.Cipher == tripledescbcID {
return newTripleDESCBCCipher(iv, key, macKey, algs)
}
c := &streamPacketCipher{
mac: macModes[algs.MAC].new(macKey),
}

14
vendor/golang.org/x/image/colornames/gen.go сгенерированный поставляемый
Просмотреть файл

@@ -143,8 +143,9 @@ func writeColorNames(w io.Writer, m map[string]color.RGBA) {
fmt.Fprintln(w, "// Map contains named colors defined in the SVG 1.1 spec.")
fmt.Fprintln(w, "var Map = map[string]color.RGBA{")
for _, k := range keys {
c := m[k]
fmt.Fprintf(w, "%q:color.RGBA{%#02x, %#02x, %#02x, %#02x}, // rgb(%d, %d, %d)\n",
k, m[k].R, m[k].G, m[k].B, m[k].A, m[k].R, m[k].G, m[k].B)
k, c.R, c.G, c.B, c.A, c.R, c.G, c.B)
}
fmt.Fprintln(w, "}\n")
fmt.Fprintln(w, "// Names contains the color names defined in the SVG 1.1 spec.")
@@ -152,7 +153,16 @@ func writeColorNames(w io.Writer, m map[string]color.RGBA) {
for _, k := range keys {
fmt.Fprintf(w, "%q,\n", k)
}
fmt.Fprintln(w, "}")
fmt.Fprintln(w, "}\n")
fmt.Fprintln(w, "var (")
for _, k := range keys {
c := m[k]
// Make the upper case version of k: "Darkred" instead of "darkred".
k = string(k[0]-0x20) + k[1:]
fmt.Fprintf(w, "%s=color.RGBA{%#02x, %#02x, %#02x, %#02x} // rgb(%d, %d, %d)\n",
k, c.R, c.G, c.B, c.A, c.R, c.G, c.B)
}
fmt.Fprintln(w, ")")
}
const url = "http://www.w3.org/TR/SVG/types.html"

150
vendor/golang.org/x/image/colornames/table.go сгенерированный поставляемый
Просмотреть файл

@@ -305,3 +305,153 @@ var Names = []string{
"yellow",
"yellowgreen",
}
var (
Aliceblue = color.RGBA{0xf0, 0xf8, 0xff, 0xff} // rgb(240, 248, 255)
Antiquewhite = color.RGBA{0xfa, 0xeb, 0xd7, 0xff} // rgb(250, 235, 215)
Aqua = color.RGBA{0x00, 0xff, 0xff, 0xff} // rgb(0, 255, 255)
Aquamarine = color.RGBA{0x7f, 0xff, 0xd4, 0xff} // rgb(127, 255, 212)
Azure = color.RGBA{0xf0, 0xff, 0xff, 0xff} // rgb(240, 255, 255)
Beige = color.RGBA{0xf5, 0xf5, 0xdc, 0xff} // rgb(245, 245, 220)
Bisque = color.RGBA{0xff, 0xe4, 0xc4, 0xff} // rgb(255, 228, 196)
Black = color.RGBA{0x00, 0x00, 0x00, 0xff} // rgb(0, 0, 0)
Blanchedalmond = color.RGBA{0xff, 0xeb, 0xcd, 0xff} // rgb(255, 235, 205)
Blue = color.RGBA{0x00, 0x00, 0xff, 0xff} // rgb(0, 0, 255)
Blueviolet = color.RGBA{0x8a, 0x2b, 0xe2, 0xff} // rgb(138, 43, 226)
Brown = color.RGBA{0xa5, 0x2a, 0x2a, 0xff} // rgb(165, 42, 42)
Burlywood = color.RGBA{0xde, 0xb8, 0x87, 0xff} // rgb(222, 184, 135)
Cadetblue = color.RGBA{0x5f, 0x9e, 0xa0, 0xff} // rgb(95, 158, 160)
Chartreuse = color.RGBA{0x7f, 0xff, 0x00, 0xff} // rgb(127, 255, 0)
Chocolate = color.RGBA{0xd2, 0x69, 0x1e, 0xff} // rgb(210, 105, 30)
Coral = color.RGBA{0xff, 0x7f, 0x50, 0xff} // rgb(255, 127, 80)
Cornflowerblue = color.RGBA{0x64, 0x95, 0xed, 0xff} // rgb(100, 149, 237)
Cornsilk = color.RGBA{0xff, 0xf8, 0xdc, 0xff} // rgb(255, 248, 220)
Crimson = color.RGBA{0xdc, 0x14, 0x3c, 0xff} // rgb(220, 20, 60)
Cyan = color.RGBA{0x00, 0xff, 0xff, 0xff} // rgb(0, 255, 255)
Darkblue = color.RGBA{0x00, 0x00, 0x8b, 0xff} // rgb(0, 0, 139)
Darkcyan = color.RGBA{0x00, 0x8b, 0x8b, 0xff} // rgb(0, 139, 139)
Darkgoldenrod = color.RGBA{0xb8, 0x86, 0x0b, 0xff} // rgb(184, 134, 11)
Darkgray = color.RGBA{0xa9, 0xa9, 0xa9, 0xff} // rgb(169, 169, 169)
Darkgreen = color.RGBA{0x00, 0x64, 0x00, 0xff} // rgb(0, 100, 0)
Darkgrey = color.RGBA{0xa9, 0xa9, 0xa9, 0xff} // rgb(169, 169, 169)
Darkkhaki = color.RGBA{0xbd, 0xb7, 0x6b, 0xff} // rgb(189, 183, 107)
Darkmagenta = color.RGBA{0x8b, 0x00, 0x8b, 0xff} // rgb(139, 0, 139)
Darkolivegreen = color.RGBA{0x55, 0x6b, 0x2f, 0xff} // rgb(85, 107, 47)
Darkorange = color.RGBA{0xff, 0x8c, 0x00, 0xff} // rgb(255, 140, 0)
Darkorchid = color.RGBA{0x99, 0x32, 0xcc, 0xff} // rgb(153, 50, 204)
Darkred = color.RGBA{0x8b, 0x00, 0x00, 0xff} // rgb(139, 0, 0)
Darksalmon = color.RGBA{0xe9, 0x96, 0x7a, 0xff} // rgb(233, 150, 122)
Darkseagreen = color.RGBA{0x8f, 0xbc, 0x8f, 0xff} // rgb(143, 188, 143)
Darkslateblue = color.RGBA{0x48, 0x3d, 0x8b, 0xff} // rgb(72, 61, 139)
Darkslategray = color.RGBA{0x2f, 0x4f, 0x4f, 0xff} // rgb(47, 79, 79)
Darkslategrey = color.RGBA{0x2f, 0x4f, 0x4f, 0xff} // rgb(47, 79, 79)
Darkturquoise = color.RGBA{0x00, 0xce, 0xd1, 0xff} // rgb(0, 206, 209)
Darkviolet = color.RGBA{0x94, 0x00, 0xd3, 0xff} // rgb(148, 0, 211)
Deeppink = color.RGBA{0xff, 0x14, 0x93, 0xff} // rgb(255, 20, 147)
Deepskyblue = color.RGBA{0x00, 0xbf, 0xff, 0xff} // rgb(0, 191, 255)
Dimgray = color.RGBA{0x69, 0x69, 0x69, 0xff} // rgb(105, 105, 105)
Dimgrey = color.RGBA{0x69, 0x69, 0x69, 0xff} // rgb(105, 105, 105)
Dodgerblue = color.RGBA{0x1e, 0x90, 0xff, 0xff} // rgb(30, 144, 255)
Firebrick = color.RGBA{0xb2, 0x22, 0x22, 0xff} // rgb(178, 34, 34)
Floralwhite = color.RGBA{0xff, 0xfa, 0xf0, 0xff} // rgb(255, 250, 240)
Forestgreen = color.RGBA{0x22, 0x8b, 0x22, 0xff} // rgb(34, 139, 34)
Fuchsia = color.RGBA{0xff, 0x00, 0xff, 0xff} // rgb(255, 0, 255)
Gainsboro = color.RGBA{0xdc, 0xdc, 0xdc, 0xff} // rgb(220, 220, 220)
Ghostwhite = color.RGBA{0xf8, 0xf8, 0xff, 0xff} // rgb(248, 248, 255)
Gold = color.RGBA{0xff, 0xd7, 0x00, 0xff} // rgb(255, 215, 0)
Goldenrod = color.RGBA{0xda, 0xa5, 0x20, 0xff} // rgb(218, 165, 32)
Gray = color.RGBA{0x80, 0x80, 0x80, 0xff} // rgb(128, 128, 128)
Green = color.RGBA{0x00, 0x80, 0x00, 0xff} // rgb(0, 128, 0)
Greenyellow = color.RGBA{0xad, 0xff, 0x2f, 0xff} // rgb(173, 255, 47)
Grey = color.RGBA{0x80, 0x80, 0x80, 0xff} // rgb(128, 128, 128)
Honeydew = color.RGBA{0xf0, 0xff, 0xf0, 0xff} // rgb(240, 255, 240)
Hotpink = color.RGBA{0xff, 0x69, 0xb4, 0xff} // rgb(255, 105, 180)
Indianred = color.RGBA{0xcd, 0x5c, 0x5c, 0xff} // rgb(205, 92, 92)
Indigo = color.RGBA{0x4b, 0x00, 0x82, 0xff} // rgb(75, 0, 130)
Ivory = color.RGBA{0xff, 0xff, 0xf0, 0xff} // rgb(255, 255, 240)
Khaki = color.RGBA{0xf0, 0xe6, 0x8c, 0xff} // rgb(240, 230, 140)
Lavender = color.RGBA{0xe6, 0xe6, 0xfa, 0xff} // rgb(230, 230, 250)
Lavenderblush = color.RGBA{0xff, 0xf0, 0xf5, 0xff} // rgb(255, 240, 245)
Lawngreen = color.RGBA{0x7c, 0xfc, 0x00, 0xff} // rgb(124, 252, 0)
Lemonchiffon = color.RGBA{0xff, 0xfa, 0xcd, 0xff} // rgb(255, 250, 205)
Lightblue = color.RGBA{0xad, 0xd8, 0xe6, 0xff} // rgb(173, 216, 230)
Lightcoral = color.RGBA{0xf0, 0x80, 0x80, 0xff} // rgb(240, 128, 128)
Lightcyan = color.RGBA{0xe0, 0xff, 0xff, 0xff} // rgb(224, 255, 255)
Lightgoldenrodyellow = color.RGBA{0xfa, 0xfa, 0xd2, 0xff} // rgb(250, 250, 210)
Lightgray = color.RGBA{0xd3, 0xd3, 0xd3, 0xff} // rgb(211, 211, 211)
Lightgreen = color.RGBA{0x90, 0xee, 0x90, 0xff} // rgb(144, 238, 144)
Lightgrey = color.RGBA{0xd3, 0xd3, 0xd3, 0xff} // rgb(211, 211, 211)
Lightpink = color.RGBA{0xff, 0xb6, 0xc1, 0xff} // rgb(255, 182, 193)
Lightsalmon = color.RGBA{0xff, 0xa0, 0x7a, 0xff} // rgb(255, 160, 122)
Lightseagreen = color.RGBA{0x20, 0xb2, 0xaa, 0xff} // rgb(32, 178, 170)
Lightskyblue = color.RGBA{0x87, 0xce, 0xfa, 0xff} // rgb(135, 206, 250)
Lightslategray = color.RGBA{0x77, 0x88, 0x99, 0xff} // rgb(119, 136, 153)
Lightslategrey = color.RGBA{0x77, 0x88, 0x99, 0xff} // rgb(119, 136, 153)
Lightsteelblue = color.RGBA{0xb0, 0xc4, 0xde, 0xff} // rgb(176, 196, 222)
Lightyellow = color.RGBA{0xff, 0xff, 0xe0, 0xff} // rgb(255, 255, 224)
Lime = color.RGBA{0x00, 0xff, 0x00, 0xff} // rgb(0, 255, 0)
Limegreen = color.RGBA{0x32, 0xcd, 0x32, 0xff} // rgb(50, 205, 50)
Linen = color.RGBA{0xfa, 0xf0, 0xe6, 0xff} // rgb(250, 240, 230)
Magenta = color.RGBA{0xff, 0x00, 0xff, 0xff} // rgb(255, 0, 255)
Maroon = color.RGBA{0x80, 0x00, 0x00, 0xff} // rgb(128, 0, 0)
Mediumaquamarine = color.RGBA{0x66, 0xcd, 0xaa, 0xff} // rgb(102, 205, 170)
Mediumblue = color.RGBA{0x00, 0x00, 0xcd, 0xff} // rgb(0, 0, 205)
Mediumorchid = color.RGBA{0xba, 0x55, 0xd3, 0xff} // rgb(186, 85, 211)
Mediumpurple = color.RGBA{0x93, 0x70, 0xdb, 0xff} // rgb(147, 112, 219)
Mediumseagreen = color.RGBA{0x3c, 0xb3, 0x71, 0xff} // rgb(60, 179, 113)
Mediumslateblue = color.RGBA{0x7b, 0x68, 0xee, 0xff} // rgb(123, 104, 238)
Mediumspringgreen = color.RGBA{0x00, 0xfa, 0x9a, 0xff} // rgb(0, 250, 154)
Mediumturquoise = color.RGBA{0x48, 0xd1, 0xcc, 0xff} // rgb(72, 209, 204)
Mediumvioletred = color.RGBA{0xc7, 0x15, 0x85, 0xff} // rgb(199, 21, 133)
Midnightblue = color.RGBA{0x19, 0x19, 0x70, 0xff} // rgb(25, 25, 112)
Mintcream = color.RGBA{0xf5, 0xff, 0xfa, 0xff} // rgb(245, 255, 250)
Mistyrose = color.RGBA{0xff, 0xe4, 0xe1, 0xff} // rgb(255, 228, 225)
Moccasin = color.RGBA{0xff, 0xe4, 0xb5, 0xff} // rgb(255, 228, 181)
Navajowhite = color.RGBA{0xff, 0xde, 0xad, 0xff} // rgb(255, 222, 173)
Navy = color.RGBA{0x00, 0x00, 0x80, 0xff} // rgb(0, 0, 128)
Oldlace = color.RGBA{0xfd, 0xf5, 0xe6, 0xff} // rgb(253, 245, 230)
Olive = color.RGBA{0x80, 0x80, 0x00, 0xff} // rgb(128, 128, 0)
Olivedrab = color.RGBA{0x6b, 0x8e, 0x23, 0xff} // rgb(107, 142, 35)
Orange = color.RGBA{0xff, 0xa5, 0x00, 0xff} // rgb(255, 165, 0)
Orangered = color.RGBA{0xff, 0x45, 0x00, 0xff} // rgb(255, 69, 0)
Orchid = color.RGBA{0xda, 0x70, 0xd6, 0xff} // rgb(218, 112, 214)
Palegoldenrod = color.RGBA{0xee, 0xe8, 0xaa, 0xff} // rgb(238, 232, 170)
Palegreen = color.RGBA{0x98, 0xfb, 0x98, 0xff} // rgb(152, 251, 152)
Paleturquoise = color.RGBA{0xaf, 0xee, 0xee, 0xff} // rgb(175, 238, 238)
Palevioletred = color.RGBA{0xdb, 0x70, 0x93, 0xff} // rgb(219, 112, 147)
Papayawhip = color.RGBA{0xff, 0xef, 0xd5, 0xff} // rgb(255, 239, 213)
Peachpuff = color.RGBA{0xff, 0xda, 0xb9, 0xff} // rgb(255, 218, 185)
Peru = color.RGBA{0xcd, 0x85, 0x3f, 0xff} // rgb(205, 133, 63)
Pink = color.RGBA{0xff, 0xc0, 0xcb, 0xff} // rgb(255, 192, 203)
Plum = color.RGBA{0xdd, 0xa0, 0xdd, 0xff} // rgb(221, 160, 221)
Powderblue = color.RGBA{0xb0, 0xe0, 0xe6, 0xff} // rgb(176, 224, 230)
Purple = color.RGBA{0x80, 0x00, 0x80, 0xff} // rgb(128, 0, 128)
Red = color.RGBA{0xff, 0x00, 0x00, 0xff} // rgb(255, 0, 0)
Rosybrown = color.RGBA{0xbc, 0x8f, 0x8f, 0xff} // rgb(188, 143, 143)
Royalblue = color.RGBA{0x41, 0x69, 0xe1, 0xff} // rgb(65, 105, 225)
Saddlebrown = color.RGBA{0x8b, 0x45, 0x13, 0xff} // rgb(139, 69, 19)
Salmon = color.RGBA{0xfa, 0x80, 0x72, 0xff} // rgb(250, 128, 114)
Sandybrown = color.RGBA{0xf4, 0xa4, 0x60, 0xff} // rgb(244, 164, 96)
Seagreen = color.RGBA{0x2e, 0x8b, 0x57, 0xff} // rgb(46, 139, 87)
Seashell = color.RGBA{0xff, 0xf5, 0xee, 0xff} // rgb(255, 245, 238)
Sienna = color.RGBA{0xa0, 0x52, 0x2d, 0xff} // rgb(160, 82, 45)
Silver = color.RGBA{0xc0, 0xc0, 0xc0, 0xff} // rgb(192, 192, 192)
Skyblue = color.RGBA{0x87, 0xce, 0xeb, 0xff} // rgb(135, 206, 235)
Slateblue = color.RGBA{0x6a, 0x5a, 0xcd, 0xff} // rgb(106, 90, 205)
Slategray = color.RGBA{0x70, 0x80, 0x90, 0xff} // rgb(112, 128, 144)
Slategrey = color.RGBA{0x70, 0x80, 0x90, 0xff} // rgb(112, 128, 144)
Snow = color.RGBA{0xff, 0xfa, 0xfa, 0xff} // rgb(255, 250, 250)
Springgreen = color.RGBA{0x00, 0xff, 0x7f, 0xff} // rgb(0, 255, 127)
Steelblue = color.RGBA{0x46, 0x82, 0xb4, 0xff} // rgb(70, 130, 180)
Tan = color.RGBA{0xd2, 0xb4, 0x8c, 0xff} // rgb(210, 180, 140)
Teal = color.RGBA{0x00, 0x80, 0x80, 0xff} // rgb(0, 128, 128)
Thistle = color.RGBA{0xd8, 0xbf, 0xd8, 0xff} // rgb(216, 191, 216)
Tomato = color.RGBA{0xff, 0x63, 0x47, 0xff} // rgb(255, 99, 71)
Turquoise = color.RGBA{0x40, 0xe0, 0xd0, 0xff} // rgb(64, 224, 208)
Violet = color.RGBA{0xee, 0x82, 0xee, 0xff} // rgb(238, 130, 238)
Wheat = color.RGBA{0xf5, 0xde, 0xb3, 0xff} // rgb(245, 222, 179)
White = color.RGBA{0xff, 0xff, 0xff, 0xff} // rgb(255, 255, 255)
Whitesmoke = color.RGBA{0xf5, 0xf5, 0xf5, 0xff} // rgb(245, 245, 245)
Yellow = color.RGBA{0xff, 0xff, 0x00, 0xff} // rgb(255, 255, 0)
Yellowgreen = color.RGBA{0x9a, 0xcd, 0x32, 0xff} // rgb(154, 205, 50)
)

32
vendor/golang.org/x/image/font/basicfont/basicfont.go сгенерированный поставляемый
Просмотреть файл

@@ -19,8 +19,8 @@ import (
// exclusive on the high end.
//
// If Low <= r && r < High, then the rune r is mapped to the sub-image of
// Face.Mask whose bounds are image.Rect(0, y, Face.Width, y+Face.Height),
// where y equals (int(r-Low) + Offset) * Face.Height.
// Face.Mask whose bounds are image.Rect(0, y*h, Face.Width, (y+1)*h),
// where y = (int(r-Low) + Offset) and h = (Face.Ascent + Face.Descent).
type Range struct {
Low, High rune
Offset int
@@ -38,6 +38,7 @@ var Face7x13 = &Face{
Width: 6,
Height: 13,
Ascent: 11,
Descent: 2,
Mask: mask7x13,
Ranges: []Range{
{'\u0020', '\u007f', 0},
@@ -53,12 +54,15 @@ type Face struct {
Advance int
// Width is the glyph width, in pixels.
Width int
// Height is the glyph height, in pixels.
// Height is the inter-line height, in pixels.
Height int
// Ascent is the glyph ascent, in pixels.
Ascent int
// TODO: do we also need Top and Left fields?
// Descent is the glyph descent, in pixels.
Descent int
// Left is the left side bearing, in pixels. A positive value means that
// all of a glyph is to the right of the dot.
Left int
// Mask contains all of the glyph masks. Its width is typically the Face's
// Width, and its height a multiple of the Face's Height.
@@ -75,7 +79,7 @@ func (f *Face) Metrics() font.Metrics {
return font.Metrics{
Height: fixed.I(f.Height),
Ascent: fixed.I(f.Ascent),
Descent: fixed.I(f.Height - f.Ascent),
Descent: fixed.I(f.Descent),
}
}
@@ -88,7 +92,7 @@ loop:
if rr < rng.Low || rng.High <= rr {
continue
}
maskp.Y = (int(rr-rng.Low) + rng.Offset) * f.Height
maskp.Y = (int(rr-rng.Low) + rng.Offset) * (f.Ascent + f.Descent)
ok = true
break loop
}
@@ -97,16 +101,16 @@ loop:
return image.Rectangle{}, nil, image.Point{}, 0, false
}
minX := int(dot.X+32) >> 6
minY := int(dot.Y+32)>>6 - f.Ascent
x := int(dot.X+32)>>6 + f.Left
y := int(dot.Y+32) >> 6
dr = image.Rectangle{
Min: image.Point{
X: minX,
Y: minY,
X: x,
Y: y - f.Ascent,
},
Max: image.Point{
X: minX + f.Width,
Y: minY + f.Height,
X: x + f.Width,
Y: y + f.Descent,
},
}
@@ -114,7 +118,7 @@ loop:
}
func (f *Face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
return fixed.R(0, -f.Ascent, f.Width, -f.Ascent+f.Height), fixed.I(f.Advance), true
return fixed.R(0, -f.Ascent, f.Width, +f.Descent), fixed.I(f.Advance), true
}
func (f *Face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {

79
vendor/golang.org/x/image/font/font.go сгенерированный поставляемый
Просмотреть файл

@@ -13,6 +13,7 @@ import (
"image"
"image/draw"
"io"
"unicode/utf8"
"golang.org/x/image/math/fixed"
)
@@ -87,9 +88,6 @@ type Metrics struct {
Descent fixed.Int26_6
}
// TODO: Drawer.Layout or Drawer.Measure methods to measure text without
// drawing?
// Drawer draws text on a destination image.
//
// A Drawer is not safe for concurrent use by multiple goroutines, since its
@@ -115,19 +113,25 @@ type Drawer struct {
// TODO: should DrawString return the last rune drawn, so the next DrawString
// call can kern beforehand? Or should that be the responsibility of the caller
// if they really want to do that, since they have to explicitly shift d.Dot
// anyway?
// anyway? What if ligatures span more than two runes? What if grapheme
// clusters span multiple runes?
//
// In general, we'd have a DrawBytes([]byte) and DrawRuneReader(io.RuneReader)
// and the last case can't assume that you can rewind the stream.
// TODO: do we assume that the input is in any particular Unicode Normalization
// Form?
//
// TODO: have DrawRunes(s []rune)? DrawRuneReader(io.RuneReader)?? If we take
// io.RuneReader, we can't assume that we can rewind the stream.
//
// TODO: how does this work with line breaking: drawing text up until a
// vertical line? Should DrawString return the number of runes drawn?
// DrawString draws s at the dot and advances the dot's location.
func (d *Drawer) DrawString(s string) {
var prevC rune
for i, c := range s {
if i != 0 {
// DrawBytes draws s at the dot and advances the dot's location.
func (d *Drawer) DrawBytes(s []byte) {
prevC := rune(-1)
for len(s) > 0 {
c, size := utf8.DecodeRune(s)
s = s[size:]
if prevC >= 0 {
d.Dot.X += d.Face.Kern(prevC, c)
}
dr, mask, maskp, advance, ok := d.Face.Glyph(d.Dot, c)
@@ -143,16 +147,63 @@ func (d *Drawer) DrawString(s string) {
}
}
// DrawString draws s at the dot and advances the dot's location.
func (d *Drawer) DrawString(s string) {
prevC := rune(-1)
for _, c := range s {
if prevC >= 0 {
d.Dot.X += d.Face.Kern(prevC, c)
}
dr, mask, maskp, advance, ok := d.Face.Glyph(d.Dot, c)
if !ok {
// TODO: is falling back on the U+FFFD glyph the responsibility of
// the Drawer or the Face?
// TODO: set prevC = '\ufffd'?
continue
}
draw.DrawMask(d.Dst, dr, d.Src, image.Point{}, mask, maskp, draw.Over)
d.Dot.X += advance
prevC = c
}
}
// MeasureBytes returns how far dot would advance by drawing s.
func (d *Drawer) MeasureBytes(s []byte) (advance fixed.Int26_6) {
return MeasureBytes(d.Face, s)
}
// MeasureString returns how far dot would advance by drawing s.
func (d *Drawer) MeasureString(s string) (advance fixed.Int26_6) {
return MeasureString(d.Face, s)
}
// MeasureBytes returns how far dot would advance by drawing s with f.
func MeasureBytes(f Face, s []byte) (advance fixed.Int26_6) {
prevC := rune(-1)
for len(s) > 0 {
c, size := utf8.DecodeRune(s)
s = s[size:]
if prevC >= 0 {
advance += f.Kern(prevC, c)
}
a, ok := f.GlyphAdvance(c)
if !ok {
// TODO: is falling back on the U+FFFD glyph the responsibility of
// the Drawer or the Face?
// TODO: set prevC = '\ufffd'?
continue
}
advance += a
prevC = c
}
return advance
}
// MeasureString returns how far dot would advance by drawing s with f.
func MeasureString(f Face, s string) (advance fixed.Int26_6) {
var prevC rune
for i, c := range s {
if i != 0 {
prevC := rune(-1)
for _, c := range s {
if prevC >= 0 {
advance += f.Kern(prevC, c)
}
a, ok := f.GlyphAdvance(c)

5557
vendor/golang.org/x/image/font/inconsolata/bold8x16.go сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

29
vendor/golang.org/x/image/font/inconsolata/inconsolata.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,29 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:generate genbasicfont -size=16 -pkg=inconsolata -hinting=full -var=regular8x16 -fontfile=http://www.levien.com/type/myfonts/inconsolata/InconsolataGo-Regular.ttf
//go:generate genbasicfont -size=16 -pkg=inconsolata -hinting=full -var=bold8x16 -fontfile=http://www.levien.com/type/myfonts/inconsolata/InconsolataGo-Bold.ttf
// The genbasicfont program is github.com/golang/freetype/example/genbasicfont
// Package inconsolata provides pre-rendered bitmap versions of the Inconsolata
// font family.
//
// Inconsolata is copyright Raph Levien and Cyreal. This package is licensed
// under Go's BSD-style license (https://golang.org/LICENSE) with their
// permission.
//
// Inconsolata's home page is at
// http://www.levien.com/type/myfonts/inconsolata.html
package inconsolata // import "golang.org/x/image/font/inconsolata"
import (
"golang.org/x/image/font/basicfont"
)
// Regular8x16 is a regular weight, 8x16 font face.
var Regular8x16 *basicfont.Face = &regular8x16
// Bold8x16 is a bold weight, 8x16 font face.
var Bold8x16 *basicfont.Face = &bold8x16

5557
vendor/golang.org/x/image/font/inconsolata/regular8x16.go сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

27
vendor/golang.org/x/image/font/plan9font/plan9font.go сгенерированный поставляемый
Просмотреть файл

@@ -174,6 +174,31 @@ func (f *face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
return 0, false
}
// For subfont files, if reading the given file name fails, we try appending
// ".n" where n is the log2 of the grayscale depth in bits (so at most 3) and
// then work down to 0. This was done in Plan 9 when antialiased fonts were
// introduced so that the 1-bit displays could keep using the 1-bit forms but
// higher depth displays could use the antialiased forms.
var subfontSuffixes = [...]string{
"",
".3",
".2",
".1",
".0",
}
func (f *face) readSubfontFile(name string) ([]byte, error) {
var firstErr error
for _, suffix := range subfontSuffixes {
if b, err := f.readFile(name + suffix); err == nil {
return b, nil
} else if firstErr == nil {
firstErr = err
}
}
return nil, firstErr
}
func (f *face) subface(r rune) (*subface, rune) {
// Fall back on U+FFFD if we can't find r.
for _, rr := range [2]rune{r, '\ufffd'} {
@@ -188,7 +213,7 @@ func (f *face) subface(r rune) (*subface, rune) {
continue
}
if x.subface == nil {
data, err := f.readFile(x.relFilename)
data, err := f.readSubfontFile(x.relFilename)
if err != nil {
log.Printf("plan9font: couldn't read subfont %q: %v", x.relFilename, err)
x.bad = true

38
vendor/golang.org/x/image/math/fixed/fixed.go сгенерированный поставляемый
Просмотреть файл

@@ -56,6 +56,11 @@ func (x Int26_6) Round() int { return int((x + 0x20) >> 6) }
// Its return type is int, not Int26_6.
func (x Int26_6) Ceil() int { return int((x + 0x3f) >> 6) }
// Mul returns x*y in 26.6 fixed-point arithmetic.
func (x Int26_6) Mul(y Int26_6) Int26_6 {
return Int26_6((int64(x)*int64(y) + 1<<5) >> 6)
}
// Int52_12 is a signed 52.12 fixed-point number.
//
// The integer part ranges from -2251799813685248 to 2251799813685247,
@@ -95,6 +100,39 @@ func (x Int52_12) Round() int { return int((x + 0x800) >> 12) }
// Its return type is int, not Int52_12.
func (x Int52_12) Ceil() int { return int((x + 0xfff) >> 12) }
// Mul returns x*y in 52.12 fixed-point arithmetic.
func (x Int52_12) Mul(y Int52_12) Int52_12 {
const M, N = 52, 12
lo, hi := muli64(int64(x), int64(y))
ret := Int52_12(hi<<M | lo>>N)
ret += Int52_12((lo >> (N - 1)) & 1) // Round to nearest, instead of rounding down.
return ret
}
// muli64 multiplies two int64 values, returning the 128-bit signed integer
// result as two uint64 values.
//
// This implementation is similar to $GOROOT/src/runtime/softfloat64.go's mullu
// function, which is in turn adapted from Hacker's Delight.
func muli64(u, v int64) (lo, hi uint64) {
const (
s = 32
mask = 1<<s - 1
)
u1 := uint64(u >> s)
u0 := uint64(u & mask)
v1 := uint64(v >> s)
v0 := uint64(v & mask)
w0 := u0 * v0
t := u1*v0 + w0>>s
w1 := t & mask
w2 := uint64(int64(t) >> s)
w1 += u0 * v1
return uint64(u) * uint64(v), u1*v1 + w2 + uint64(int64(w1)>>s)
}
// P returns the integer values x and y as a Point26_6.
//
// For example, passing the integer values (2, -3) yields Point26_6{128, -192}.

329
vendor/golang.org/x/image/math/fixed/fixed_test.go сгенерированный поставляемый
Просмотреть файл

@@ -5,6 +5,8 @@
package fixed
import (
"math"
"math/rand"
"testing"
)
@@ -74,6 +76,7 @@ var testCases = []struct {
}}
func TestInt26_6(t *testing.T) {
const one = Int26_6(1 << 6)
for _, tc := range testCases {
x := Int26_6(tc.x * (1 << 6))
if got, want := x.String(), tc.s26_6; got != want {
@@ -88,10 +91,17 @@ func TestInt26_6(t *testing.T) {
if got, want := x.Ceil(), tc.ceil; got != want {
t.Errorf("tc.x=%v: Ceil: got %v, want %v", tc.x, got, want)
}
if got, want := x.Mul(one), x; got != want {
t.Errorf("tc.x=%v: Mul by one: got %v, want %v", tc.x, got, want)
}
if got, want := x.mul(one), x; got != want {
t.Errorf("tc.x=%v: mul by one: got %v, want %v", tc.x, got, want)
}
}
}
func TestInt52_12(t *testing.T) {
const one = Int52_12(1 << 12)
for _, tc := range testCases {
x := Int52_12(tc.x * (1 << 12))
if got, want := x.String(), tc.s52_12; got != want {
@@ -106,5 +116,324 @@ func TestInt52_12(t *testing.T) {
if got, want := x.Ceil(), tc.ceil; got != want {
t.Errorf("tc.x=%v: Ceil: got %v, want %v", tc.x, got, want)
}
if got, want := x.Mul(one), x; got != want {
t.Errorf("tc.x=%v: Mul by one: got %v, want %v", tc.x, got, want)
}
}
}
var mulTestCases = []struct {
x float64
y float64
z26_6 float64 // Equals truncate26_6(x)*truncate26_6(y).
z52_12 float64 // Equals truncate52_12(x)*truncate52_12(y).
s26_6 string
s52_12 string
}{{
x: 0,
y: 1.5,
z26_6: 0,
z52_12: 0,
s26_6: "0:00",
s52_12: "0:0000",
}, {
x: +1.25,
y: +4,
z26_6: +5,
z52_12: +5,
s26_6: "5:00",
s52_12: "5:0000",
}, {
x: +1.25,
y: -4,
z26_6: -5,
z52_12: -5,
s26_6: "-5:00",
s52_12: "-5:0000",
}, {
x: -1.25,
y: +4,
z26_6: -5,
z52_12: -5,
s26_6: "-5:00",
s52_12: "-5:0000",
}, {
x: -1.25,
y: -4,
z26_6: +5,
z52_12: +5,
s26_6: "5:00",
s52_12: "5:0000",
}, {
x: 1.25,
y: 1.5,
z26_6: 1.875,
z52_12: 1.875,
s26_6: "1:56",
s52_12: "1:3584",
}, {
x: 1234.5,
y: -8888.875,
z26_6: -10973316.1875,
z52_12: -10973316.1875,
s26_6: "-10973316:12",
s52_12: "-10973316:0768",
}, {
x: 1.515625, // 1 + 33/64 = 97/64
y: 1.531250, // 1 + 34/64 = 98/64
z26_6: 2.32080078125, // 2 + 1314/4096 = 9506/4096
z52_12: 2.32080078125, // 2 + 1314/4096 = 9506/4096
s26_6: "2:21", // 2.32812500000, which is closer than 2:20 (in decimal, 2.3125)
s52_12: "2:1314", // 2.32080078125
}, {
x: 0.500244140625, // 2049/4096, approximately 32/64
y: 0.500732421875, // 2051/4096, approximately 32/64
z26_6: 0.25, // 4194304/16777216, or 1024/4096
z52_12: 0.2504884600639343, // 4202499/16777216
s26_6: "0:16", // 0.25000000000
s52_12: "0:1026", // 0.25048828125, which is closer than 0:1027 (in decimal, 0.250732421875)
}, {
x: 0.015625, // 1/64
y: 0.000244140625, // 1/4096, approximately 0/64
z26_6: 0.0, // 0
z52_12: 0.000003814697265625, // 1/262144
s26_6: "0:00", // 0
s52_12: "0:0000", // 0, which is closer than 0:0001 (in decimal, 0.000244140625)
}, {
// Round the Int52_12 calculation down.
x: 1.44140625, // 1 + 1808/4096 = 5904/4096, approximately 92/64
y: 1.44140625, // 1 + 1808/4096 = 5904/4096, approximately 92/64
z26_6: 2.06640625, // 2 + 272/4096 = 8464/4096
z52_12: 2.0776519775390625, // 2 + 318/4096 + 256/16777216 = 34857216/16777216
s26_6: "2:04", // 2.06250000000, which is closer than 2:05 (in decimal, 2.078125000000)
s52_12: "2:0318", // 2.07763671875, which is closer than 2:0319 (in decimal, 2.077880859375)
}, {
// Round the Int52_12 calculation up.
x: 1.44140625, // 1 + 1808/4096 = 5904/4096, approximately 92/64
y: 1.441650390625, // 1 + 1809/4096 = 5905/4096, approximately 92/64
z26_6: 2.06640625, // 2 + 272/4096 = 8464/4096
z52_12: 2.0780038833618164, // 2 + 319/4096 + 2064/16777216 = 34863120/16777216
s26_6: "2:04", // 2.06250000000, which is closer than 2:05 (in decimal, 2.078125000000)
s52_12: "2:0320", // 2.07812500000, which is closer than 2:0319 (in decimal, 2.077880859375)
}}
func TestInt26_6Mul(t *testing.T) {
for _, tc := range mulTestCases {
x := Int26_6(tc.x * (1 << 6))
y := Int26_6(tc.y * (1 << 6))
if z := float64(x) * float64(y) / (1 << 12); z != tc.z26_6 {
t.Errorf("tc.x=%v, tc.y=%v: z: got %v, want %v", tc.x, tc.y, z, tc.z26_6)
continue
}
if got, want := x.Mul(y).String(), tc.s26_6; got != want {
t.Errorf("tc.x=%v: Mul: got %q, want %q", tc.x, got, want)
}
}
}
func TestInt52_12Mul(t *testing.T) {
for _, tc := range mulTestCases {
x := Int52_12(tc.x * (1 << 12))
y := Int52_12(tc.y * (1 << 12))
if z := float64(x) * float64(y) / (1 << 24); z != tc.z52_12 {
t.Errorf("tc.x=%v, tc.y=%v: z: got %v, want %v", tc.x, tc.y, z, tc.z52_12)
continue
}
if got, want := x.Mul(y).String(), tc.s52_12; got != want {
t.Errorf("tc.x=%v: Mul: got %q, want %q", tc.x, got, want)
}
}
}
func TestInt26_6MulByOneMinusIota(t *testing.T) {
const (
totalBits = 32
fracBits = 6
oneMinusIota = Int26_6(1<<fracBits) - 1
oneMinusIotaF = float64(oneMinusIota) / (1 << fracBits)
)
for _, neg := range []bool{false, true} {
for i := uint(0); i < totalBits; i++ {
x := Int26_6(1 << i)
if neg {
x = -x
} else if i == totalBits-1 {
// A signed int32 can't represent 1<<31.
continue
}
// want equals x * oneMinusIota, rounded to nearest.
want := Int26_6(0)
if -1<<fracBits < x && x < 1<<fracBits {
// (x * oneMinusIota) isn't exactly representable as an
// Int26_6. Calculate the rounded value using float64 math.
xF := float64(x) / (1 << fracBits)
wantF := xF * oneMinusIotaF * (1 << fracBits)
want = Int26_6(math.Floor(wantF + 0.5))
} else {
// (x * oneMinusIota) is exactly representable.
want = oneMinusIota << (i - fracBits)
if neg {
want = -want
}
}
if got := x.Mul(oneMinusIota); got != want {
t.Errorf("neg=%t, i=%d, x=%v, Mul: got %v, want %v", neg, i, x, got, want)
}
if got := x.mul(oneMinusIota); got != want {
t.Errorf("neg=%t, i=%d, x=%v, mul: got %v, want %v", neg, i, x, got, want)
}
}
}
}
func TestInt52_12MulByOneMinusIota(t *testing.T) {
const (
totalBits = 64
fracBits = 12
oneMinusIota = Int52_12(1<<fracBits) - 1
oneMinusIotaF = float64(oneMinusIota) / (1 << fracBits)
)
for _, neg := range []bool{false, true} {
for i := uint(0); i < totalBits; i++ {
x := Int52_12(1 << i)
if neg {
x = -x
} else if i == totalBits-1 {
// A signed int64 can't represent 1<<63.
continue
}
// want equals x * oneMinusIota, rounded to nearest.
want := Int52_12(0)
if -1<<fracBits < x && x < 1<<fracBits {
// (x * oneMinusIota) isn't exactly representable as an
// Int52_12. Calculate the rounded value using float64 math.
xF := float64(x) / (1 << fracBits)
wantF := xF * oneMinusIotaF * (1 << fracBits)
want = Int52_12(math.Floor(wantF + 0.5))
} else {
// (x * oneMinusIota) is exactly representable.
want = oneMinusIota << (i - fracBits)
if neg {
want = -want
}
}
if got := x.Mul(oneMinusIota); got != want {
t.Errorf("neg=%t, i=%d, x=%v, Mul: got %v, want %v", neg, i, x, got, want)
}
}
}
}
func TestInt26_6MulVsMul(t *testing.T) {
rng := rand.New(rand.NewSource(1))
for i := 0; i < 10000; i++ {
u := Int26_6(rng.Uint32())
v := Int26_6(rng.Uint32())
Mul := u.Mul(v)
mul := u.mul(v)
if Mul != mul {
t.Errorf("u=%#08x, v=%#08x: Mul=%#08x and mul=%#08x differ",
uint32(u), uint32(v), uint32(Mul), uint32(mul))
}
}
}
func TestMuli32(t *testing.T) {
rng := rand.New(rand.NewSource(2))
for i := 0; i < 10000; i++ {
u := int32(rng.Uint32())
v := int32(rng.Uint32())
lo, hi := muli32(u, v)
got := uint64(lo) | uint64(hi)<<32
want := uint64(int64(u) * int64(v))
if got != want {
t.Errorf("u=%#08x, v=%#08x: got %#016x, want %#016x", uint32(u), uint32(v), got, want)
}
}
}
func TestMulu32(t *testing.T) {
rng := rand.New(rand.NewSource(3))
for i := 0; i < 10000; i++ {
u := rng.Uint32()
v := rng.Uint32()
lo, hi := mulu32(u, v)
got := uint64(lo) | uint64(hi)<<32
want := uint64(u) * uint64(v)
if got != want {
t.Errorf("u=%#08x, v=%#08x: got %#016x, want %#016x", u, v, got, want)
}
}
}
// mul (with a lower case 'm') is an alternative implementation of Int26_6.Mul
// (with an upper case 'M'). It has the same structure as the Int52_12.Mul
// implementation, but Int26_6.mul is easier to test since Go has built-in
// 64-bit integers.
func (x Int26_6) mul(y Int26_6) Int26_6 {
const M, N = 26, 6
lo, hi := muli32(int32(x), int32(y))
ret := Int26_6(hi<<M | lo>>N)
ret += Int26_6((lo >> (N - 1)) & 1) // Round to nearest, instead of rounding down.
return ret
}
// muli32 multiplies two int32 values, returning the 64-bit signed integer
// result as two uint32 values.
//
// muli32 isn't used directly by this package, but it has the same structure as
// muli64, and muli32 is easier to test since Go has built-in 64-bit integers.
func muli32(u, v int32) (lo, hi uint32) {
const (
s = 16
mask = 1<<s - 1
)
u1 := uint32(u >> s)
u0 := uint32(u & mask)
v1 := uint32(v >> s)
v0 := uint32(v & mask)
w0 := u0 * v0
t := u1*v0 + w0>>s
w1 := t & mask
w2 := uint32(int32(t) >> s)
w1 += u0 * v1
return uint32(u) * uint32(v), u1*v1 + w2 + uint32(int32(w1)>>s)
}
// mulu32 is like muli32, except that it multiplies unsigned instead of signed
// values.
//
// This implementation comes from $GOROOT/src/runtime/softfloat64.go's mullu
// function, which is in turn adapted from Hacker's Delight.
//
// mulu32 (and its corresponding test, TestMulu32) isn't used directly by this
// package. It is provided in this test file as a reference point to compare
// the muli32 (and TestMuli32) implementations against.
func mulu32(u, v uint32) (lo, hi uint32) {
const (
s = 16
mask = 1<<s - 1
)
u0 := u & mask
u1 := u >> s
v0 := v & mask
v1 := v >> s
w0 := u0 * v0
t := u1*v0 + w0>>s
w1 := t & mask
w2 := t >> s
w1 += u0 * v1
return u * v, u1*v1 + w2 + w1>>s
}

20
vendor/golang.org/x/image/riff/riff.go сгенерированный поставляемый
Просмотреть файл

@@ -23,6 +23,7 @@ import (
var (
errMissingPaddingByte = errors.New("riff: missing padding byte")
errMissingRIFFChunkHeader = errors.New("riff: missing RIFF chunk header")
errListSubchunkTooLong = errors.New("riff: list subchunk too long")
errShortChunkData = errors.New("riff: short chunk data")
errShortChunkHeader = errors.New("riff: short chunk header")
errStaleReader = errors.New("riff: stale reader")
@@ -100,13 +101,23 @@ func (z *Reader) Next() (chunkID FourCC, chunkLen uint32, chunkData io.Reader, e
// Drain the rest of the previous chunk.
if z.chunkLen != 0 {
_, z.err = io.Copy(ioutil.Discard, z.chunkReader)
want := z.chunkLen
var got int64
got, z.err = io.Copy(ioutil.Discard, z.chunkReader)
if z.err == nil && uint32(got) != want {
z.err = errShortChunkData
}
if z.err != nil {
return FourCC{}, 0, nil, z.err
}
}
z.chunkReader = nil
if z.padded {
if z.totalLen == 0 {
z.err = errListSubchunkTooLong
return FourCC{}, 0, nil, z.err
}
z.totalLen--
_, z.err = io.ReadFull(z.r, z.buf[:1])
if z.err != nil {
if z.err == io.EOF {
@@ -114,7 +125,6 @@ func (z *Reader) Next() (chunkID FourCC, chunkLen uint32, chunkData io.Reader, e
}
return FourCC{}, 0, nil, z.err
}
z.totalLen--
}
// We are done if we have no more data.
@@ -129,7 +139,7 @@ func (z *Reader) Next() (chunkID FourCC, chunkLen uint32, chunkData io.Reader, e
return FourCC{}, 0, nil, z.err
}
z.totalLen -= chunkHeaderSize
if _, err = io.ReadFull(z.r, z.buf[:chunkHeaderSize]); err != nil {
if _, z.err = io.ReadFull(z.r, z.buf[:chunkHeaderSize]); z.err != nil {
if z.err == io.EOF || z.err == io.ErrUnexpectedEOF {
z.err = errShortChunkHeader
}
@@ -137,6 +147,10 @@ func (z *Reader) Next() (chunkID FourCC, chunkLen uint32, chunkData io.Reader, e
}
chunkID = FourCC{z.buf[0], z.buf[1], z.buf[2], z.buf[3]}
z.chunkLen = u32(z.buf[4:])
if z.chunkLen > z.totalLen {
z.err = errListSubchunkTooLong
return FourCC{}, 0, nil, z.err
}
z.padded = z.chunkLen&1 == 1
z.chunkReader = &chunkReader{z}
return chunkID, z.chunkLen, z.chunkReader, nil

69
vendor/golang.org/x/image/riff/riff_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,69 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package riff
import (
"bytes"
"testing"
)
func encodeU32(u uint32) []byte {
return []byte{
byte(u >> 0),
byte(u >> 8),
byte(u >> 16),
byte(u >> 24),
}
}
func TestShortChunks(t *testing.T) {
// s is a RIFF(ABCD) with allegedly 256 bytes of data (excluding the
// leading 8-byte "RIFF\x00\x01\x00\x00"). The first chunk of that ABCD
// list is an abcd chunk of length m followed by n zeroes.
for _, m := range []uint32{0, 8, 15, 200, 300} {
for _, n := range []int{0, 1, 2, 7} {
s := []byte("RIFF\x00\x01\x00\x00ABCDabcd")
s = append(s, encodeU32(m)...)
s = append(s, make([]byte, n)...)
_, r, err := NewReader(bytes.NewReader(s))
if err != nil {
t.Errorf("m=%d, n=%d: NewReader: %v", m, n, err)
continue
}
_, _, _, err0 := r.Next()
// The total "ABCD" list length is 256 bytes, of which the first 12
// bytes are "ABCDabcd" plus the 4-byte encoding of m. If the
// "abcd" subchunk length (m) plus those 12 bytes is greater than
// the total list length, we have an invalid RIFF, and we expect an
// errListSubchunkTooLong error.
if m+12 > 256 {
if err0 != errListSubchunkTooLong {
t.Errorf("m=%d, n=%d: Next #0: got %v, want %v", m, n, err0, errListSubchunkTooLong)
}
continue
}
// Otherwise, we expect a nil error.
if err0 != nil {
t.Errorf("m=%d, n=%d: Next #0: %v", m, n, err0)
continue
}
_, _, _, err1 := r.Next()
// If m > 0, then m > n, so that "abcd" subchunk doesn't have m
// bytes of data. If m == 0, then that "abcd" subchunk is OK in
// that it has 0 extra bytes of data, but the next subchunk (8 byte
// header plus body) is missing, as we only have n < 8 more bytes.
want := errShortChunkData
if m == 0 {
want = errShortChunkHeader
}
if err1 != want {
t.Errorf("m=%d, n=%d: Next #1: got %v, want %v", m, n, err1, want)
continue
}
}
}
}

153
vendor/golang.org/x/image/vector/raster_floating.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,153 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vector
// This file contains a floating point math implementation of the vector
// graphics rasterizer.
import (
"math"
"golang.org/x/image/math/f32"
)
func floatingMax(x, y float32) float32 {
if x > y {
return x
}
return y
}
func floatingMin(x, y float32) float32 {
if x < y {
return x
}
return y
}
func floatingFloor(x float32) int32 { return int32(math.Floor(float64(x))) }
func floatingCeil(x float32) int32 { return int32(math.Ceil(float64(x))) }
func (z *Rasterizer) floatingLineTo(b f32.Vec2) {
a := z.pen
z.pen = b
dir := float32(1)
if a[1] > b[1] {
dir, a, b = -1, b, a
}
// Horizontal line segments yield no change in coverage. Almost horizontal
// segments would yield some change, in ideal math, but the computation
// further below, involving 1 / (b[1] - a[1]), is unstable in floating
// point math, so we treat the segment as if it was perfectly horizontal.
if b[1]-a[1] <= 0.000001 {
return
}
dxdy := (b[0] - a[0]) / (b[1] - a[1])
x := a[0]
y := floatingFloor(a[1])
yMax := floatingCeil(b[1])
if yMax > int32(z.size.Y) {
yMax = int32(z.size.Y)
}
width := int32(z.size.X)
for ; y < yMax; y++ {
dy := floatingMin(float32(y+1), b[1]) - floatingMax(float32(y), a[1])
xNext := x + dy*dxdy
if y < 0 {
x = xNext
continue
}
buf := z.area[y*width:]
d := dy * dir
x0, x1 := x, xNext
if x > xNext {
x0, x1 = x1, x0
}
x0i := floatingFloor(x0)
x0Floor := float32(x0i)
x1i := floatingCeil(x1)
x1Ceil := float32(x1i)
if x1i <= x0i+1 {
xmf := 0.5*(x+xNext) - x0Floor
if i := clamp(x0i+0, width); i < uint(len(buf)) {
buf[i] += d - d*xmf
}
if i := clamp(x0i+1, width); i < uint(len(buf)) {
buf[i] += d * xmf
}
} else {
s := 1 / (x1 - x0)
x0f := x0 - x0Floor
oneMinusX0f := 1 - x0f
a0 := 0.5 * s * oneMinusX0f * oneMinusX0f
x1f := x1 - x1Ceil + 1
am := 0.5 * s * x1f * x1f
if i := clamp(x0i, width); i < uint(len(buf)) {
buf[i] += d * a0
}
if x1i == x0i+2 {
if i := clamp(x0i+1, width); i < uint(len(buf)) {
buf[i] += d * (1 - a0 - am)
}
} else {
a1 := s * (1.5 - x0f)
if i := clamp(x0i+1, width); i < uint(len(buf)) {
buf[i] += d * (a1 - a0)
}
dTimesS := d * s
for xi := x0i + 2; xi < x1i-1; xi++ {
if i := clamp(xi, width); i < uint(len(buf)) {
buf[i] += dTimesS
}
}
a2 := a1 + s*float32(x1i-x0i-3)
if i := clamp(x1i-1, width); i < uint(len(buf)) {
buf[i] += d * (1 - a2 - am)
}
}
if i := clamp(x1i, width); i < uint(len(buf)) {
buf[i] += d * am
}
}
x = xNext
}
}
func floatingAccumulate(dst []uint8, src []float32) {
// almost256 scales a floating point value in the range [0, 1] to a uint8
// value in the range [0x00, 0xff].
//
// 255 is too small. Floating point math accumulates rounding errors, so a
// fully covered src value that would in ideal math be float32(1) might be
// float32(1-ε), and uint8(255 * (1-ε)) would be 0xfe instead of 0xff. The
// uint8 conversion rounds to zero, not to nearest.
//
// 256 is too big. If we multiplied by 256, below, then a fully covered src
// value of float32(1) would translate to uint8(256 * 1), which can be 0x00
// instead of the maximal value 0xff.
//
// math.Float32bits(almost256) is 0x437fffff.
const almost256 = 255.99998
acc := float32(0)
for i, v := range src {
acc += v
a := acc
if a < 0 {
a = -a
}
if a > 1 {
a = 1
}
dst[i] = uint8(almost256 * a)
}
}

228
vendor/golang.org/x/image/vector/vector.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,228 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package vector provides a rasterizer for 2-D vector graphics.
package vector // import "golang.org/x/image/vector"
// The rasterizer's design follows
// https://medium.com/@raphlinus/inside-the-fastest-font-renderer-in-the-world-75ae5270c445
//
// Proof of concept code is in
// https://github.com/google/font-go
//
// See also:
// http://nothings.org/gamedev/rasterize/
// http://projects.tuxee.net/cl-vectors/section-the-cl-aa-algorithm
// https://people.gnome.org/~mathieu/libart/internals.html#INTERNALS-SCANLINE
import (
"image"
"image/draw"
"math"
"golang.org/x/image/math/f32"
)
func midPoint(p, q f32.Vec2) f32.Vec2 {
return f32.Vec2{
(p[0] + q[0]) * 0.5,
(p[1] + q[1]) * 0.5,
}
}
func lerp(t float32, p, q f32.Vec2) f32.Vec2 {
return f32.Vec2{
p[0] + t*(q[0]-p[0]),
p[1] + t*(q[1]-p[1]),
}
}
func clamp(i, width int32) uint {
if i < 0 {
return 0
}
if i < width {
return uint(i)
}
return uint(width)
}
// NewRasterizer returns a new Rasterizer whose rendered mask image is bounded
// by the given width and height.
func NewRasterizer(w, h int) *Rasterizer {
return &Rasterizer{
area: make([]float32, w*h),
size: image.Point{w, h},
}
}
// Raster is a 2-D vector graphics rasterizer.
type Rasterizer struct {
area []float32
size image.Point
first f32.Vec2
pen f32.Vec2
// DrawOp is the operator used for the Draw method.
//
// The zero value is draw.Over.
DrawOp draw.Op
// TODO: an exported field equivalent to the mask point in the
// draw.DrawMask function in the stdlib image/draw package?
}
// Reset resets a Rasterizer as if it was just returned by NewRasterizer.
//
// This includes setting z.DrawOp to draw.Over.
func (z *Rasterizer) Reset(w, h int) {
if n := w * h; n > cap(z.area) {
z.area = make([]float32, n)
} else {
z.area = z.area[:n]
for i := range z.area {
z.area[i] = 0
}
}
z.size = image.Point{w, h}
z.first = f32.Vec2{}
z.pen = f32.Vec2{}
z.DrawOp = draw.Over
}
// Size returns the width and height passed to NewRasterizer or Reset.
func (z *Rasterizer) Size() image.Point {
return z.size
}
// Bounds returns the rectangle from (0, 0) to the width and height passed to
// NewRasterizer or Reset.
func (z *Rasterizer) Bounds() image.Rectangle {
return image.Rectangle{Max: z.size}
}
// Pen returns the location of the path-drawing pen: the last argument to the
// most recent XxxTo call.
func (z *Rasterizer) Pen() f32.Vec2 {
return z.pen
}
// ClosePath closes the current path.
func (z *Rasterizer) ClosePath() {
z.LineTo(z.first)
}
// MoveTo starts a new path and moves the pen to a.
//
// The coordinates are allowed to be out of the Rasterizer's bounds.
func (z *Rasterizer) MoveTo(a f32.Vec2) {
z.first = a
z.pen = a
}
// LineTo adds a line segment, from the pen to b, and moves the pen to b.
//
// The coordinates are allowed to be out of the Rasterizer's bounds.
func (z *Rasterizer) LineTo(b f32.Vec2) {
// TODO: add a fixed point math implementation.
z.floatingLineTo(b)
}
// QuadTo adds a quadratic Bézier segment, from the pen via b to c, and moves
// the pen to c.
//
// The coordinates are allowed to be out of the Rasterizer's bounds.
func (z *Rasterizer) QuadTo(b, c f32.Vec2) {
a := z.pen
devsq := devSquared(a, b, c)
if devsq >= 0.333 {
const tol = 3
n := 1 + int(math.Sqrt(math.Sqrt(tol*float64(devsq))))
t, nInv := float32(0), 1/float32(n)
for i := 0; i < n-1; i++ {
t += nInv
ab := lerp(t, a, b)
bc := lerp(t, b, c)
z.LineTo(lerp(t, ab, bc))
}
}
z.LineTo(c)
}
// CubeTo adds a cubic Bézier segment, from the pen via b and c to d, and moves
// the pen to d.
//
// The coordinates are allowed to be out of the Rasterizer's bounds.
func (z *Rasterizer) CubeTo(b, c, d f32.Vec2) {
a := z.pen
devsq := devSquared(a, b, d)
if devsqAlt := devSquared(a, c, d); devsq < devsqAlt {
devsq = devsqAlt
}
if devsq >= 0.333 {
const tol = 3
n := 1 + int(math.Sqrt(math.Sqrt(tol*float64(devsq))))
t, nInv := float32(0), 1/float32(n)
for i := 0; i < n-1; i++ {
t += nInv
ab := lerp(t, a, b)
bc := lerp(t, b, c)
cd := lerp(t, c, d)
abc := lerp(t, ab, bc)
bcd := lerp(t, bc, cd)
z.LineTo(lerp(t, abc, bcd))
}
}
z.LineTo(d)
}
// devSquared returns a measure of how curvy the sequnce a to b to c is. It
// determines how many line segments will approximate a Bézier curve segment.
//
// http://lists.nongnu.org/archive/html/freetype-devel/2016-08/msg00080.html
// gives the rationale for this evenly spaced heuristic instead of a recursive
// de Casteljau approach:
//
// The reason for the subdivision by n is that I expect the "flatness"
// computation to be semi-expensive (it's done once rather than on each
// potential subdivision) and also because you'll often get fewer subdivisions.
// Taking a circular arc as a simplifying assumption (ie a spherical cow),
// where I get n, a recursive approach would get 2^⌈lg n⌉, which, if I haven't
// made any horrible mistakes, is expected to be 33% more in the limit.
func devSquared(a, b, c f32.Vec2) float32 {
devx := a[0] - 2*b[0] + c[0]
devy := a[1] - 2*b[1] + c[1]
return devx*devx + devy*devy
}
// Draw implements the Drawer interface from the standard library's image/draw
// package.
//
// The vector paths previously added via the XxxTo calls become the mask for
// drawing src onto dst.
func (z *Rasterizer) Draw(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
if src, ok := src.(*image.Uniform); ok {
_, _, _, srcA := src.RGBA()
switch dst := dst.(type) {
case *image.Alpha:
// Fast path for glyph rendering.
if srcA == 0xffff && z.DrawOp == draw.Src {
z.rasterizeDstAlphaSrcOpaqueOpSrc(dst, r)
return
}
}
}
println("TODO: the general case")
}
func (z *Rasterizer) rasterizeDstAlphaSrcOpaqueOpSrc(dst *image.Alpha, r image.Rectangle) {
// TODO: add SIMD implementations.
// TODO: add a fixed point math implementation.
// TODO: non-zero vs even-odd winding?
if r == dst.Bounds() && r == z.Bounds() {
floatingAccumulate(dst.Pix, z.area)
return
}
println("TODO: the general case")
}

76
vendor/golang.org/x/image/vector/vector_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,76 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vector
// TODO: add tests for NaN and Inf coordinates.
import (
"image"
"image/draw"
"image/png"
"os"
"testing"
"golang.org/x/image/math/f32"
)
// encodePNG is useful for manually debugging the tests.
func encodePNG(dstFilename string, src image.Image) error {
f, err := os.Create(dstFilename)
if err != nil {
return err
}
encErr := png.Encode(f, src)
closeErr := f.Close()
if encErr != nil {
return encErr
}
return closeErr
}
func TestBasicPath(t *testing.T) {
want := []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xaa, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x5f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x24, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa1, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x14, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4a, 0x00, 0x00,
0x00, 0x00, 0xcc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0x00, 0x00,
0x00, 0x00, 0x66, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xe4, 0xff, 0xff, 0xff, 0xb6, 0x00, 0x00,
0x00, 0x00, 0x0c, 0xf2, 0xff, 0xff, 0xfe, 0x9e, 0x15, 0x00, 0x15, 0x96, 0xff, 0xce, 0x00, 0x00,
0x00, 0x00, 0x00, 0x88, 0xfc, 0xe3, 0x43, 0x00, 0x00, 0x00, 0x00, 0x06, 0xcd, 0xdc, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xde, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}
z := NewRasterizer(16, 16)
z.MoveTo(f32.Vec2{2, 2})
z.LineTo(f32.Vec2{8, 2})
z.QuadTo(f32.Vec2{14, 2}, f32.Vec2{14, 14})
z.CubeTo(f32.Vec2{8, 2}, f32.Vec2{5, 20}, f32.Vec2{2, 8})
z.ClosePath()
dst := image.NewAlpha(z.Bounds())
z.DrawOp = draw.Src
z.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
got := dst.Pix
if len(got) != len(want) {
t.Fatalf("len(got)=%d and len(want)=%d differ", len(got), len(want))
}
for i := range got {
delta := int(got[i]) - int(want[i])
// The +/- 2 allows different implementations to give different
// rounding errors.
if delta < -2 || +2 < delta {
t.Errorf("i=%d: got %#02x, want %#02x", i, got[i], want[i])
}
}
}

8
vendor/golang.org/x/image/webp/decode.go сгенерированный поставляемый
Просмотреть файл

@@ -2,11 +2,9 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package webp implements a decoder for WEBP images.
//
// WEBP is defined at:
// https://developers.google.com/speed/webp/docs/riff_container
package webp // import "golang.org/x/image/webp"
// +build go1.6
package webp
import (
"bytes"

2
vendor/golang.org/x/image/webp/decode_test.go сгенерированный поставляемый
Просмотреть файл

@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.6
package webp
import (

30
vendor/golang.org/x/image/webp/webp.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,30 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package webp implements a decoder for WEBP images.
//
// WEBP is defined at:
// https://developers.google.com/speed/webp/docs/riff_container
//
// It requires Go 1.6 or later.
package webp // import "golang.org/x/image/webp"
// This blank Go file, other than the package clause, exists so that this
// package can be built for Go 1.5 and earlier. (The other files in this
// package are all marked "+build go1.6" for the NYCbCrA types introduced in Go
// 1.6). There is no functionality in a blank package, but some image
// manipulation programs might still underscore import this package for the
// side effect of registering the WEBP format with the standard library's
// image.RegisterFormat and image.Decode functions. For example, that program
// might contain:
//
// // Underscore imports to register some formats for image.Decode.
// import _ "image/gif"
// import _ "image/jpeg"
// import _ "image/png"
// import _ "golang.org/x/image/webp"
//
// Such a program will still compile for Go 1.5 (due to this placeholder Go
// file). It will simply not be able to recognize and decode WEBP (but still
// handle GIF, JPEG and PNG).

28
vendor/golang.org/x/sys/unix/asm_linux_s390x.s сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,28 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build s390x
// +build linux
// +build !gccgo
#include "textflag.h"
//
// System calls for s390x, Linux
//
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-56
BR syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80
BR syscall·Syscall6(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
BR syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
BR syscall·RawSyscall6(SB)

17
vendor/golang.org/x/sys/unix/mkall.sh сгенерированный поставляемый
Просмотреть файл

@@ -161,7 +161,7 @@ freebsd_arm)
mkerrors="$mkerrors"
mksyscall="./mksyscall.pl -l32 -arm"
mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
# Let the type of C char be singed for making the bare syscall
# Let the type of C char be signed for making the bare syscall
# API consistent across over platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
@@ -194,7 +194,7 @@ linux_arm64)
exit 1
fi
mksysnum="./mksysnum_linux.pl $unistd_h"
# Let the type of C char be singed for making the bare syscall
# Let the type of C char be signed for making the bare syscall
# API consistent across over platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
@@ -212,6 +212,17 @@ linux_ppc64le)
mksysnum="./mksysnum_linux.pl $unistd_h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
linux_s390x)
GOOSARCH_in=syscall_linux_s390x.go
unistd_h=/usr/include/asm/unistd.h
mkerrors="$mkerrors -m64"
mksysnum="./mksysnum_linux.pl $unistd_h"
# Let the type of C char be signed to make the bare sys
# API more consistent between platforms.
# This is a deliberate departure from the way the syscall
# package generates its version of the types file.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
netbsd_386)
mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32 -netbsd"
@@ -269,6 +280,6 @@ esac
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
if [ -n "$mktypes" ]; then
echo "echo // +build $GOARCH,$GOOS > ztypes_$GOOSARCH.go";
echo "$mktypes types_$GOOS.go | gofmt >>ztypes_$GOOSARCH.go";
echo "$mktypes types_$GOOS.go | go run mkpost.go >>ztypes_$GOOSARCH.go";
fi
) | $run

62
vendor/golang.org/x/sys/unix/mkpost.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,62 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
// mkpost processes the output of cgo -godefs to
// modify the generated types. It is used to clean up
// the sys API in an architecture specific manner.
//
// mkpost is run after cgo -godefs by mkall.sh.
package main
import (
"fmt"
"go/format"
"io/ioutil"
"log"
"os"
"regexp"
)
func main() {
b, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Fatal(err)
}
s := string(b)
goarch := os.Getenv("GOARCH")
goos := os.Getenv("GOOS")
if goarch == "s390x" && goos == "linux" {
// Export the types of PtraceRegs fields.
re := regexp.MustCompile("ptrace(Psw|Fpregs|Per)")
s = re.ReplaceAllString(s, "Ptrace$1")
// Replace padding fields inserted by cgo with blank identifiers.
re = regexp.MustCompile("Pad_cgo[A-Za-z0-9_]*")
s = re.ReplaceAllString(s, "_")
// Replace other unwanted fields with blank identifiers.
re = regexp.MustCompile("X_[A-Za-z0-9_]*")
s = re.ReplaceAllString(s, "_")
// Replace the control_regs union with a blank identifier for now.
re = regexp.MustCompile("(Control_regs)\\s+\\[0\\]uint64")
s = re.ReplaceAllString(s, "_ [0]uint64")
}
// gofmt
b, err = format.Source([]byte(s))
if err != nil {
log.Fatal(err)
}
// Append this command to the header to show where the new file
// came from.
re := regexp.MustCompile("(cgo -godefs [a-zA-Z0-9_]+\\.go.*)")
b = re.ReplaceAll(b, []byte("$1 | go run mkpost.go"))
fmt.Printf("%s", b)
}

29
vendor/golang.org/x/sys/unix/syscall_bsd_test.go сгенерированный поставляемый
Просмотреть файл

@@ -7,6 +7,7 @@
package unix_test
import (
"os/exec"
"runtime"
"testing"
@@ -14,23 +15,37 @@ import (
)
const MNT_WAIT = 1
const MNT_NOWAIT = 2
func TestGetfsstat(t *testing.T) {
n, err := unix.Getfsstat(nil, MNT_WAIT)
const flags = MNT_NOWAIT // see golang.org/issue/16937
n, err := unix.Getfsstat(nil, flags)
if err != nil {
t.Fatal(err)
}
data := make([]unix.Statfs_t, n)
n, err = unix.Getfsstat(data, MNT_WAIT)
n2, err := unix.Getfsstat(data, flags)
if err != nil {
t.Fatal(err)
}
empty := unix.Statfs_t{}
for _, stat := range data {
if stat == empty {
t.Fatal("an empty Statfs_t struct was returned")
if n != n2 {
t.Errorf("Getfsstat(nil) = %d, but subsequent Getfsstat(slice) = %d", n, n2)
}
for i, stat := range data {
if stat == (unix.Statfs_t{}) {
t.Errorf("index %v is an empty Statfs_t struct", i)
}
}
if t.Failed() {
for i, stat := range data[:n2] {
t.Logf("data[%v] = %+v", i, stat)
}
mount, err := exec.Command("mount").CombinedOutput()
if err != nil {
t.Logf("mount: %v\n%s", err, mount)
} else {
t.Logf("mount: %s", mount)
}
}
}

2
vendor/golang.org/x/sys/unix/syscall_darwin.go сгенерированный поставляемый
Просмотреть файл

@@ -144,6 +144,7 @@ func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (
uintptr(options),
0,
)
use(unsafe.Pointer(_p0))
if e1 != 0 {
return nil, e1
}
@@ -196,6 +197,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
}
r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags))
use(unsafe.Pointer(_p0))
n = int(r0)
if e1 != 0 {
err = e1

1
vendor/golang.org/x/sys/unix/syscall_dragonfly.go сгенерированный поставляемый
Просмотреть файл

@@ -109,6 +109,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
}
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
use(unsafe.Pointer(_p0))
n = int(r0)
if e1 != 0 {
err = e1

1
vendor/golang.org/x/sys/unix/syscall_freebsd.go сгенерированный поставляемый
Просмотреть файл

@@ -129,6 +129,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
}
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
use(unsafe.Pointer(_p0))
n = int(r0)
if e1 != 0 {
err = e1

11
vendor/golang.org/x/sys/unix/syscall_linux.go сгенерированный поставляемый
Просмотреть файл

@@ -60,6 +60,15 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
return openat(dirfd, path, flags|O_LARGEFILE, mode)
}
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
if len(fds) == 0 {
return ppoll(nil, 0, timeout, sigmask)
}
return ppoll(&fds[0], len(fds), timeout, sigmask)
}
//sys readlinkat(dirfd int, path string, buf []byte) (n int, err error)
func Readlink(path string, buf []byte) (n int, err error) {
@@ -1043,8 +1052,6 @@ func Munmap(b []byte) (err error) {
// Newfstatat
// Nfsservctl
// Personality
// Poll
// Ppoll
// Pselect6
// Ptrace
// Putpmsg

9
vendor/golang.org/x/sys/unix/syscall_linux_386.go сгенерированный поставляемый
Просмотреть файл

@@ -388,3 +388,12 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

9
vendor/golang.org/x/sys/unix/syscall_linux_amd64.go сгенерированный поставляемый
Просмотреть файл

@@ -146,3 +146,12 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

9
vendor/golang.org/x/sys/unix/syscall_linux_arm.go сгенерированный поставляемый
Просмотреть файл

@@ -252,3 +252,12 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

12
vendor/golang.org/x/sys/unix/syscall_linux_arm64.go сгенерированный поставляемый
Просмотреть файл

@@ -178,3 +178,15 @@ const (
SYS_EPOLL_CREATE = 1042
SYS_EPOLL_WAIT = 1069
)
func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec
if timeout >= 0 {
ts = new(Timespec)
*ts = NsecToTimespec(int64(timeout) * 1e6)
}
if len(fds) == 0 {
return ppoll(nil, 0, ts, nil)
}
return ppoll(&fds[0], len(fds), ts, nil)
}

9
vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go сгенерированный поставляемый
Просмотреть файл

@@ -204,3 +204,12 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

9
vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go сгенерированный поставляемый
Просмотреть файл

@@ -124,3 +124,12 @@ func Pipe2(p []int, flags int) (err error) {
p[1] = int(pp[1])
return
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

329
vendor/golang.org/x/sys/unix/syscall_linux_s390x.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,329 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build s390x,linux
package unix
import (
"unsafe"
)
//sys Dup2(oldfd int, newfd int) (err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int)
//sysnb Geteuid() (euid int)
//sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int)
//sysnb InotifyInit() (fd int, err error)
//sys Lchown(path string, uid int, gid int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error)
//sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error)
//sys Setfsuid(uid int) (err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
//sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
//sysnb setgroups(n int, list *_Gid_t) (err error)
func Getpagesize() int { return 4096 }
//sysnb Gettimeofday(tv *Timeval) (err error)
func Time(t *Time_t) (tt Time_t, err error) {
var tv Timeval
err = Gettimeofday(&tv)
if err != nil {
return 0, err
}
if t != nil {
*t = Time_t(tv.Sec)
}
return Time_t(tv.Sec), nil
}
//sys Utime(path string, buf *Utimbuf) (err error)
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = nsec % 1e9
return
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Sec = nsec / 1e9
tv.Usec = nsec % 1e9 / 1e3
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0) // pipe2 is the same as pipe when flags are set to 0.
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Ioperm(from int, num int, on int) (err error) {
return ENOSYS
}
func Iopl(level int) (err error) {
return ENOSYS
}
func (r *PtraceRegs) PC() uint64 { return r.Psw.Addr }
func (r *PtraceRegs) SetPC(pc uint64) { r.Psw.Addr = pc }
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
// Linux on s390x uses the old mmap interface, which requires arguments to be passed in a struct.
// mmap2 also requires arguments to be passed in a struct; it is currently not exposed in <asm/unistd.h>.
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
mmap_args := [6]uintptr{addr, length, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)}
r0, _, e1 := Syscall(SYS_MMAP, uintptr(unsafe.Pointer(&mmap_args[0])), 0, 0)
use(unsafe.Pointer(&mmap_args[0]))
xaddr = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// On s390x Linux, all the socket calls go through an extra indirection.
// The arguments to the underlying system call (SYS_SOCKETCALL) are the
// number below and a pointer to an array of uintptr.
const (
// see linux/net.h
netSocket = 1
netBind = 2
netConnect = 3
netListen = 4
netAccept = 5
netGetSockName = 6
netGetPeerName = 7
netSocketPair = 8
netSend = 9
netRecv = 10
netSendTo = 11
netRecvFrom = 12
netShutdown = 13
netSetSockOpt = 14
netGetSockOpt = 15
netSendMsg = 16
netRecvMsg = 17
netAccept4 = 18
netRecvMMsg = 19
netSendMMsg = 20
)
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (int, error) {
args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))}
fd, _, err := Syscall(SYS_SOCKETCALL, netAccept, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(fd), nil
}
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (int, error) {
args := [4]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags)}
fd, _, err := Syscall(SYS_SOCKETCALL, netAccept4, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(fd), nil
}
func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) error {
args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))}
_, _, err := RawSyscall(SYS_SOCKETCALL, netGetSockName, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) error {
args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))}
_, _, err := RawSyscall(SYS_SOCKETCALL, netGetPeerName, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func socketpair(domain int, typ int, flags int, fd *[2]int32) error {
args := [4]uintptr{uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd))}
_, _, err := RawSyscall(SYS_SOCKETCALL, netSocketPair, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func bind(s int, addr unsafe.Pointer, addrlen _Socklen) error {
args := [3]uintptr{uintptr(s), uintptr(addr), uintptr(addrlen)}
_, _, err := Syscall(SYS_SOCKETCALL, netBind, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func connect(s int, addr unsafe.Pointer, addrlen _Socklen) error {
args := [3]uintptr{uintptr(s), uintptr(addr), uintptr(addrlen)}
_, _, err := Syscall(SYS_SOCKETCALL, netConnect, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func socket(domain int, typ int, proto int) (int, error) {
args := [3]uintptr{uintptr(domain), uintptr(typ), uintptr(proto)}
fd, _, err := RawSyscall(SYS_SOCKETCALL, netSocket, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(fd), nil
}
func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) error {
args := [5]uintptr{uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen))}
_, _, err := Syscall(SYS_SOCKETCALL, netGetSockOpt, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) error {
args := [4]uintptr{uintptr(s), uintptr(level), uintptr(name), uintptr(val)}
_, _, err := Syscall(SYS_SOCKETCALL, netSetSockOpt, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (int, error) {
var base uintptr
if len(p) > 0 {
base = uintptr(unsafe.Pointer(&p[0]))
}
args := [6]uintptr{uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))}
n, _, err := Syscall(SYS_SOCKETCALL, netRecvFrom, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(n), nil
}
func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) error {
var base uintptr
if len(p) > 0 {
base = uintptr(unsafe.Pointer(&p[0]))
}
args := [6]uintptr{uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen)}
_, _, err := Syscall(SYS_SOCKETCALL, netSendTo, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func recvmsg(s int, msg *Msghdr, flags int) (int, error) {
args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)}
n, _, err := Syscall(SYS_SOCKETCALL, netRecvMsg, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(n), nil
}
func sendmsg(s int, msg *Msghdr, flags int) (int, error) {
args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)}
n, _, err := Syscall(SYS_SOCKETCALL, netSendMsg, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(n), nil
}
func Listen(s int, n int) error {
args := [2]uintptr{uintptr(s), uintptr(n)}
_, _, err := Syscall(SYS_SOCKETCALL, netListen, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func Shutdown(s, how int) error {
args := [2]uintptr{uintptr(s), uintptr(how)}
_, _, err := Syscall(SYS_SOCKETCALL, netShutdown, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

76
vendor/golang.org/x/sys/unix/syscall_linux_test.go сгенерированный поставляемый
Просмотреть файл

@@ -15,6 +15,82 @@ import (
"golang.org/x/sys/unix"
)
func TestPoll(t *testing.T) {
f, cleanup := mktmpfifo(t)
defer cleanup()
const timeout = 100
ok := make(chan bool, 1)
go func() {
select {
case <-time.After(10 * timeout * time.Millisecond):
t.Errorf("Poll: failed to timeout after %d milliseconds", 10*timeout)
case <-ok:
}
}()
fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
n, err := unix.Poll(fds, timeout)
ok <- true
if err != nil {
t.Errorf("Poll: unexpected error: %v", err)
return
}
if n != 0 {
t.Errorf("Poll: wrong number of events: got %v, expected %v", n, 0)
return
}
}
func TestPpoll(t *testing.T) {
f, cleanup := mktmpfifo(t)
defer cleanup()
const timeout = 100 * time.Millisecond
ok := make(chan bool, 1)
go func() {
select {
case <-time.After(10 * timeout):
t.Errorf("Ppoll: failed to timeout after %d", 10*timeout)
case <-ok:
}
}()
fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
timeoutTs := unix.NsecToTimespec(int64(timeout))
n, err := unix.Ppoll(fds, &timeoutTs, nil)
ok <- true
if err != nil {
t.Errorf("Ppoll: unexpected error: %v", err)
return
}
if n != 0 {
t.Errorf("Ppoll: wrong number of events: got %v, expected %v", n, 0)
return
}
}
// mktmpfifo creates a temporary FIFO and provides a cleanup function.
func mktmpfifo(t *testing.T) (*os.File, func()) {
err := unix.Mkfifo("fifo", 0666)
if err != nil {
t.Fatalf("mktmpfifo: failed to create FIFO: %v", err)
}
f, err := os.OpenFile("fifo", os.O_RDWR, 0666)
if err != nil {
os.Remove("fifo")
t.Fatalf("mktmpfifo: failed to open FIFO: %v", err)
}
return f, func() {
f.Close()
os.Remove("fifo")
}
}
func TestTime(t *testing.T) {
var ut unix.Time_t
ut2, err := unix.Time(&ut)

1
vendor/golang.org/x/sys/unix/syscall_openbsd.go сгенерированный поставляемый
Просмотреть файл

@@ -111,6 +111,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
}
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
use(unsafe.Pointer(_p0))
n = int(r0)
if e1 != 0 {
err = e1

46
vendor/golang.org/x/sys/unix/syscall_solaris.go сгенерированный поставляемый
Просмотреть файл

@@ -72,18 +72,20 @@ func ParseDirent(buf []byte, max int, names []string) (consumed int, count int,
return origlen - len(buf), count, names
}
func pipe() (r uintptr, w uintptr, err uintptr)
//sysnb pipe(p *[2]_C_int) (n int, err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
r0, w0, e1 := pipe()
if e1 != 0 {
err = syscall.Errno(e1)
var pp [2]_C_int
n, err := pipe(&pp)
if n != 0 {
return err
}
p[0], p[1] = int(r0), int(w0)
return
p[0] = int(pp[0])
p[1] = int(pp[1])
return nil
}
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
@@ -269,24 +271,34 @@ func (w WaitStatus) StopSignal() syscall.Signal {
func (w WaitStatus) TrapCause() int { return -1 }
func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr)
//sys wait4(pid int32, statusp *_C_int, options int, rusage *Rusage) (wpid int32, err error)
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage)
if e1 != 0 {
err = syscall.Errno(e1)
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (int, error) {
var status _C_int
rpid, err := wait4(int32(pid), &status, options, rusage)
wpid := int(rpid)
if wpid == -1 {
return wpid, err
}
return int(r0), err
if wstatus != nil {
*wstatus = WaitStatus(status)
}
return wpid, nil
}
func gethostname() (name string, err uintptr)
//sys gethostname(buf []byte) (n int, err error)
func Gethostname() (name string, err error) {
name, e1 := gethostname()
if e1 != 0 {
err = syscall.Errno(e1)
var buf [MaxHostNameLen]byte
n, err := gethostname(buf[:])
if n != 0 {
return "", err
}
return name, err
n = clen(buf[:])
if n < 1 {
return "", EFAULT
}
return string(buf[:n]), nil
}
//sys utimes(path string, times *[2]Timeval) (err error)

37
vendor/golang.org/x/sys/unix/types_linux.go сгенерированный поставляемый
Просмотреть файл

@@ -24,6 +24,7 @@ package unix
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netpacket/packet.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <sys/epoll.h>
@@ -102,10 +103,22 @@ typedef struct user_pt_regs PtraceRegs;
typedef struct pt_regs PtraceRegs;
#elif defined(__mips__)
typedef struct user PtraceRegs;
#elif defined(__s390x__)
typedef struct _user_regs_struct PtraceRegs;
#else
typedef struct user_regs_struct PtraceRegs;
#endif
#if defined(__s390x__)
typedef struct _user_psw_struct ptracePsw;
typedef struct _user_fpregs_struct ptraceFpregs;
typedef struct _user_per_struct ptracePer;
#else
typedef struct {} ptracePsw;
typedef struct {} ptraceFpregs;
typedef struct {} ptracePer;
#endif
// The real epoll_event is a union, and godefs doesn't handle it well.
struct my_epoll_event {
uint32_t events;
@@ -113,8 +126,7 @@ struct my_epoll_event {
// padding is not specified in linux/eventpoll.h but added to conform to the
// alignment requirements of EABI
int32_t padFd;
#endif
#ifdef __powerpc64__
#elif defined(__powerpc64__) || defined(__s390x__)
int32_t _padFd;
#endif
int32_t fd;
@@ -393,6 +405,13 @@ const SizeofInotifyEvent = C.sizeof_struct_inotify_event
// Register structures
type PtraceRegs C.PtraceRegs
// Structures contained in PtraceRegs on s390x (exported by mkpost.go)
type ptracePsw C.ptracePsw
type ptraceFpregs C.ptraceFpregs
type ptracePer C.ptracePer
// Misc
type FdSet C.fd_set
@@ -412,6 +431,20 @@ const (
AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
)
type PollFd C.struct_pollfd
const (
POLLIN = C.POLLIN
POLLPRI = C.POLLPRI
POLLOUT = C.POLLOUT
POLLRDHUP = C.POLLRDHUP
POLLERR = C.POLLERR
POLLHUP = C.POLLHUP
POLLNVAL = C.POLLNVAL
)
type Sigset_t C.sigset_t
// Terminal handling
type Termios C.termios_t

2
vendor/golang.org/x/sys/unix/types_solaris.go сгенерированный поставляемый
Просмотреть файл

@@ -22,6 +22,7 @@ package unix
#define __USE_LEGACY_PROTOTYPES__ // iovec
#include <dirent.h>
#include <fcntl.h>
#include <netdb.h>
#include <limits.h>
#include <signal.h>
#include <termios.h>
@@ -81,6 +82,7 @@ const (
sizeofLong = C.sizeof_long
sizeofLongLong = C.sizeof_longlong
PathMax = C.PATH_MAX
MaxHostNameLen = C.MAXHOSTNAMELEN
)
// Basic types

1
vendor/golang.org/x/sys/unix/zerrors_linux_386.go сгенерированный поставляемый
Просмотреть файл

@@ -216,6 +216,7 @@ const (
CLONE_FILES = 0x400
CLONE_FS = 0x200
CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000

1
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go сгенерированный поставляемый
Просмотреть файл

@@ -216,6 +216,7 @@ const (
CLONE_FILES = 0x400
CLONE_FS = 0x200
CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000

1
vendor/golang.org/x/sys/unix/zerrors_linux_arm.go сгенерированный поставляемый
Просмотреть файл

@@ -212,6 +212,7 @@ const (
CLONE_FILES = 0x400
CLONE_FS = 0x200
CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000

1
vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go сгенерированный поставляемый
Просмотреть файл

@@ -222,6 +222,7 @@ const (
CLONE_FILES = 0x400
CLONE_FS = 0x200
CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000

1
vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go сгенерированный поставляемый
Просмотреть файл

@@ -221,6 +221,7 @@ const (
CLONE_FILES = 0x400
CLONE_FS = 0x200
CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000

1
vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go сгенерированный поставляемый
Просмотреть файл

@@ -221,6 +221,7 @@ const (
CLONE_FILES = 0x400
CLONE_FS = 0x200
CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000

1
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go сгенерированный поставляемый
Просмотреть файл

@@ -223,6 +223,7 @@ const (
CLONE_FILES = 0x400
CLONE_FS = 0x200
CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000

1
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go сгенерированный поставляемый
Просмотреть файл

@@ -222,6 +222,7 @@ const (
CLONE_FILES = 0x400
CLONE_FS = 0x200
CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000

2027
vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

1
vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go сгенерированный поставляемый
Просмотреть файл

@@ -222,6 +222,7 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr)
_p0 = unsafe.Pointer(&_zero)
}
_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
use(_p0)
if e1 != 0 {
err = errnoErr(e1)
}

1
vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go сгенерированный поставляемый
Просмотреть файл

@@ -222,6 +222,7 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr)
_p0 = unsafe.Pointer(&_zero)
}
_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
use(_p0)
if e1 != 0 {
err = errnoErr(e1)
}

1
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go сгенерированный поставляемый
Просмотреть файл

@@ -222,6 +222,7 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr)
_p0 = unsafe.Pointer(&_zero)
}
_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
use(_p0)
if e1 != 0 {
err = errnoErr(e1)
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше