designed primarily for Rutoken authentication Rutoken Plugin Doc
verifies encapContentInfo signature with messageDigest verifies SigningTime in the range notBefore - notAfter verifies SignedAttributes that signature is valid verifies attached certificates that it has valid ca signature
- GOST R 34.11-94 hash function (RFC 5831)
- GOST R 34.11-2012 Стрибог (Streebog) hash function (RFC 6986)
- GOST R 34.10-2001 (RFC 5832) public key signature function
- GOST R 34.10-2012 256 and 512 bit (RFC 7091) public key signature function
- as well as RSA with SHA256/SHA512
- DSA , ECDSA, RSA PSS not supported
- Validate Content Data, Signing time, Signers certificates against provided CA
implement only Signed-data Content Type. ignore signature algorithm parameters (use only GOST A-ParamSets)
- https://tc26.ru/
- https://datatracker.ietf.org/doc/rfc4491/?include_text=1
- https://tools.ietf.org/html/rfc5652#page-13
- https://www.cryptopro.ru/sites/default/files/products/tls/tk26iok.pdf
- https://www.streebog.net/en/
https://cpdn.cryptopro.ru/content/csp40/html/group___pro_c_s_p_ex_CP_PARAM_OIDS.html http://cpdn.cryptopro.ru/content/csp36/html/group___pro_c_s_p_ex_DP8.html
- Go 1.11 or higher.
- gogost https://github.com/ddulesov/gogost
Install:
go get -u github.com/ddulesov/pkcs7
Import:
import "github.com/ddulesov/pkcs7"
package main
import (
"log"
"os"
"github.com/ddulesov/pkcs7"
"encoding/pem"
"errors"
"io/ioutil"
"time"
)
func check(err error) {
if err != nil {
log.Fatal(err)
}
}
func loadCertificatesFromFile(filename string) ([]*pkcs7.Certificate, error) {
var ber *pem.Block
buff, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
calist := make([]*pkcs7.Certificate, 0)
for len(buff) > 0 {
ber, buff = pem.Decode(buff)
if ber == nil || ber.Type != "CERTIFICATE" {
return nil, errors.New("invalid certificate file format")
}
ca, err := pkcs7.ParseCertificate(ber.Bytes)
if err != nil {
return nil, err
}
calist = append(calist, ca)
}
return calist, nil
}
func main() {
if len(os.Args) < 2 {
log.Printf("%s <cms.file> <ca.cert>", os.Args[0])
return
}
file := os.Args[1]
buff, err := ioutil.ReadFile(file)
check(err)
ber, _ := pem.Decode(buff)
if ber == nil || ber.Type != "CMS" {
log.Fatal("not PEM encoded")
}
cms, err := pkcs7.ParseCMS(ber.Bytes)
check(err)
file = os.Args[2]
calist, err := loadCertificatesFromFile(file)
check(err)
err = cms.VerifyCertificates(calist)
check(err)
time1 := time.Date(2019, time.August, 23, 0, 0, 0, 0, time.UTC)
time2 := time.Date(2019, time.August, 25, 0, 0, 0, 0, time.UTC)
data := []byte{116, 101, 115, 116, 32, 115, 116, 114, 105, 110, 103, 10}
err = cms.Verify(data, time1, time2)
check(err)
log.Printf("%s valid!", os.Args[1])
}
PEM encoded certificates, cms, csr online viewer http://gostcrypto.com/tool-asn1.html