OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [crypto/] [tls/] [common.go] - Rev 761

Go to most recent revision | Compare with Previous | Blame | View Log

// Copyright 2009 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 tls

import (
        "crypto"
        "crypto/rand"
        "crypto/x509"
        "io"
        "strings"
        "sync"
        "time"
)

const (
        maxPlaintext    = 16384        // maximum plaintext payload length
        maxCiphertext   = 16384 + 2048 // maximum ciphertext payload length
        recordHeaderLen = 5            // record header length
        maxHandshake    = 65536        // maximum handshake we support (protocol max is 16 MB)

        versionSSL30 = 0x0300
        versionTLS10 = 0x0301

        minVersion = versionSSL30
        maxVersion = versionTLS10
)

// TLS record types.
type recordType uint8

const (
        recordTypeChangeCipherSpec recordType = 20
        recordTypeAlert            recordType = 21
        recordTypeHandshake        recordType = 22
        recordTypeApplicationData  recordType = 23
)

// TLS handshake message types.
const (
        typeClientHello        uint8 = 1
        typeServerHello        uint8 = 2
        typeCertificate        uint8 = 11
        typeServerKeyExchange  uint8 = 12
        typeCertificateRequest uint8 = 13
        typeServerHelloDone    uint8 = 14
        typeCertificateVerify  uint8 = 15
        typeClientKeyExchange  uint8 = 16
        typeFinished           uint8 = 20
        typeCertificateStatus  uint8 = 22
        typeNextProtocol       uint8 = 67 // Not IANA assigned
)

// TLS compression types.
const (
        compressionNone uint8 = 0
)

// TLS extension numbers
var (
        extensionServerName      uint16 = 0
        extensionStatusRequest   uint16 = 5
        extensionSupportedCurves uint16 = 10
        extensionSupportedPoints uint16 = 11
        extensionNextProtoNeg    uint16 = 13172 // not IANA assigned
)

// TLS Elliptic Curves
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
var (
        curveP256 uint16 = 23
        curveP384 uint16 = 24
        curveP521 uint16 = 25
)

// TLS Elliptic Curve Point Formats
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
var (
        pointFormatUncompressed uint8 = 0
)

// TLS CertificateStatusType (RFC 3546)
const (
        statusTypeOCSP uint8 = 1
)

// Certificate types (for certificateRequestMsg)
const (
        certTypeRSASign    = 1 // A certificate containing an RSA key
        certTypeDSSSign    = 2 // A certificate containing a DSA key
        certTypeRSAFixedDH = 3 // A certificate containing a static DH key
        certTypeDSSFixedDH = 4 // A certificate containing a static DH key
        // Rest of these are reserved by the TLS spec
)

// ConnectionState records basic TLS details about the connection.
type ConnectionState struct {
        HandshakeComplete          bool
        CipherSuite                uint16
        NegotiatedProtocol         string
        NegotiatedProtocolIsMutual bool

        // ServerName contains the server name indicated by the client, if any.
        // (Only valid for server connections.)
        ServerName string

        // the certificate chain that was presented by the other side
        PeerCertificates []*x509.Certificate
        // the verified certificate chains built from PeerCertificates.
        VerifiedChains [][]*x509.Certificate
}

// ClientAuthType declares the policy the server will follow for
// TLS Client Authentication.
type ClientAuthType int

const (
        NoClientCert ClientAuthType = iota
        RequestClientCert
        RequireAnyClientCert
        VerifyClientCertIfGiven
        RequireAndVerifyClientCert
)

// A Config structure is used to configure a TLS client or server. After one
// has been passed to a TLS function it must not be modified.
type Config struct {
        // Rand provides the source of entropy for nonces and RSA blinding.
        // If Rand is nil, TLS uses the cryptographic random reader in package
        // crypto/rand.
        Rand io.Reader

        // Time returns the current time as the number of seconds since the epoch.
        // If Time is nil, TLS uses time.Now.
        Time func() time.Time

        // Certificates contains one or more certificate chains
        // to present to the other side of the connection.
        // Server configurations must include at least one certificate.
        Certificates []Certificate

        // NameToCertificate maps from a certificate name to an element of
        // Certificates. Note that a certificate name can be of the form
        // '*.example.com' and so doesn't have to be a domain name as such.
        // See Config.BuildNameToCertificate
        // The nil value causes the first element of Certificates to be used
        // for all connections.
        NameToCertificate map[string]*Certificate

        // RootCAs defines the set of root certificate authorities
        // that clients use when verifying server certificates.
        // If RootCAs is nil, TLS uses the host's root CA set.
        RootCAs *x509.CertPool

        // NextProtos is a list of supported, application level protocols.
        NextProtos []string

        // ServerName is included in the client's handshake to support virtual
        // hosting.
        ServerName string

        // ClientAuth determines the server's policy for
        // TLS Client Authentication. The default is NoClientCert.
        ClientAuth ClientAuthType

        // ClientCAs defines the set of root certificate authorities
        // that servers use if required to verify a client certificate
        // by the policy in ClientAuth.
        ClientCAs *x509.CertPool

        // InsecureSkipVerify controls whether a client verifies the
        // server's certificate chain and host name.
        // If InsecureSkipVerify is true, TLS accepts any certificate
        // presented by the server and any host name in that certificate.
        // In this mode, TLS is susceptible to man-in-the-middle attacks.
        // This should be used only for testing.
        InsecureSkipVerify bool

        // CipherSuites is a list of supported cipher suites. If CipherSuites
        // is nil, TLS uses a list of suites supported by the implementation.
        CipherSuites []uint16
}

func (c *Config) rand() io.Reader {
        r := c.Rand
        if r == nil {
                return rand.Reader
        }
        return r
}

func (c *Config) time() time.Time {
        t := c.Time
        if t == nil {
                t = time.Now
        }
        return t()
}

func (c *Config) rootCAs() *x509.CertPool {
        s := c.RootCAs
        if s == nil {
                s = defaultRoots()
        }
        return s
}

func (c *Config) cipherSuites() []uint16 {
        s := c.CipherSuites
        if s == nil {
                s = defaultCipherSuites()
        }
        return s
}

// getCertificateForName returns the best certificate for the given name,
// defaulting to the first element of c.Certificates if there are no good
// options.
func (c *Config) getCertificateForName(name string) *Certificate {
        if len(c.Certificates) == 1 || c.NameToCertificate == nil {
                // There's only one choice, so no point doing any work.
                return &c.Certificates[0]
        }

        name = strings.ToLower(name)
        for len(name) > 0 && name[len(name)-1] == '.' {
                name = name[:len(name)-1]
        }

        if cert, ok := c.NameToCertificate[name]; ok {
                return cert
        }

        // try replacing labels in the name with wildcards until we get a
        // match.
        labels := strings.Split(name, ".")
        for i := range labels {
                labels[i] = "*"
                candidate := strings.Join(labels, ".")
                if cert, ok := c.NameToCertificate[candidate]; ok {
                        return cert
                }
        }

        // If nothing matches, return the first certificate.
        return &c.Certificates[0]
}

// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate
// from the CommonName and SubjectAlternateName fields of each of the leaf
// certificates.
func (c *Config) BuildNameToCertificate() {
        c.NameToCertificate = make(map[string]*Certificate)
        for i := range c.Certificates {
                cert := &c.Certificates[i]
                x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
                if err != nil {
                        continue
                }
                if len(x509Cert.Subject.CommonName) > 0 {
                        c.NameToCertificate[x509Cert.Subject.CommonName] = cert
                }
                for _, san := range x509Cert.DNSNames {
                        c.NameToCertificate[san] = cert
                }
        }
}

// A Certificate is a chain of one or more certificates, leaf first.
type Certificate struct {
        Certificate [][]byte
        PrivateKey  crypto.PrivateKey // supported types: *rsa.PrivateKey
        // OCSPStaple contains an optional OCSP response which will be served
        // to clients that request it.
        OCSPStaple []byte
        // Leaf is the parsed form of the leaf certificate, which may be
        // initialized using x509.ParseCertificate to reduce per-handshake
        // processing for TLS clients doing client authentication. If nil, the
        // leaf certificate will be parsed as needed.
        Leaf *x509.Certificate
}

// A TLS record.
type record struct {
        contentType  recordType
        major, minor uint8
        payload      []byte
}

type handshakeMessage interface {
        marshal() []byte
        unmarshal([]byte) bool
}

// mutualVersion returns the protocol version to use given the advertised
// version of the peer.
func mutualVersion(vers uint16) (uint16, bool) {
        if vers < minVersion {
                return 0, false
        }
        if vers > maxVersion {
                vers = maxVersion
        }
        return vers, true
}

var emptyConfig Config

func defaultConfig() *Config {
        return &emptyConfig
}

var once sync.Once

func defaultRoots() *x509.CertPool {
        once.Do(initDefaults)
        return varDefaultRoots
}

func defaultCipherSuites() []uint16 {
        once.Do(initDefaults)
        return varDefaultCipherSuites
}

func initDefaults() {
        initDefaultRoots()
        initDefaultCipherSuites()
}

var (
        varDefaultRoots        *x509.CertPool
        varDefaultCipherSuites []uint16
)

func initDefaultCipherSuites() {
        varDefaultCipherSuites = make([]uint16, len(cipherSuites))
        for i, suite := range cipherSuites {
                varDefaultCipherSuites[i] = suite.id
        }
}

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.