using glide

This commit is contained in:
fatedier
2017-11-01 16:21:57 +08:00
parent ad858a0d32
commit 0f1005ff61
1073 changed files with 293160 additions and 171 deletions

45
vendor/github.com/tjfoc/gmsm/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,45 @@
sudo: false
language:
- go
go:
- 1.8.3
#before_install:
#- git rm -r --cached .
#- git add .
#- git commit -m 'update .gitignore'
install:
- go get -v github.com/golang/lint/golint
- go get -v golang.org/x/crypto/ripemd160
- go get -v golang.org/x/crypto/sha3
- go build -v ./sm2
- go build -v ./sm3
- go build -v ./sm4
script:
- go vet ./sm2
- go vet ./sm3
- go vet ./sm4
- $HOME/gopath/bin/golint .
- export GOPATH="${TRAVIS_BUILD_DIR}/Godeps/_workspace:$GOPATH"
- export PATH="${TRAVIS_BUILD_DIR}/Godeps/_workspace/bin:$PATH"
- ls /home/travis/gopath/src/
- go test -v ./sm2
- go test -v ./sm3
- go test -v ./sm4
after_failure:
- |
echo "Error!"
notifications:
email:
recipients:
- zhiqiang@tj-fintech.com
- yanwenze@tj-fintech.com
- maoxiuze@tj-fintech.com
- yewei@tj-fintech.com
on_success: never # default: change
on_failure: never # default: always

17
vendor/github.com/tjfoc/gmsm/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,17 @@
## 更新日志
主要更新:
- 添加以下oid<br>
SM3WithSM2 1.2.156.10197.1.501<br>
SHA1WithSM2 1.2.156.10197.1.502<br>
SHA256WithSM2 1.2.156.10197.1.503<br>
- x509生成的证书如今可以使用SM3作为hash算法
- 引入了以下hash算法
RIPEMD160<br>
SHA3_256<br>
SHA3_384<br>
SHA3_512<br>
SHA3_SM3<br>
用户需要自己安装golang.org/x/crypto

42
vendor/github.com/tjfoc/gmsm/README.md generated vendored Normal file
View File

@@ -0,0 +1,42 @@
GM SM2/3/4 library based on Golang
Process Results
[![Build Status](https://travis-ci.org/tjfoc/gmsm.svg?branch=master)](https://travis-ci.org/tjfoc/gmsm)
基于Go语言的国密SM2/SM3/SM4加密算法库
版权所有 苏州同济区块链研究院有限公司(http://www.tj-fintech.com)
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
GMSM包含以下主要功能
SM2: 国密椭圆曲线算法库
. 支持Generate Key, Sign, Verify基础操作
. 支持加密和不加密的pem文件格式(加密方法参见RFC5958, 具体实现参加代码)
. 支持证书的生成,证书的读写(接口兼容rsa和ecdsa的证书)
. 支持证书链的操作(接口兼容rsa和ecdsa)
. 支持crypto.Signer接口
SM3: 国密hash算法库
. 支持基础的sm3Sum操作
. 支持hash.Hash接口
SM4: 国密分组密码算法库
. 支持Generate Key, Encrypt, Decrypt基础操作
. 提供Cipher.Block接口
. 支持加密和不加密的pem文件格式(加密方法为pem block加密, 具体函数为x509.EncryptPEMBlock)
关于GMSM交流 [![Join the chat at https://gitter.im/tjfoc/gmsm](https://badges.gitter.im/tjfoc/gmsm.svg)](https://gitter.im/tjfoc/gmsm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

229
vendor/github.com/tjfoc/gmsm/sm2/cert_pool.go generated vendored Normal file
View File

@@ -0,0 +1,229 @@
/*
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sm2
import (
"encoding/pem"
"errors"
"io/ioutil"
"os"
"runtime"
"sync"
)
// Possible certificate files; stop after finding one.
var certFiles = []string{
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/pki/tls/cacert.pem", // OpenELEC
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
}
// CertPool is a set of certificates.
type CertPool struct {
bySubjectKeyId map[string][]int
byName map[string][]int
certs []*Certificate
}
// NewCertPool returns a new, empty CertPool.
func NewCertPool() *CertPool {
return &CertPool{
bySubjectKeyId: make(map[string][]int),
byName: make(map[string][]int),
}
}
// Possible directories with certificate files; stop after successfully
// reading at least one file from a directory.
var certDirectories = []string{
"/etc/ssl/certs", // SLES10/SLES11, https://golang.org/issue/12139
"/system/etc/security/cacerts", // Android
}
var (
once sync.Once
systemRoots *CertPool
systemRootsErr error
)
func systemRootsPool() *CertPool {
once.Do(initSystemRoots)
return systemRoots
}
func initSystemRoots() {
systemRoots, systemRootsErr = loadSystemRoots()
}
func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
return nil, nil
}
func loadSystemRoots() (*CertPool, error) {
roots := NewCertPool()
var firstErr error
for _, file := range certFiles {
data, err := ioutil.ReadFile(file)
if err == nil {
roots.AppendCertsFromPEM(data)
return roots, nil
}
if firstErr == nil && !os.IsNotExist(err) {
firstErr = err
}
}
for _, directory := range certDirectories {
fis, err := ioutil.ReadDir(directory)
if err != nil {
if firstErr == nil && !os.IsNotExist(err) {
firstErr = err
}
continue
}
rootsAdded := false
for _, fi := range fis {
data, err := ioutil.ReadFile(directory + "/" + fi.Name())
if err == nil && roots.AppendCertsFromPEM(data) {
rootsAdded = true
}
}
if rootsAdded {
return roots, nil
}
}
return nil, firstErr
}
// SystemCertPool returns a copy of the system cert pool.
//
// Any mutations to the returned pool are not written to disk and do
// not affect any other pool.
func SystemCertPool() (*CertPool, error) {
if runtime.GOOS == "windows" {
// Issue 16736, 18609:
return nil, errors.New("crypto/x509: system root pool is not available on Windows")
}
return loadSystemRoots()
}
// findVerifiedParents attempts to find certificates in s which have signed the
// given certificate. If any candidates were rejected then errCert will be set
// to one of them, arbitrarily, and err will contain the reason that it was
// rejected.
func (s *CertPool) findVerifiedParents(cert *Certificate) (parents []int, errCert *Certificate, err error) {
if s == nil {
return
}
var candidates []int
if len(cert.AuthorityKeyId) > 0 {
candidates = s.bySubjectKeyId[string(cert.AuthorityKeyId)]
}
if len(candidates) == 0 {
candidates = s.byName[string(cert.RawIssuer)]
}
for _, c := range candidates {
if err = cert.CheckSignatureFrom(s.certs[c]); err == nil {
parents = append(parents, c)
} else {
errCert = s.certs[c]
}
}
return
}
func (s *CertPool) contains(cert *Certificate) bool {
if s == nil {
return false
}
candidates := s.byName[string(cert.RawSubject)]
for _, c := range candidates {
if s.certs[c].Equal(cert) {
return true
}
}
return false
}
// AddCert adds a certificate to a pool.
func (s *CertPool) AddCert(cert *Certificate) {
if cert == nil {
panic("adding nil Certificate to CertPool")
}
// Check that the certificate isn't being added twice.
if s.contains(cert) {
return
}
n := len(s.certs)
s.certs = append(s.certs, cert)
if len(cert.SubjectKeyId) > 0 {
keyId := string(cert.SubjectKeyId)
s.bySubjectKeyId[keyId] = append(s.bySubjectKeyId[keyId], n)
}
name := string(cert.RawSubject)
s.byName[name] = append(s.byName[name], n)
}
// AppendCertsFromPEM attempts to parse a series of PEM encoded certificates.
// It appends any certificates found to s and reports whether any certificates
// were successfully parsed.
//
// On many Linux systems, /etc/ssl/cert.pem will contain the system wide set
// of root CAs in a format suitable for this function.
func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) {
for len(pemCerts) > 0 {
var block *pem.Block
block, pemCerts = pem.Decode(pemCerts)
if block == nil {
break
}
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
continue
}
cert, err := ParseCertificate(block.Bytes)
if err != nil {
continue
}
s.AddCert(cert)
ok = true
}
return
}
// Subjects returns a list of the DER-encoded subjects of
// all of the certificates in the pool.
func (s *CertPool) Subjects() [][]byte {
res := make([][]byte, len(s.certs))
for i, c := range s.certs {
res[i] = c.RawSubject
}
return res
}

43
vendor/github.com/tjfoc/gmsm/sm2/p256.go generated vendored Normal file
View File

@@ -0,0 +1,43 @@
/*
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sm2
import (
"crypto/elliptic"
"math/big"
"sync"
)
var initonce sync.Once
var p256Sm2Params *elliptic.CurveParams
// 取自elliptic的p256.go文件修改曲线参数为sm2
// See FIPS 186-3, section D.2.3
func initP256Sm2() {
p256Sm2Params = &elliptic.CurveParams{Name: "SM2-P-256"} // 注明为SM2
//SM2椭 椭 圆 曲 线 公 钥 密 码 算 法 推 荐 曲 线 参 数
p256Sm2Params.P, _ = new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16)
p256Sm2Params.N, _ = new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", 16)
p256Sm2Params.B, _ = new(big.Int).SetString("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", 16)
p256Sm2Params.Gx, _ = new(big.Int).SetString("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16)
p256Sm2Params.Gy, _ = new(big.Int).SetString("BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", 16)
p256Sm2Params.BitSize = 256
}
func P256Sm2() elliptic.Curve {
initonce.Do(initP256Sm2)
return p256Sm2Params
}

132
vendor/github.com/tjfoc/gmsm/sm2/pkcs1.go generated vendored Normal file
View File

@@ -0,0 +1,132 @@
/*
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sm2
import (
"crypto/rsa"
"encoding/asn1"
"errors"
"math/big"
)
// pkcs1PrivateKey is a structure which mirrors the PKCS#1 ASN.1 for an RSA private key.
type pkcs1PrivateKey struct {
Version int
N *big.Int
E int
D *big.Int
P *big.Int
Q *big.Int
// We ignore these values, if present, because rsa will calculate them.
Dp *big.Int `asn1:"optional"`
Dq *big.Int `asn1:"optional"`
Qinv *big.Int `asn1:"optional"`
AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional,omitempty"`
}
type pkcs1AdditionalRSAPrime struct {
Prime *big.Int
// We ignore these values because rsa will calculate them.
Exp *big.Int
Coeff *big.Int
}
// ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER encoded form.
func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) {
var priv pkcs1PrivateKey
rest, err := asn1.Unmarshal(der, &priv)
if len(rest) > 0 {
return nil, asn1.SyntaxError{Msg: "trailing data"}
}
if err != nil {
return nil, err
}
if priv.Version > 1 {
return nil, errors.New("x509: unsupported private key version")
}
if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 {
return nil, errors.New("x509: private key contains zero or negative value")
}
key := new(rsa.PrivateKey)
key.PublicKey = rsa.PublicKey{
E: priv.E,
N: priv.N,
}
key.D = priv.D
key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes))
key.Primes[0] = priv.P
key.Primes[1] = priv.Q
for i, a := range priv.AdditionalPrimes {
if a.Prime.Sign() <= 0 {
return nil, errors.New("x509: private key contains zero or negative prime")
}
key.Primes[i+2] = a.Prime
// We ignore the other two values because rsa will calculate
// them as needed.
}
err = key.Validate()
if err != nil {
return nil, err
}
key.Precompute()
return key, nil
}
// MarshalPKCS1PrivateKey converts a private key to ASN.1 DER encoded form.
func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte {
key.Precompute()
version := 0
if len(key.Primes) > 2 {
version = 1
}
priv := pkcs1PrivateKey{
Version: version,
N: key.N,
E: key.PublicKey.E,
D: key.D,
P: key.Primes[0],
Q: key.Primes[1],
Dp: key.Precomputed.Dp,
Dq: key.Precomputed.Dq,
Qinv: key.Precomputed.Qinv,
}
priv.AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(key.Precomputed.CRTValues))
for i, values := range key.Precomputed.CRTValues {
priv.AdditionalPrimes[i].Prime = key.Primes[2+i]
priv.AdditionalPrimes[i].Exp = values.Exp
priv.AdditionalPrimes[i].Coeff = values.Coeff
}
b, _ := asn1.Marshal(priv)
return b
}
// rsaPublicKey reflects the ASN.1 structure of a PKCS#1 public key.
type rsaPublicKey struct {
N *big.Int
E int
}

488
vendor/github.com/tjfoc/gmsm/sm2/pkcs8.go generated vendored Normal file
View File

@@ -0,0 +1,488 @@
/*
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sm2
import (
"crypto/aes"
"crypto/cipher"
"crypto/elliptic"
"crypto/hmac"
"crypto/md5"
"crypto/rand"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"errors"
"hash"
"io/ioutil"
"math/big"
"os"
"reflect"
)
/*
* reference to RFC5959 and RFC2898
*/
var (
oidPBES1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 3} // pbeWithMD5AndDES-CBC(PBES1)
oidPBES2 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 13} // id-PBES2(PBES2)
oidPBKDF2 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 12} // id-PBKDF2
oidKEYMD5 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 5}
oidKEYSHA1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 7}
oidKEYSHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 9}
oidKEYSHA512 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 11}
oidAES128CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 2}
oidAES256CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42}
oidSM2 = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
)
// reference to https://www.rfc-editor.org/rfc/rfc5958.txt
type PrivateKeyInfo struct {
Version int // v1 or v2
PrivateKeyAlgorithm []asn1.ObjectIdentifier
PrivateKey []byte
}
// reference to https://www.rfc-editor.org/rfc/rfc5958.txt
type EncryptedPrivateKeyInfo struct {
EncryptionAlgorithm Pbes2Algorithms
EncryptedData []byte
}
// reference to https://www.ietf.org/rfc/rfc2898.txt
type Pbes2Algorithms struct {
IdPBES2 asn1.ObjectIdentifier
Pbes2Params Pbes2Params
}
// reference to https://www.ietf.org/rfc/rfc2898.txt
type Pbes2Params struct {
KeyDerivationFunc Pbes2KDfs // PBES2-KDFs
EncryptionScheme Pbes2Encs // PBES2-Encs
}
// reference to https://www.ietf.org/rfc/rfc2898.txt
type Pbes2KDfs struct {
IdPBKDF2 asn1.ObjectIdentifier
Pkdf2Params Pkdf2Params
}
type Pbes2Encs struct {
EncryAlgo asn1.ObjectIdentifier
IV []byte
}
// reference to https://www.ietf.org/rfc/rfc2898.txt
type Pkdf2Params struct {
Salt []byte
IterationCount int
Prf pkix.AlgorithmIdentifier
}
type sm2PrivateKey struct {
Version int
PrivateKey []byte
NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"`
}
type pkcs8 struct {
Version int
Algo pkix.AlgorithmIdentifier
PrivateKey []byte
}
// copy from crypto/pbkdf2.go
func pbkdf(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
prf := hmac.New(h, password)
hashLen := prf.Size()
numBlocks := (keyLen + hashLen - 1) / hashLen
var buf [4]byte
dk := make([]byte, 0, numBlocks*hashLen)
U := make([]byte, hashLen)
for block := 1; block <= numBlocks; block++ {
// N.B.: || means concatenation, ^ means XOR
// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
// U_1 = PRF(password, salt || uint(i))
prf.Reset()
prf.Write(salt)
buf[0] = byte(block >> 24)
buf[1] = byte(block >> 16)
buf[2] = byte(block >> 8)
buf[3] = byte(block)
prf.Write(buf[:4])
dk = prf.Sum(dk)
T := dk[len(dk)-hashLen:]
copy(U, T)
// U_n = PRF(password, U_(n-1))
for n := 2; n <= iter; n++ {
prf.Reset()
prf.Write(U)
U = U[:0]
U = prf.Sum(U)
for x := range U {
T[x] ^= U[x]
}
}
}
return dk[:keyLen]
}
func ParseSm2PublicKey(der []byte) (*PublicKey, error) {
var pubkey pkixPublicKey
if _, err := asn1.Unmarshal(der, &pubkey); err != nil {
return nil, err
}
if !reflect.DeepEqual(pubkey.Algo.Algorithm, oidSM2) {
return nil, errors.New("x509: not sm2 elliptic curve")
}
curve := P256Sm2()
x, y := elliptic.Unmarshal(curve, pubkey.BitString.Bytes)
pub := PublicKey{
Curve: curve,
X: x,
Y: y,
}
return &pub, nil
}
func MarshalSm2PublicKey(key *PublicKey) ([]byte, error) {
var r pkixPublicKey
var algo pkix.AlgorithmIdentifier
algo.Algorithm = oidSM2
algo.Parameters.Class = 0
algo.Parameters.Tag = 6
algo.Parameters.IsCompound = false
algo.Parameters.FullBytes = []byte{6, 8, 42, 129, 28, 207, 85, 1, 130, 45} // asn1.Marshal(asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301})
r.Algo = algo
r.BitString = asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}
return asn1.Marshal(r)
}
func ParseSm2PrivateKey(der []byte) (*PrivateKey, error) {
var privKey sm2PrivateKey
if _, err := asn1.Unmarshal(der, &privKey); err != nil {
return nil, errors.New("x509: failed to parse SM2 private key: " + err.Error())
}
curve := P256Sm2()
k := new(big.Int).SetBytes(privKey.PrivateKey)
curveOrder := curve.Params().N
if k.Cmp(curveOrder) >= 0 {
return nil, errors.New("x509: invalid elliptic curve private key value")
}
priv := new(PrivateKey)
priv.Curve = curve
priv.D = k
privateKey := make([]byte, (curveOrder.BitLen()+7)/8)
for len(privKey.PrivateKey) > len(privateKey) {
if privKey.PrivateKey[0] != 0 {
return nil, errors.New("x509: invalid private key length")
}
privKey.PrivateKey = privKey.PrivateKey[1:]
}
copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
priv.X, priv.Y = curve.ScalarBaseMult(privateKey)
return priv, nil
}
func ParsePKCS8UnecryptedPrivateKey(der []byte) (*PrivateKey, error) {
var privKey pkcs8
if _, err := asn1.Unmarshal(der, &privKey); err != nil {
return nil, err
}
if !reflect.DeepEqual(privKey.Algo.Algorithm, oidSM2) {
return nil, errors.New("x509: not sm2 elliptic curve")
}
return ParseSm2PrivateKey(privKey.PrivateKey)
}
func ParsePKCS8EcryptedPrivateKey(der, pwd []byte) (*PrivateKey, error) {
var keyInfo EncryptedPrivateKeyInfo
_, err := asn1.Unmarshal(der, &keyInfo)
if err != nil {
return nil, errors.New("x509: unknown format")
}
if !reflect.DeepEqual(keyInfo.EncryptionAlgorithm.IdPBES2, oidPBES2) {
return nil, errors.New("x509: only support PBES2")
}
encryptionScheme := keyInfo.EncryptionAlgorithm.Pbes2Params.EncryptionScheme
keyDerivationFunc := keyInfo.EncryptionAlgorithm.Pbes2Params.KeyDerivationFunc
if !reflect.DeepEqual(keyDerivationFunc.IdPBKDF2, oidPBKDF2) {
return nil, errors.New("x509: only support PBKDF2")
}
pkdf2Params := keyDerivationFunc.Pkdf2Params
if !reflect.DeepEqual(encryptionScheme.EncryAlgo, oidAES128CBC) &&
!reflect.DeepEqual(encryptionScheme.EncryAlgo, oidAES256CBC) {
return nil, errors.New("x509: unknow encryption algorithm")
}
iv := encryptionScheme.IV
salt := pkdf2Params.Salt
iter := pkdf2Params.IterationCount
encryptedKey := keyInfo.EncryptedData
var key []byte
switch {
case pkdf2Params.Prf.Algorithm.Equal(oidKEYMD5):
key = pbkdf(pwd, salt, iter, 32, md5.New)
break
case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA1):
key = pbkdf(pwd, salt, iter, 32, sha1.New)
break
case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA256):
key = pbkdf(pwd, salt, iter, 32, sha256.New)
break
case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA512):
key = pbkdf(pwd, salt, iter, 32, sha512.New)
break
default:
return nil, errors.New("x509: unknown hash algorithm")
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(encryptedKey, encryptedKey)
rKey, err := ParsePKCS8UnecryptedPrivateKey(encryptedKey)
if err != nil {
return nil, errors.New("pkcs8: incorrect password")
}
return rKey, nil
}
func ParsePKCS8PrivateKey(der, pwd []byte) (*PrivateKey, error) {
if pwd == nil {
return ParsePKCS8UnecryptedPrivateKey(der)
}
return ParsePKCS8EcryptedPrivateKey(der, pwd)
}
func MarshalSm2UnecryptedPrivateKey(key *PrivateKey) ([]byte, error) {
var r pkcs8
var priv sm2PrivateKey
var algo pkix.AlgorithmIdentifier
algo.Algorithm = oidSM2
algo.Parameters.Class = 0
algo.Parameters.Tag = 6
algo.Parameters.IsCompound = false
algo.Parameters.FullBytes = []byte{6, 8, 42, 129, 28, 207, 85, 1, 130, 45} // asn1.Marshal(asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301})
priv.Version = 1
priv.NamedCurveOID = oidNamedCurveP256SM2
priv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}
priv.PrivateKey = key.D.Bytes()
r.Version = 0
r.Algo = algo
r.PrivateKey, _ = asn1.Marshal(priv)
return asn1.Marshal(r)
}
func MarshalSm2EcryptedPrivateKey(PrivKey *PrivateKey, pwd []byte) ([]byte, error) {
der, err := MarshalSm2UnecryptedPrivateKey(PrivKey)
if err != nil {
return nil, err
}
iter := 2048
salt := make([]byte, 8)
iv := make([]byte, 16)
rand.Reader.Read(salt)
rand.Reader.Read(iv)
key := pbkdf(pwd, salt, iter, 32, sha1.New) // 默认是SHA1
padding := aes.BlockSize - len(der)%aes.BlockSize
if padding > 0 {
n := len(der)
der = append(der, make([]byte, padding)...)
for i := 0; i < padding; i++ {
der[n+i] = byte(padding)
}
}
encryptedKey := make([]byte, len(der))
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(encryptedKey, der)
var algorithmIdentifier pkix.AlgorithmIdentifier
algorithmIdentifier.Algorithm = oidKEYSHA1
algorithmIdentifier.Parameters.Tag = 5
algorithmIdentifier.Parameters.IsCompound = false
algorithmIdentifier.Parameters.FullBytes = []byte{5, 0}
keyDerivationFunc := Pbes2KDfs{
oidPBKDF2,
Pkdf2Params{
salt,
iter,
algorithmIdentifier,
},
}
encryptionScheme := Pbes2Encs{
oidAES256CBC,
iv,
}
pbes2Algorithms := Pbes2Algorithms{
oidPBES2,
Pbes2Params{
keyDerivationFunc,
encryptionScheme,
},
}
encryptedPkey := EncryptedPrivateKeyInfo{
pbes2Algorithms,
encryptedKey,
}
return asn1.Marshal(encryptedPkey)
}
func MarshalSm2PrivateKey(key *PrivateKey, pwd []byte) ([]byte, error) {
if pwd == nil {
return MarshalSm2UnecryptedPrivateKey(key)
}
return MarshalSm2EcryptedPrivateKey(key, pwd)
}
func ReadPrivateKeyFromMem(data []byte, pwd []byte) (*PrivateKey, error) {
var block *pem.Block
block, _ = pem.Decode(data)
if block == nil {
return nil, errors.New("failed to decode private key")
}
priv, err := ParsePKCS8PrivateKey(block.Bytes, pwd)
return priv, err
}
func ReadPrivateKeyFromPem(FileName string, pwd []byte) (*PrivateKey, error) {
data, err := ioutil.ReadFile(FileName)
if err != nil {
return nil, err
}
return ReadPrivateKeyFromMem(data, pwd)
}
func WritePrivateKeytoMem(key *PrivateKey, pwd []byte) ([]byte, error) {
var block *pem.Block
der, err := MarshalSm2PrivateKey(key, pwd)
if err != nil {
return nil, err
}
if pwd != nil {
block = &pem.Block{
Type: "ENCRYPTED PRIVATE KEY",
Bytes: der,
}
} else {
block = &pem.Block{
Type: "PRIVATE KEY",
Bytes: der,
}
}
return pem.EncodeToMemory(block), nil
}
func WritePrivateKeytoPem(FileName string, key *PrivateKey, pwd []byte) (bool, error) {
var block *pem.Block
der, err := MarshalSm2PrivateKey(key, pwd)
if err != nil {
return false, err
}
if pwd != nil {
block = &pem.Block{
Type: "ENCRYPTED PRIVATE KEY",
Bytes: der,
}
} else {
block = &pem.Block{
Type: "PRIVATE KEY",
Bytes: der,
}
}
file, err := os.Create(FileName)
if err != nil {
return false, err
}
defer file.Close()
err = pem.Encode(file, block)
if err != nil {
return false, err
}
return true, nil
}
func ReadPublicKeyFromMem(data []byte, _ []byte) (*PublicKey, error) {
block, _ := pem.Decode(data)
if block == nil || block.Type != "PUBLIC KEY" {
return nil, errors.New("failed to decode public key")
}
pub, err := ParseSm2PublicKey(block.Bytes)
return pub, err
}
func ReadPublicKeyFromPem(FileName string, pwd []byte) (*PublicKey, error) {
data, err := ioutil.ReadFile(FileName)
if err != nil {
return nil, err
}
return ReadPublicKeyFromMem(data, pwd)
}
func WritePublicKeytoMem(key *PublicKey, _ []byte) ([]byte, error) {
der, err := MarshalSm2PublicKey(key)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: der,
}
return pem.EncodeToMemory(block), nil
}
func WritePublicKeytoPem(FileName string, key *PublicKey, _ []byte) (bool, error) {
der, err := MarshalSm2PublicKey(key)
if err != nil {
return false, err
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: der,
}
file, err := os.Create(FileName)
defer file.Close()
if err != nil {
return false, err
}
err = pem.Encode(file, block)
if err != nil {
return false, err
}
return true, nil
}

222
vendor/github.com/tjfoc/gmsm/sm2/sm2.go generated vendored Normal file
View File

@@ -0,0 +1,222 @@
/*
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sm2
// reference to ecdsa
import (
"crypto"
"crypto/aes"
"crypto/cipher"
"crypto/elliptic"
"crypto/rand"
"crypto/sha512"
"encoding/asn1"
"errors"
"io"
"math/big"
)
type combinedMult interface {
CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int)
}
const (
aesIV = "IV for <SM2> CTR"
)
type PublicKey struct {
elliptic.Curve
X, Y *big.Int
}
type PrivateKey struct {
PublicKey
D *big.Int
}
type sm2Signature struct {
R, S *big.Int
}
// The SM2's private key contains the public key
func (priv *PrivateKey) Public() crypto.PublicKey {
return &priv.PublicKey
}
// sign format = 30 + len(z) + 02 + len(r) + r + 02 + len(s) + s, z being what follows its size, ie 02+len(r)+r+02+len(s)+s
func (priv *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
r, s, err := Sign(priv, msg)
if err != nil {
return nil, err
}
return asn1.Marshal(sm2Signature{r, s})
}
func (pub *PublicKey) Verify(msg []byte, sign []byte) bool {
var sm2Sign sm2Signature
_, err := asn1.Unmarshal(sign, &sm2Sign)
if err != nil {
return false
}
return Verify(pub, msg, sm2Sign.R, sm2Sign.S)
}
var one = new(big.Int).SetInt64(1)
func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
params := c.Params()
b := make([]byte, params.BitSize/8+8)
_, err = io.ReadFull(rand, b)
if err != nil {
return
}
k = new(big.Int).SetBytes(b)
n := new(big.Int).Sub(params.N, one)
k.Mod(k, n)
k.Add(k, one)
return
}
func GenerateKey() (*PrivateKey, error) {
c := P256Sm2()
k, err := randFieldElement(c, rand.Reader)
if err != nil {
return nil, err
}
priv := new(PrivateKey)
priv.PublicKey.Curve = c
priv.D = k
priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
return priv, nil
}
var errZeroParam = errors.New("zero parameter")
func Sign(priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
entropylen := (priv.Curve.Params().BitSize + 7) / 16
if entropylen > 32 {
entropylen = 32
}
entropy := make([]byte, entropylen)
_, err = io.ReadFull(rand.Reader, entropy)
if err != nil {
return
}
// Initialize an SHA-512 hash context; digest ...
md := sha512.New()
md.Write(priv.D.Bytes()) // the private key,
md.Write(entropy) // the entropy,
md.Write(hash) // and the input hash;
key := md.Sum(nil)[:32] // and compute ChopMD-256(SHA-512),
// which is an indifferentiable MAC.
// Create an AES-CTR instance to use as a CSPRNG.
block, err := aes.NewCipher(key)
if err != nil {
return nil, nil, err
}
// Create a CSPRNG that xors a stream of zeros with
// the output of the AES-CTR instance.
csprng := cipher.StreamReader{
R: zeroReader,
S: cipher.NewCTR(block, []byte(aesIV)),
}
// See [NSA] 3.4.1
c := priv.PublicKey.Curve
N := c.Params().N
if N.Sign() == 0 {
return nil, nil, errZeroParam
}
var k *big.Int
e := new(big.Int).SetBytes(hash)
for { // 调整算法细节以实现SM2
for {
k, err = randFieldElement(c, csprng)
if err != nil {
r = nil
return
}
r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
r.Add(r, e)
r.Mod(r, N)
if r.Sign() != 0 {
break
}
if t := new(big.Int).Add(r, k); t.Cmp(N) == 0 {
break
}
}
rD := new(big.Int).Mul(priv.D, r)
s = new(big.Int).Sub(k, rD)
d1 := new(big.Int).Add(priv.D, one)
d1Inv := new(big.Int).ModInverse(d1, N)
s.Mul(s, d1Inv)
s.Mod(s, N)
if s.Sign() != 0 {
break
}
}
return
}
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
c := pub.Curve
N := c.Params().N
if r.Sign() <= 0 || s.Sign() <= 0 {
return false
}
if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
return false
}
// 调整算法细节以实现SM2
t := new(big.Int).Add(r, s)
t.Mod(t, N)
if N.Sign() == 0 {
return false
}
var x *big.Int
if opt, ok := c.(combinedMult); ok {
x, _ = opt.CombinedMult(pub.X, pub.Y, s.Bytes(), t.Bytes())
} else {
x1, y1 := c.ScalarBaseMult(s.Bytes())
x2, y2 := c.ScalarMult(pub.X, pub.Y, t.Bytes())
x, _ = c.Add(x1, y1, x2, y2)
}
e := new(big.Int).SetBytes(hash)
x.Add(x, e)
x.Mod(x, N)
return x.Cmp(r) == 0
}
type zr struct {
io.Reader
}
func (z *zr) Read(dst []byte) (n int, err error) {
for i := range dst {
dst[i] = 0
}
return len(dst), nil
}
var zeroReader = &zr{}

184
vendor/github.com/tjfoc/gmsm/sm2/sm2_test.go generated vendored Normal file
View File

@@ -0,0 +1,184 @@
/*
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sm2
import (
"crypto/rand"
"crypto/x509/pkix"
"encoding/asn1"
"fmt"
"io/ioutil"
"log"
"math/big"
"net"
"os"
"testing"
"time"
)
func TestSm2(t *testing.T) {
priv, err := GenerateKey() // 生成密钥对
if err != nil {
log.Fatal(err)
}
ok, err := WritePrivateKeytoPem("priv.pem", priv, nil) // 生成密钥文件
if ok != true {
log.Fatal(err)
}
pubKey, _ := priv.Public().(*PublicKey)
ok, err = WritePublicKeytoPem("pub.pem", pubKey, nil) // 生成公钥文件
if ok != true {
log.Fatal(err)
}
msg := []byte("test")
err = ioutil.WriteFile("ifile", msg, os.FileMode(0644)) // 生成测试文件
if err != nil {
log.Fatal(err)
}
privKey, err := ReadPrivateKeyFromPem("priv.pem", nil) // 读取密钥
if err != nil {
log.Fatal(err)
}
pubKey, err = ReadPublicKeyFromPem("pub.pem", nil) // 读取公钥
if err != nil {
log.Fatal(err)
}
msg, _ = ioutil.ReadFile("ifile") // 从文件读取数据
sign, err := privKey.Sign(rand.Reader, msg, nil) // 签名
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile("ofile", sign, os.FileMode(0644))
if err != nil {
log.Fatal(err)
}
signdata, _ := ioutil.ReadFile("ofile")
ok = privKey.Verify(msg, signdata) // 密钥验证
if ok != true {
fmt.Printf("Verify error\n")
} else {
fmt.Printf("Verify ok\n")
}
ok = pubKey.Verify(msg, signdata) // 公钥验证
if ok != true {
fmt.Printf("Verify error\n")
} else {
fmt.Printf("Verify ok\n")
}
templateReq := CertificateRequest{
Subject: pkix.Name{
CommonName: "test.example.com",
Organization: []string{"Test"},
},
// SignatureAlgorithm: ECDSAWithSHA256,
SignatureAlgorithm: SM2WithSM3,
}
_, err = CreateCertificateRequestToPem("req.pem", &templateReq, privKey)
if err != nil {
log.Fatal(err)
}
req, err := ReadCertificateRequestFromPem("req.pem")
if err != nil {
log.Fatal(err)
}
err = req.CheckSignature()
if err != nil {
log.Fatal(err)
} else {
fmt.Printf("CheckSignature ok\n")
}
testExtKeyUsage := []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageServerAuth}
testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}}
extraExtensionData := []byte("extra extension")
commonName := "test.example.com"
template := Certificate{
// SerialNumber is negative to ensure that negative
// values are parsed. This is due to the prevalence of
// buggy code that produces certificates with negative
// serial numbers.
SerialNumber: big.NewInt(-1),
Subject: pkix.Name{
CommonName: commonName,
Organization: []string{"TEST"},
Country: []string{"China"},
ExtraNames: []pkix.AttributeTypeAndValue{
{
Type: []int{2, 5, 4, 42},
Value: "Gopher",
},
// This should override the Country, above.
{
Type: []int{2, 5, 4, 6},
Value: "NL",
},
},
},
NotBefore: time.Unix(1000, 0),
NotAfter: time.Unix(100000, 0),
// SignatureAlgorithm: ECDSAWithSHA256,
SignatureAlgorithm: SM2WithSM3,
SubjectKeyId: []byte{1, 2, 3, 4},
KeyUsage: KeyUsageCertSign,
ExtKeyUsage: testExtKeyUsage,
UnknownExtKeyUsage: testUnknownExtKeyUsage,
BasicConstraintsValid: true,
IsCA: true,
OCSPServer: []string{"http://ocsp.example.com"},
IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"},
DNSNames: []string{"test.example.com"},
EmailAddresses: []string{"gopher@golang.org"},
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}},
PermittedDNSDomains: []string{".example.com", "example.com"},
CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"},
ExtraExtensions: []pkix.Extension{
{
Id: []int{1, 2, 3, 4},
Value: extraExtensionData,
},
// This extension should override the SubjectKeyId, above.
{
Id: oidExtensionSubjectKeyId,
Critical: false,
Value: []byte{0x04, 0x04, 4, 3, 2, 1},
},
},
}
pubKey, _ = priv.Public().(*PublicKey)
ok, _ = CreateCertificateToPem("cert.pem", &template, &template, pubKey, privKey)
if ok != true {
fmt.Printf("failed to create cert file\n")
}
cert, err := ReadCertificateFromPem("cert.pem")
if err != nil {
fmt.Printf("failed to read cert file")
}
err = cert.CheckSignature(cert.SignatureAlgorithm, cert.RawTBSCertificate, cert.Signature)
if err != nil {
log.Fatal(err)
} else {
fmt.Printf("CheckSignature ok\n")
}
}

568
vendor/github.com/tjfoc/gmsm/sm2/verify.go generated vendored Normal file
View File

@@ -0,0 +1,568 @@
/*
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sm2
import (
"bytes"
"errors"
"fmt"
"net"
"runtime"
"strings"
"time"
"unicode/utf8"
)
type InvalidReason int
const (
// NotAuthorizedToSign results when a certificate is signed by another
// which isn't marked as a CA certificate.
NotAuthorizedToSign InvalidReason = iota
// Expired results when a certificate has expired, based on the time
// given in the VerifyOptions.
Expired
// CANotAuthorizedForThisName results when an intermediate or root
// certificate has a name constraint which doesn't include the name
// being checked.
CANotAuthorizedForThisName
// TooManyIntermediates results when a path length constraint is
// violated.
TooManyIntermediates
// IncompatibleUsage results when the certificate's key usage indicates
// that it may only be used for a different purpose.
IncompatibleUsage
// NameMismatch results when the subject name of a parent certificate
// does not match the issuer name in the child.
NameMismatch
)
// CertificateInvalidError results when an odd error occurs. Users of this
// library probably want to handle all these errors uniformly.
type CertificateInvalidError struct {
Cert *Certificate
Reason InvalidReason
}
func (e CertificateInvalidError) Error() string {
switch e.Reason {
case NotAuthorizedToSign:
return "x509: certificate is not authorized to sign other certificates"
case Expired:
return "x509: certificate has expired or is not yet valid"
case CANotAuthorizedForThisName:
return "x509: a root or intermediate certificate is not authorized to sign in this domain"
case TooManyIntermediates:
return "x509: too many intermediates for path length constraint"
case IncompatibleUsage:
return "x509: certificate specifies an incompatible key usage"
case NameMismatch:
return "x509: issuer name does not match subject from issuing certificate"
}
return "x509: unknown error"
}
// HostnameError results when the set of authorized names doesn't match the
// requested name.
type HostnameError struct {
Certificate *Certificate
Host string
}
func (h HostnameError) Error() string {
c := h.Certificate
var valid string
if ip := net.ParseIP(h.Host); ip != nil {
// Trying to validate an IP
if len(c.IPAddresses) == 0 {
return "x509: cannot validate certificate for " + h.Host + " because it doesn't contain any IP SANs"
}
for _, san := range c.IPAddresses {
if len(valid) > 0 {
valid += ", "
}
valid += san.String()
}
} else {
if len(c.DNSNames) > 0 {
valid = strings.Join(c.DNSNames, ", ")
} else {
valid = c.Subject.CommonName
}
}
if len(valid) == 0 {
return "x509: certificate is not valid for any names, but wanted to match " + h.Host
}
return "x509: certificate is valid for " + valid + ", not " + h.Host
}
// UnknownAuthorityError results when the certificate issuer is unknown
type UnknownAuthorityError struct {
Cert *Certificate
// hintErr contains an error that may be helpful in determining why an
// authority wasn't found.
hintErr error
// hintCert contains a possible authority certificate that was rejected
// because of the error in hintErr.
hintCert *Certificate
}
func (e UnknownAuthorityError) Error() string {
s := "x509: certificate signed by unknown authority"
if e.hintErr != nil {
certName := e.hintCert.Subject.CommonName
if len(certName) == 0 {
if len(e.hintCert.Subject.Organization) > 0 {
certName = e.hintCert.Subject.Organization[0]
} else {
certName = "serial:" + e.hintCert.SerialNumber.String()
}
}
s += fmt.Sprintf(" (possibly because of %q while trying to verify candidate authority certificate %q)", e.hintErr, certName)
}
return s
}
// SystemRootsError results when we fail to load the system root certificates.
type SystemRootsError struct {
Err error
}
func (se SystemRootsError) Error() string {
msg := "x509: failed to load system roots and no roots provided"
if se.Err != nil {
return msg + "; " + se.Err.Error()
}
return msg
}
// errNotParsed is returned when a certificate without ASN.1 contents is
// verified. Platform-specific verification needs the ASN.1 contents.
var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate")
// VerifyOptions contains parameters for Certificate.Verify. It's a structure
// because other PKIX verification APIs have ended up needing many options.
type VerifyOptions struct {
DNSName string
Intermediates *CertPool
Roots *CertPool // if nil, the system roots are used
CurrentTime time.Time // if zero, the current time is used
// KeyUsage specifies which Extended Key Usage values are acceptable.
// An empty list means ExtKeyUsageServerAuth. Key usage is considered a
// constraint down the chain which mirrors Windows CryptoAPI behavior,
// but not the spec. To accept any key usage, include ExtKeyUsageAny.
KeyUsages []ExtKeyUsage
}
const (
leafCertificate = iota
intermediateCertificate
rootCertificate
)
func matchNameConstraint(domain, constraint string) bool {
// The meaning of zero length constraints is not specified, but this
// code follows NSS and accepts them as valid for everything.
if len(constraint) == 0 {
return true
}
if len(domain) < len(constraint) {
return false
}
prefixLen := len(domain) - len(constraint)
if !strings.EqualFold(domain[prefixLen:], constraint) {
return false
}
if prefixLen == 0 {
return true
}
isSubdomain := domain[prefixLen-1] == '.'
constraintHasLeadingDot := constraint[0] == '.'
return isSubdomain != constraintHasLeadingDot
}
// isValid performs validity checks on the c.
func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error {
if len(currentChain) > 0 {
child := currentChain[len(currentChain)-1]
if !bytes.Equal(child.RawIssuer, c.RawSubject) {
return CertificateInvalidError{c, NameMismatch}
}
}
now := opts.CurrentTime
if now.IsZero() {
now = time.Now()
}
if now.Before(c.NotBefore) || now.After(c.NotAfter) {
return CertificateInvalidError{c, Expired}
}
if len(c.PermittedDNSDomains) > 0 {
ok := false
for _, constraint := range c.PermittedDNSDomains {
ok = matchNameConstraint(opts.DNSName, constraint)
if ok {
break
}
}
if !ok {
return CertificateInvalidError{c, CANotAuthorizedForThisName}
}
}
// KeyUsage status flags are ignored. From Engineering Security, Peter
// Gutmann: A European government CA marked its signing certificates as
// being valid for encryption only, but no-one noticed. Another
// European CA marked its signature keys as not being valid for
// signatures. A different CA marked its own trusted root certificate
// as being invalid for certificate signing. Another national CA
// distributed a certificate to be used to encrypt data for the
// countrys tax authority that was marked as only being usable for
// digital signatures but not for encryption. Yet another CA reversed
// the order of the bit flags in the keyUsage due to confusion over
// encoding endianness, essentially setting a random keyUsage in
// certificates that it issued. Another CA created a self-invalidating
// certificate by adding a certificate policy statement stipulating
// that the certificate had to be used strictly as specified in the
// keyUsage, and a keyUsage containing a flag indicating that the RSA
// encryption key could only be used for Diffie-Hellman key agreement.
if certType == intermediateCertificate && (!c.BasicConstraintsValid || !c.IsCA) {
return CertificateInvalidError{c, NotAuthorizedToSign}
}
if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
numIntermediates := len(currentChain) - 1
if numIntermediates > c.MaxPathLen {
return CertificateInvalidError{c, TooManyIntermediates}
}
}
return nil
}
// Verify attempts to verify c by building one or more chains from c to a
// certificate in opts.Roots, using certificates in opts.Intermediates if
// needed. If successful, it returns one or more chains where the first
// element of the chain is c and the last element is from opts.Roots.
//
// If opts.Roots is nil and system roots are unavailable the returned error
// will be of type SystemRootsError.
//
// WARNING: this doesn't do any revocation checking.
func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
// Platform-specific verification needs the ASN.1 contents so
// this makes the behavior consistent across platforms.
if len(c.Raw) == 0 {
return nil, errNotParsed
}
if opts.Intermediates != nil {
for _, intermediate := range opts.Intermediates.certs {
if len(intermediate.Raw) == 0 {
return nil, errNotParsed
}
}
}
// Use Windows's own verification and chain building.
if opts.Roots == nil && runtime.GOOS == "windows" {
return c.systemVerify(&opts)
}
if len(c.UnhandledCriticalExtensions) > 0 {
return nil, UnhandledCriticalExtension{}
}
if opts.Roots == nil {
opts.Roots = systemRootsPool()
if opts.Roots == nil {
return nil, SystemRootsError{systemRootsErr}
}
}
err = c.isValid(leafCertificate, nil, &opts)
if err != nil {
return
}
if len(opts.DNSName) > 0 {
err = c.VerifyHostname(opts.DNSName)
if err != nil {
return
}
}
var candidateChains [][]*Certificate
if opts.Roots.contains(c) {
candidateChains = append(candidateChains, []*Certificate{c})
} else {
if candidateChains, err = c.buildChains(make(map[int][][]*Certificate), []*Certificate{c}, &opts); err != nil {
return nil, err
}
}
keyUsages := opts.KeyUsages
if len(keyUsages) == 0 {
keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
}
// If any key usage is acceptable then we're done.
for _, usage := range keyUsages {
if usage == ExtKeyUsageAny {
chains = candidateChains
return
}
}
for _, candidate := range candidateChains {
if checkChainForKeyUsage(candidate, keyUsages) {
chains = append(chains, candidate)
}
}
if len(chains) == 0 {
err = CertificateInvalidError{c, IncompatibleUsage}
}
return
}
func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate {
n := make([]*Certificate, len(chain)+1)
copy(n, chain)
n[len(chain)] = cert
return n
}
func (c *Certificate) buildChains(cache map[int][][]*Certificate, currentChain []*Certificate, opts *VerifyOptions) (chains [][]*Certificate, err error) {
possibleRoots, failedRoot, rootErr := opts.Roots.findVerifiedParents(c)
nextRoot:
for _, rootNum := range possibleRoots {
root := opts.Roots.certs[rootNum]
for _, cert := range currentChain {
if cert.Equal(root) {
continue nextRoot
}
}
err = root.isValid(rootCertificate, currentChain, opts)
if err != nil {
continue
}
chains = append(chains, appendToFreshChain(currentChain, root))
}
possibleIntermediates, failedIntermediate, intermediateErr := opts.Intermediates.findVerifiedParents(c)
nextIntermediate:
for _, intermediateNum := range possibleIntermediates {
intermediate := opts.Intermediates.certs[intermediateNum]
for _, cert := range currentChain {
if cert.Equal(intermediate) {
continue nextIntermediate
}
}
err = intermediate.isValid(intermediateCertificate, currentChain, opts)
if err != nil {
continue
}
var childChains [][]*Certificate
childChains, ok := cache[intermediateNum]
if !ok {
childChains, err = intermediate.buildChains(cache, appendToFreshChain(currentChain, intermediate), opts)
cache[intermediateNum] = childChains
}
chains = append(chains, childChains...)
}
if len(chains) > 0 {
err = nil
}
if len(chains) == 0 && err == nil {
hintErr := rootErr
hintCert := failedRoot
if hintErr == nil {
hintErr = intermediateErr
hintCert = failedIntermediate
}
err = UnknownAuthorityError{c, hintErr, hintCert}
}
return
}
func matchHostnames(pattern, host string) bool {
host = strings.TrimSuffix(host, ".")
pattern = strings.TrimSuffix(pattern, ".")
if len(pattern) == 0 || len(host) == 0 {
return false
}
patternParts := strings.Split(pattern, ".")
hostParts := strings.Split(host, ".")
if len(patternParts) != len(hostParts) {
return false
}
for i, patternPart := range patternParts {
if i == 0 && patternPart == "*" {
continue
}
if patternPart != hostParts[i] {
return false
}
}
return true
}
// toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use
// an explicitly ASCII function to avoid any sharp corners resulting from
// performing Unicode operations on DNS labels.
func toLowerCaseASCII(in string) string {
// If the string is already lower-case then there's nothing to do.
isAlreadyLowerCase := true
for _, c := range in {
if c == utf8.RuneError {
// If we get a UTF-8 error then there might be
// upper-case ASCII bytes in the invalid sequence.
isAlreadyLowerCase = false
break
}
if 'A' <= c && c <= 'Z' {
isAlreadyLowerCase = false
break
}
}
if isAlreadyLowerCase {
return in
}
out := []byte(in)
for i, c := range out {
if 'A' <= c && c <= 'Z' {
out[i] += 'a' - 'A'
}
}
return string(out)
}
// VerifyHostname returns nil if c is a valid certificate for the named host.
// Otherwise it returns an error describing the mismatch.
func (c *Certificate) VerifyHostname(h string) error {
// IP addresses may be written in [ ].
candidateIP := h
if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' {
candidateIP = h[1 : len(h)-1]
}
if ip := net.ParseIP(candidateIP); ip != nil {
// We only match IP addresses against IP SANs.
// https://tools.ietf.org/html/rfc6125#appendix-B.2
for _, candidate := range c.IPAddresses {
if ip.Equal(candidate) {
return nil
}
}
return HostnameError{c, candidateIP}
}
lowered := toLowerCaseASCII(h)
if len(c.DNSNames) > 0 {
for _, match := range c.DNSNames {
if matchHostnames(toLowerCaseASCII(match), lowered) {
return nil
}
}
// If Subject Alt Name is given, we ignore the common name.
} else if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) {
return nil
}
return HostnameError{c, h}
}
func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool {
usages := make([]ExtKeyUsage, len(keyUsages))
copy(usages, keyUsages)
if len(chain) == 0 {
return false
}
usagesRemaining := len(usages)
// We walk down the list and cross out any usages that aren't supported
// by each certificate. If we cross out all the usages, then the chain
// is unacceptable.
NextCert:
for i := len(chain) - 1; i >= 0; i-- {
cert := chain[i]
if len(cert.ExtKeyUsage) == 0 && len(cert.UnknownExtKeyUsage) == 0 {
// The certificate doesn't have any extended key usage specified.
continue
}
for _, usage := range cert.ExtKeyUsage {
if usage == ExtKeyUsageAny {
// The certificate is explicitly good for any usage.
continue NextCert
}
}
const invalidUsage ExtKeyUsage = -1
NextRequestedUsage:
for i, requestedUsage := range usages {
if requestedUsage == invalidUsage {
continue
}
for _, usage := range cert.ExtKeyUsage {
if requestedUsage == usage {
continue NextRequestedUsage
} else if requestedUsage == ExtKeyUsageServerAuth &&
(usage == ExtKeyUsageNetscapeServerGatedCrypto ||
usage == ExtKeyUsageMicrosoftServerGatedCrypto) {
// In order to support COMODO
// certificate chains, we have to
// accept Netscape or Microsoft SGC
// usages as equal to ServerAuth.
continue NextRequestedUsage
}
}
usages[i] = invalidUsage
usagesRemaining--
if usagesRemaining == 0 {
return false
}
}
}
return true
}

2526
vendor/github.com/tjfoc/gmsm/sm2/x509.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
vendor/github.com/tjfoc/gmsm/sm3/ifile generated vendored Normal file
View File

@@ -0,0 +1 @@
test

207
vendor/github.com/tjfoc/gmsm/sm3/sm3.go generated vendored Normal file
View File

@@ -0,0 +1,207 @@
/*
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sm3
import (
"encoding/binary"
"hash"
)
type SM3 struct {
digest [8]uint32 // digest represents the partial evaluation of V
length uint64 // length of the message
unhandleMsg []byte // uint8 //
}
func (sm3 *SM3) ff0(x, y, z uint32) uint32 { return x ^ y ^ z }
func (sm3 *SM3) ff1(x, y, z uint32) uint32 { return (x & y) | (x & z) | (y & z) }
func (sm3 *SM3) gg0(x, y, z uint32) uint32 { return x ^ y ^ z }
func (sm3 *SM3) gg1(x, y, z uint32) uint32 { return (x & y) | (^x & z) }
func (sm3 *SM3) p0(x uint32) uint32 { return x ^ sm3.leftRotate(x, 9) ^ sm3.leftRotate(x, 17) }
func (sm3 *SM3) p1(x uint32) uint32 { return x ^ sm3.leftRotate(x, 15) ^ sm3.leftRotate(x, 23) }
func (sm3 *SM3) leftRotate(x uint32, i uint32) uint32 { return (x<<(i%32) | x>>(32-i%32)) }
func (sm3 *SM3) pad() []byte {
msg := sm3.unhandleMsg
msg = append(msg, 0x80) // Append '1'
blockSize := 64 // Append until the resulting message length (in bits) is congruent to 448 (mod 512)
for len(msg)%blockSize != 56 {
msg = append(msg, 0x00)
}
// append message length
msg = append(msg, uint8(sm3.length>>56&0xff))
msg = append(msg, uint8(sm3.length>>48&0xff))
msg = append(msg, uint8(sm3.length>>40&0xff))
msg = append(msg, uint8(sm3.length>>32&0xff))
msg = append(msg, uint8(sm3.length>>24&0xff))
msg = append(msg, uint8(sm3.length>>16&0xff))
msg = append(msg, uint8(sm3.length>>8&0xff))
msg = append(msg, uint8(sm3.length>>0&0xff))
if len(msg)%64 != 0 {
panic("------SM3 Pad: error msgLen =")
}
return msg
}
func (sm3 *SM3) update(msg []byte, nblocks int) {
var w [68]uint32
var w1 [64]uint32
a, b, c, d, e, f, g, h := sm3.digest[0], sm3.digest[1], sm3.digest[2], sm3.digest[3], sm3.digest[4], sm3.digest[5], sm3.digest[6], sm3.digest[7]
for len(msg) >= 64 {
for i := 0; i < 16; i++ {
w[i] = binary.BigEndian.Uint32(msg[4*i : 4*(i+1)])
}
for i := 16; i < 68; i++ {
w[i] = sm3.p1(w[i-16]^w[i-9]^sm3.leftRotate(w[i-3], 15)) ^ sm3.leftRotate(w[i-13], 7) ^ w[i-6]
}
for i := 0; i < 64; i++ {
w1[i] = w[i] ^ w[i+4]
}
A, B, C, D, E, F, G, H := a, b, c, d, e, f, g, h
for i := 0; i < 16; i++ {
SS1 := sm3.leftRotate(sm3.leftRotate(A, 12)+E+sm3.leftRotate(0x79cc4519, uint32(i)), 7)
SS2 := SS1 ^ sm3.leftRotate(A, 12)
TT1 := sm3.ff0(A, B, C) + D + SS2 + w1[i]
TT2 := sm3.gg0(E, F, G) + H + SS1 + w[i]
D = C
C = sm3.leftRotate(B, 9)
B = A
A = TT1
H = G
G = sm3.leftRotate(F, 19)
F = E
E = sm3.p0(TT2)
}
for i := 16; i < 64; i++ {
SS1 := sm3.leftRotate(sm3.leftRotate(A, 12)+E+sm3.leftRotate(0x7a879d8a, uint32(i)), 7)
SS2 := SS1 ^ sm3.leftRotate(A, 12)
TT1 := sm3.ff1(A, B, C) + D + SS2 + w1[i]
TT2 := sm3.gg1(E, F, G) + H + SS1 + w[i]
D = C
C = sm3.leftRotate(B, 9)
B = A
A = TT1
H = G
G = sm3.leftRotate(F, 19)
F = E
E = sm3.p0(TT2)
}
a ^= A
b ^= B
c ^= C
d ^= D
e ^= E
f ^= F
g ^= G
h ^= H
msg = msg[64:]
}
sm3.digest[0], sm3.digest[1], sm3.digest[2], sm3.digest[3], sm3.digest[4], sm3.digest[5], sm3.digest[6], sm3.digest[7] = a, b, c, d, e, f, g, h
}
func New() hash.Hash {
var sm3 SM3
sm3.Reset()
return &sm3
}
// BlockSize, required by the hash.Hash interface.
// BlockSize returns the hash's underlying block size.
// The Write method must be able to accept any amount
// of data, but it may operate more efficiently if all writes
// are a multiple of the block size.
func (sm3 *SM3) BlockSize() int { return 64 }
// Size, required by the hash.Hash interface.
// Size returns the number of bytes Sum will return.
func (sm3 *SM3) Size() int { return 32 }
// Reset clears the internal state by zeroing bytes in the state buffer.
// This can be skipped for a newly-created hash state; the default zero-allocated state is correct.
func (sm3 *SM3) Reset() {
// Reset digest
sm3.digest[0] = 0x7380166f
sm3.digest[1] = 0x4914b2b9
sm3.digest[2] = 0x172442d7
sm3.digest[3] = 0xda8a0600
sm3.digest[4] = 0xa96f30bc
sm3.digest[5] = 0x163138aa
sm3.digest[6] = 0xe38dee4d
sm3.digest[7] = 0xb0fb0e4e
sm3.length = 0 // Reset numberic states
sm3.unhandleMsg = []byte{}
}
// Write, required by the hash.Hash interface.
// Write (via the embedded io.Writer interface) adds more data to the running hash.
// It never returns an error.
func (sm3 *SM3) Write(p []byte) (int, error) {
toWrite := len(p)
sm3.length += uint64(len(p) * 8)
msg := append(sm3.unhandleMsg, p...)
nblocks := len(msg) / sm3.BlockSize()
sm3.update(msg, nblocks)
// Update unhandleMsg
sm3.unhandleMsg = msg[nblocks*sm3.BlockSize():]
return toWrite, nil
}
// Sum, required by the hash.Hash interface.
// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
func (sm3 *SM3) Sum(in []byte) []byte {
sm3.Write(in)
msg := sm3.pad()
// Finialize
sm3.update(msg, len(msg)/sm3.BlockSize())
// save hash to in
needed := sm3.Size()
if cap(in)-len(in) < needed {
newIn := make([]byte, len(in), len(in)+needed)
copy(newIn, in)
in = newIn
}
out := in[len(in) : len(in)+needed]
for i := 0; i < 8; i++ {
binary.BigEndian.PutUint32(out[i*4:], sm3.digest[i])
}
return out
}
func Sm3Sum(data []byte) []byte {
var sm3 SM3
sm3.Reset()
sm3.Write(data)
return sm3.Sum(nil)
}

63
vendor/github.com/tjfoc/gmsm/sm3/sm3_test.go generated vendored Normal file
View File

@@ -0,0 +1,63 @@
/*
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sm3
import (
"fmt"
"io/ioutil"
"log"
"os"
"testing"
)
func byteToString(b []byte) string {
ret := ""
for i := 0; i < len(b); i++ {
ret += fmt.Sprintf("%02x", b[i])
}
return ret
}
func TestSm3(t *testing.T) {
msg := []byte("test")
err := ioutil.WriteFile("ifile", msg, os.FileMode(0644)) // 生成测试文件
if err != nil {
log.Fatal(err)
}
msg, err = ioutil.ReadFile("ifile")
if err != nil {
log.Fatal(err)
}
hw := New()
hw.Write(msg)
hash := hw.Sum(nil)
fmt.Println(hash)
fmt.Printf("%s\n", byteToString(hash))
hash1 := Sm3Sum(msg)
fmt.Println(hash1)
fmt.Printf("%s\n", byteToString(hash1))
}
func BenchmarkSm3(t *testing.B) {
t.ReportAllocs()
msg := []byte("test")
hw := New()
for i := 0; i < t.N; i++ {
hw.Sum(nil)
Sm3Sum(msg)
}
}

67
vendor/github.com/tjfoc/gmsm/sm4/sm4_test.go generated vendored Normal file
View File

@@ -0,0 +1,67 @@
/*
Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sm4
import (
"fmt"
"log"
"testing"
)
func TestSM4(t *testing.T) {
key := []byte("1234567890abcdef")
fmt.Printf("key = %v\n", key)
data := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}
WriteKeyToPem("key.pem", key, nil)
key, err := ReadKeyFromPem("key.pem", nil)
fmt.Printf("key = %v\n", key)
if err != nil {
log.Fatal(err)
}
fmt.Printf("data = %x\n", data)
c, err := NewCipher(key)
if err != nil {
log.Fatal(err)
}
d0 := make([]byte, 16)
c.Encrypt(d0, data)
fmt.Printf("d0 = %x\n", d0)
d1 := make([]byte, 16)
c.Decrypt(d1, d0)
fmt.Printf("d1 = %x\n", d1)
}
func BenchmarkSM4(t *testing.B) {
t.ReportAllocs()
key := []byte("1234567890abcdef")
data := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}
WriteKeyToPem("key.pem", key, nil)
key, err := ReadKeyFromPem("key.pem", nil)
if err != nil {
log.Fatal(err)
}
c, err := NewCipher(key)
if err != nil {
log.Fatal(err)
}
for i := 0; i < t.N; i++ {
d0 := make([]byte, 16)
c.Encrypt(d0, data)
d1 := make([]byte, 16)
c.Decrypt(d1, d0)
}
}