зеркало из https://github.com/github/certstore.git
p12 import for darwin
This commit is contained in:
Родитель
1e2be670b3
Коммит
30bf0d4124
|
@ -1 +1 @@
|
|||
bin
|
||||
test_data
|
||||
|
|
9
Makefile
9
Makefile
|
@ -1,9 +0,0 @@
|
|||
default: all
|
||||
|
||||
all: bin/certstore
|
||||
|
||||
bin:
|
||||
mkdir -p bin
|
||||
|
||||
bin/certstore: certstore.go certstore_darwin.go main.go bin
|
||||
GOOS=darwin go build -o bin/certstore .
|
9
TODO
9
TODO
|
@ -1,9 +0,0 @@
|
|||
* [x] Windows CNG — RSA PKCS1 Signer
|
||||
* [ ] Windows CNG — RSA PSS Signer
|
||||
* [x] Windows CNG — ECDSA Signer
|
||||
* [x] Windows CryptoAPI — RSA PKCS1 Signer
|
||||
* [ ] Windows CryptoAPI — RSA PSS Signer
|
||||
* [x] Windows CryptoAPI — ECDSA Signer
|
||||
* [ ] Darwin — RSA PKCS1 Signer
|
||||
* [ ] Darwin — RSA PSS Signer
|
||||
* [ ] Darwin — ECDSA Signer
|
|
@ -45,7 +45,10 @@ func (s macStore) Identities() ([]Identity, error) {
|
|||
}
|
||||
defer C.CFRelease(C.CFTypeRef(absResult))
|
||||
|
||||
// don't need to release aryResult since the abstract result is released above.
|
||||
aryResult := C.CFArrayRef(absResult)
|
||||
|
||||
// identRefs aren't owned by us initially. newMacIdentity retains them.
|
||||
n := C.CFArrayGetCount(aryResult)
|
||||
identRefs := make([]C.CFTypeRef, n)
|
||||
C.CFArrayGetValues(aryResult, C.CFRange{0, n}, (*unsafe.Pointer)(&identRefs[0]))
|
||||
|
@ -60,7 +63,30 @@ func (s macStore) Identities() ([]Identity, error) {
|
|||
|
||||
// Import implements the Store interface.
|
||||
func (s macStore) Import(data []byte, password string) error {
|
||||
return errors.New("not implemente4d")
|
||||
cdata, err := bytesToCFData(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer C.CFRelease(C.CFTypeRef(cdata))
|
||||
|
||||
cpass := stringToCFString(password)
|
||||
defer C.CFRelease(C.CFTypeRef(cpass))
|
||||
|
||||
cops := mapToCFDictionary(map[C.CFTypeRef]C.CFTypeRef{
|
||||
C.CFTypeRef(C.kSecImportExportPassphrase): C.CFTypeRef(cpass),
|
||||
})
|
||||
if cops == nil {
|
||||
return errors.New("error creating CFDictionary")
|
||||
}
|
||||
defer C.CFRelease(C.CFTypeRef(cops))
|
||||
|
||||
var cret C.CFArrayRef
|
||||
if err := osStatusError(C.SecPKCS12Import(cdata, cops, &cret)); err != nil {
|
||||
return err
|
||||
}
|
||||
defer C.CFRelease(C.CFTypeRef(cret))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close implements the Store interface.
|
||||
|
@ -180,6 +206,7 @@ func (i *macIdentity) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer C.CFRelease(C.CFTypeRef(cdigest))
|
||||
|
||||
algo, err := i.getAlgo(hash)
|
||||
if err != nil {
|
||||
|
@ -191,6 +218,8 @@ func (i *macIdentity) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts
|
|||
csig := C.SecKeyCreateSignature(kref, algo, cdigest, &cerr)
|
||||
|
||||
if err := cfErrorError(cerr); err != nil {
|
||||
defer C.CFRelease(C.CFTypeRef(cerr))
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -224,7 +253,7 @@ func (i *macIdentity) getAlgo(hash crypto.Hash) (algo C.SecKeyAlgorithm, err err
|
|||
case crypto.SHA512:
|
||||
algo = C.kSecKeyAlgorithmECDSASignatureDigestX962SHA512
|
||||
default:
|
||||
err = errors.New("unsupported hash algorithm")
|
||||
err = ErrUnsupportedHash
|
||||
}
|
||||
case *rsa.PublicKey:
|
||||
switch hash {
|
||||
|
@ -237,7 +266,7 @@ func (i *macIdentity) getAlgo(hash crypto.Hash) (algo C.SecKeyAlgorithm, err err
|
|||
case crypto.SHA512:
|
||||
algo = C.kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512
|
||||
default:
|
||||
err = errors.New("unsupported hash algorithm")
|
||||
err = ErrUnsupportedHash
|
||||
}
|
||||
default:
|
||||
err = errors.New("unsupported key type")
|
||||
|
|
|
@ -333,8 +333,6 @@ func (wpk *winPrivateKey) cngSignHash(hash crypto.Hash, digest []byte) ([]byte,
|
|||
padPtr = unsafe.Pointer(&padInfo)
|
||||
|
||||
switch hash {
|
||||
case crypto.MD5:
|
||||
padInfo.pszAlgId = BCRYPT_MD5_ALGORITHM
|
||||
case crypto.SHA1:
|
||||
padInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM
|
||||
case crypto.SHA256:
|
||||
|
|
119
main.go
119
main.go
|
@ -1,119 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("foo")
|
||||
// create()
|
||||
check()
|
||||
delete()
|
||||
}
|
||||
|
||||
func check() {
|
||||
store, err := Open()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
defer store.Close()
|
||||
|
||||
idents, err := store.Identities()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
hash := crypto.SHA256
|
||||
digest := sha256.Sum256([]byte("hi"))
|
||||
|
||||
for _, ident := range idents {
|
||||
defer ident.Close()
|
||||
|
||||
if signer, err := ident.Signer(); err != nil {
|
||||
fmt.Println(err)
|
||||
continue
|
||||
} else {
|
||||
if _, err := signer.Sign(rand.Reader, digest[:], hash); err != nil {
|
||||
fmt.Println(err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("Checked")
|
||||
}
|
||||
|
||||
func create() {
|
||||
f, err := os.Open("./test_data/rsa.pfx")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
if _, err := io.Copy(buf, f); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
store, err := Open()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
defer store.Close()
|
||||
|
||||
if err := store.Import(buf.Bytes(), "asdf"); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Created")
|
||||
}
|
||||
|
||||
func delete() {
|
||||
store, err := Open()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
defer store.Close()
|
||||
|
||||
idents, err := store.Identities()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, ident := range idents {
|
||||
defer ident.Close()
|
||||
|
||||
crt, err := ident.Certificate()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if crt.Subject.CommonName != "certstore-test" {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := ident.Delete(); err != nil {
|
||||
fmt.Println(errors.Wrap(err, "failed to destroy identity"))
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Println("Deleted")
|
||||
}
|
||||
}
|
|
@ -1,5 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
mkdir -p test_data
|
||||
cd test_data
|
||||
|
||||
# generate RSA cert/key/pfx
|
||||
openssl req -new -days 365 -nodes -x509 -newkey rsa:2048 -sha256 -subj "/CN=certstore-test" -keyout rsa.key -out rsa.crt
|
||||
openssl pkcs12 -export -out rsa.pfx -inkey rsa.key -in rsa.crt -passout pass:asdf
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
if [ ! -d test_data ]; then
|
||||
script/setup
|
||||
fi
|
||||
|
||||
go test
|
|
@ -1,9 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBITCByAIJAM3H1SutDsfYMAoGCCqGSM49BAMCMBkxFzAVBgNVBAMMDmNlcnRz
|
||||
dG9yZS10ZXN0MB4XDTE3MTExNDE3MjIyNVoXDTE4MTExNDE3MjIyNVowGTEXMBUG
|
||||
A1UEAwwOY2VydHN0b3JlLXRlc3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQn
|
||||
Lf1KU4xHlkoJjX3s22eub62MgWgDbNXDK4Wgim8zFMaeXm6zT72xivzCg6yXff+y
|
||||
7uoyRog+7/JEBvR7qsSsMAoGCCqGSM49BAMCA0gAMEUCIA2Z64Ymic8UdGmmr+yp
|
||||
VW0N48RBPWKjFbX929J5GmG+AiEAssFUSCZklw4nHO6jRIMHz6+RSELZ3slV3zqF
|
||||
3CQf/Bs=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,5 +0,0 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgnRYlR9a+lUsQrU1G
|
||||
qidQMfTz/qw0nwDjtdisXvvEhS2hRANCAAQnLf1KU4xHlkoJjX3s22eub62MgWgD
|
||||
bNXDK4Wgim8zFMaeXm6zT72xivzCg6yXff+y7uoyRog+7/JEBvR7qsSs
|
||||
-----END PRIVATE KEY-----
|
Двоичные данные
test_data/ec.pfx
Двоичные данные
test_data/ec.pfx
Двоичный файл не отображается.
|
@ -1,17 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICrjCCAZYCCQDu0Khex89pejANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDDA5j
|
||||
ZXJ0c3RvcmUtdGVzdDAeFw0xNzExMTQxNzIyMjVaFw0xODExMTQxNzIyMjVaMBkx
|
||||
FzAVBgNVBAMMDmNlcnRzdG9yZS10ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||
MIIBCgKCAQEAxp8qaCRXz7zWtFQsiIaKn8pP7PqUlXUYIlpqtcQOSHCZ8DPRLbPj
|
||||
9yf4qO8TBsBmO5ZZjv+9T0IpsqCxSMNRwalUeEUjRNwOn2UALgfmcs13p5MK1gJY
|
||||
/4Rv6+i4901sCb6Akv/gvHAfkrKYV7hWbiA8ZE1VqxN6MLTYoTpQU1H/YDNAAUVY
|
||||
C4Wo2/2SF8Wt+4rBhaUMmB3hjXdQeeunh7fuS11cixN1V0hiUinTnQqQVcaxEwmS
|
||||
7RibMy2Cbmp4gFBl0IWfvOEcwUbFQAW/eBKeSh1qPzETgmD7lYIjheuDVmWOHZdx
|
||||
bcOa0ab8psE85oUzVdWajVFeYkf87G3QwwIDAQABMA0GCSqGSIb3DQEBCwUAA4IB
|
||||
AQCX6Y7W/ABxxxSIFuAXRkluj+kup0eGgnBYqnsfUAgIx2Z65vP9zzo0x06q9X7J
|
||||
p4UVzJOz9DbfmU7pHi1k+Nln+IVT4+kZZtg0OWYOelrUR1Ag8V2XJVKBPEWGN0j9
|
||||
b0CP1SDwJKQcQw2QHxoYJvR8DnTgo07nepoNwidGt2Mlc8IJKVbJK6AGKkNh/lym
|
||||
jNMGyw56wrOtMLEk3sQfVpR2R3h8XYlmIZaSQ3eY+cDSmsPM91ls7STiFsBW0nco
|
||||
pENzLVsKu5N3w0Z4K01Ojivkj5uWmyu5UtPHo26NBOUrv3/29yCxusUdxreH/D2P
|
||||
Y1KTvNKNjg+6GkWHCmNhimjT
|
||||
-----END CERTIFICATE-----
|
|
@ -1,28 +0,0 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDGnypoJFfPvNa0
|
||||
VCyIhoqfyk/s+pSVdRgiWmq1xA5IcJnwM9Ets+P3J/io7xMGwGY7llmO/71PQimy
|
||||
oLFIw1HBqVR4RSNE3A6fZQAuB+ZyzXenkwrWAlj/hG/r6Lj3TWwJvoCS/+C8cB+S
|
||||
sphXuFZuIDxkTVWrE3owtNihOlBTUf9gM0ABRVgLhajb/ZIXxa37isGFpQyYHeGN
|
||||
d1B566eHt+5LXVyLE3VXSGJSKdOdCpBVxrETCZLtGJszLYJuaniAUGXQhZ+84RzB
|
||||
RsVABb94Ep5KHWo/MROCYPuVgiOF64NWZY4dl3Ftw5rRpvymwTzmhTNV1ZqNUV5i
|
||||
R/zsbdDDAgMBAAECggEAF13WQVY1Nm1C3QgiDRW27UGB0aFRJZwW8MOuVh/whjkp
|
||||
Awc1jqjhIsyDBmzJ0juES3JOqvIPNWnVOfyJnsPLtHrVQyjvE0TIO5xIPyISzGK7
|
||||
tu0nkzHHgpf0Cs7gI8fp8+ODgMe1irWuITX9kiRPlrkYIbyvXWb3Mw+zhJQ1qvd/
|
||||
g0MRnMLSSOjwPHmtcE+fVtZXhl3ucDzEallpJSEcyni68Y9cOq2vPCZUvNA2PNL9
|
||||
JHuv++63z0ICSr6OAZKeY5cr9kgT2NziIiNGqkI1XxK8nKmNpIxezquMOM55vp0Y
|
||||
6/0uGmHKNoCaw7oUmU1fyphpOLa+Pv9nWPlb8X28EQKBgQDhj4JGn1UEUNf3zb5C
|
||||
/sWBx9RIzSYnU+bdnUU858xZ3oaTh+vGxPk5iRIdxUA274pE8P3x4x4rF+ZKADkO
|
||||
Kk0z5X0b8m7oYF9Jts+WjlGB05ZrIHeYVMN/eZDh3ZGV/5leFXNSTgL+qg/HCfuW
|
||||
sRy+BjNQZW8G9TGtnAVmKk5AtQKBgQDhbP6kQQ2C9CWEyA7Eo46xu1O2QbYNovAj
|
||||
HNO6gC8LZngqAsk/6HAZ4H0HSPJGx1v4iPLVYTyhV6BedJqDiRc56AFS2cVc8yk0
|
||||
Oipjkd2w8wqWZSSl0WReecKGFVn9QH+3YUh+XY/psK7N/dRtWesd2zMlYBlQIhA0
|
||||
x5CWQ+TOlwKBgHzfcCYc63o6L3Y25xA776gLsxCi0m6PWo5yFPTE9zMBqMtgQj2G
|
||||
qtsZcXgdzZEcSBYmvM//BqKg1pM9UFjxPlBuyjaAnrnzMI2ksYQOQj13oByqmssw
|
||||
khKugHEqswCxwnx9r5xvJ+VIzPdKJYilgN4KnLnzjeXyNJCCgdKvtSbJAoGAWs+O
|
||||
sVqnd8akyp3RHTQKStz89yH3lfy6olp9jNcQnJYV+E6RBha7+iCuHV4sg4jSKwf4
|
||||
Uy9Nvm1PZF2y1SRH4ALvbZHe6Pfn9GsuIlhjp2HxNO7f2ZDFzy1byKoXS2dNS/F7
|
||||
w7QrQmfzs3X6umaLycZBD2BsMhTW1HxEadRF+1cCgYAI1yolkEV5sKAIozhdA0jJ
|
||||
ouTvPFGRa16PMIV25zVq9RhEKbAxO+llwUASiLaSCSm/xGOvxJ0Szrs2uFAicVRX
|
||||
x0V7aAM6Kg7gCLra3ieMTYaXmgA4RqbBSO6Uhxy+ZyOWFhJwmc+bznpf1f1TszIK
|
||||
jrdJHEqNCVMM1J2sgNqRIA==
|
||||
-----END PRIVATE KEY-----
|
Двоичные данные
test_data/rsa.pfx
Двоичные данные
test_data/rsa.pfx
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче