// Checksum returns the checksum of some data, using a specified algorithm. // It only returns an error when an invalid algorithm is used. The valid ones // are MD5, SHA1, SHA224, SHA256, SHA384, SHA512, SHA3224, SHA3256, SHA3384, // and SHA3512. func Checksum(algorithm string, data []byte) (checksum string, err error) { // default var hasher hash.Hash switch strings.ToUpper(algorithm) { case "MD5": hasher = md5.New() case "SHA1": hasher = sha1.New() case "SHA224": hasher = sha256.New224() case "SHA256": hasher = sha256.New() case "SHA384": hasher = sha512.New384() case "SHA512": hasher = sha512.New() case "SHA3224": hasher = sha3.New224() case "SHA3256": hasher = sha3.New256() case "SHA3384": hasher = sha3.New384() case "SHA3512": hasher = sha3.New512() default: msg := "Invalid algorithm parameter passed go Checksum: %s" return checksum, fmt.Errorf(msg, algorithm) } hasher.Write(data) str := hex.EncodeToString(hasher.Sum(nil)) return str, nil }
// CreateCertificate requests the creation of a new enrollment certificate by the TLSCA. // func (tlscap *TLSCAP) CreateCertificate(ctx context.Context, req *pb.TLSCertCreateReq) (*pb.TLSCertCreateResp, error) { Trace.Println("grpc TLSCAP:CreateCertificate") id := req.Id.Id sig := req.Sig req.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) raw := req.Pub.Key if req.Pub.Type != pb.CryptoType_ECDSA { return nil, errors.New("unsupported key type") } pub, err := x509.ParsePKIXPublicKey(req.Pub.Key) if err != nil { return nil, err } hash := sha3.New384() raw, _ = proto.Marshal(req) hash.Write(raw) if ecdsa.Verify(pub.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } if raw, err = tlscap.tlsca.createCertificate(id, pub.(*ecdsa.PublicKey), x509.KeyUsageDigitalSignature, req.Ts.Seconds, nil); err != nil { Error.Println(err) return nil, err } return &pb.TLSCertCreateResp{&pb.Cert{raw}, &pb.Cert{tlscap.tlsca.raw}}, nil }
// ReadCertificate reads a transaction certificate from the TCA. // func (tcap *TCAP) ReadCertificate(ctx context.Context, req *pb.TCertReadReq) (*pb.Cert, error) { Trace.Println("grpc TCAP:ReadCertificate") id := req.Id.Id raw, err := tcap.tca.eca.readCertificate(id, x509.KeyUsageDigitalSignature) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } sig := req.Sig req.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := sha3.New384() raw, _ = proto.Marshal(req) hash.Write(raw) if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } raw, err = tcap.tca.readCertificate1(id, req.Ts.Seconds) if err != nil { return nil, err } return &pb.Cert{raw}, nil }
// Derive the shared secret according to acme spec 5.6 func performECDH(priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey, outLen int, label string) []byte { // Derive Z from the private and public keys according to SEC 1 Ver. 2.0 - 3.3.1 Z, _ := priv.PublicKey.ScalarMult(pub.X, pub.Y, priv.D.Bytes()) if len(Z.Bytes())+len(label)+4 > 384 { return nil } if outLen < 384*(2^32-1) { return nil } // Derive the shared secret key using the ANS X9.63 KDF - SEC 1 Ver. 2.0 - 3.6.1 hasher := sha3.New384() buffer := make([]byte, outLen) bufferLen := 0 for i := 0; i < outLen/384; i++ { hasher.Reset() // Ki = Hash(Z || Counter || [SharedInfo]) hasher.Write(Z.Bytes()) binary.Write(hasher, binary.BigEndian, i) hasher.Write([]byte(label)) hash := hasher.Sum(nil) copied := copy(buffer[bufferLen:], hash) bufferLen += copied } return buffer }
func TestHashOpts(t *testing.T) { msg := []byte("abcd") // SHA256 digest1, err := currentBCCSP.Hash(msg, &bccsp.SHA256Opts{}) if err != nil { t.Fatalf("Failed computing SHA256 [%s]", err) } h := sha256.New() h.Write(msg) digest2 := h.Sum(nil) if !bytes.Equal(digest1, digest2) { t.Fatalf("Different SHA256 computed. [%x][%x]", digest1, digest2) } // SHA384 digest1, err = currentBCCSP.Hash(msg, &bccsp.SHA384Opts{}) if err != nil { t.Fatalf("Failed computing SHA384 [%s]", err) } h = sha512.New384() h.Write(msg) digest2 = h.Sum(nil) if !bytes.Equal(digest1, digest2) { t.Fatalf("Different SHA384 computed. [%x][%x]", digest1, digest2) } // SHA3_256O digest1, err = currentBCCSP.Hash(msg, &bccsp.SHA3_256Opts{}) if err != nil { t.Fatalf("Failed computing SHA3_256 [%s]", err) } h = sha3.New256() h.Write(msg) digest2 = h.Sum(nil) if !bytes.Equal(digest1, digest2) { t.Fatalf("Different SHA3_256 computed. [%x][%x]", digest1, digest2) } // SHA3_384 digest1, err = currentBCCSP.Hash(msg, &bccsp.SHA3_384Opts{}) if err != nil { t.Fatalf("Failed computing SHA3_384 [%s]", err) } h = sha3.New384() h.Write(msg) digest2 = h.Sum(nil) if !bytes.Equal(digest1, digest2) { t.Fatalf("Different SHA3_384 computed. [%x][%x]", digest1, digest2) } }
func (ca *CA) newCertificate(id string, pub *ecdsa.PublicKey, timestamp int64, opt ...pkix.Extension) ([]byte, error) { Trace.Println("creating certificate for " + id) notBefore := time.Now() notAfter := notBefore.Add(time.Hour * 24 * 90) isCA := ca.cert == nil tmpl := x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{ CommonName: "OBC", Organization: []string{"IBM"}, Country: []string{"US"}, }, NotBefore: notBefore, NotAfter: notAfter, SubjectKeyId: []byte{1, 2, 3, 4}, SignatureAlgorithm: x509.ECDSAWithSHA384, KeyUsage: x509.KeyUsageDigitalSignature, BasicConstraintsValid: true, IsCA: isCA, } if len(opt) > 0 { tmpl.Extensions = opt tmpl.ExtraExtensions = opt } parent := ca.cert if isCA { parent = &tmpl } raw, err := x509.CreateCertificate( rand.Reader, &tmpl, parent, pub, ca.priv, ) if isCA && err != nil { Panic.Panicln(err) } hash := sha3.New384() hash.Write(raw) if _, err = ca.db.Exec("INSERT INTO Certificates (id, timestamp, cert, hash) VALUES (?, ?, ?, ?)", id, timestamp, raw, hash.Sum(nil)); err != nil { if isCA { Panic.Panicln(err) } else { Error.Println(err) } } return raw, err }
// ReadCertificateSet reads a transaction certificate set from the TCA. Not yet implemented. // func (tcap *TCAP) ReadCertificateSet(ctx context.Context, in *pb.TCertReadSetReq) (*pb.CertSet, error) { Trace.Println("grpc TCAP:ReadCertificateSet") req := in.Req.Id id := in.Id.Id if req != id && tcap.tca.eca.readRole(req)&int(pb.Role_AUDITOR) == 0 { return nil, errors.New("access denied") } raw, err := tcap.tca.eca.readCertificate(req, x509.KeyUsageDigitalSignature) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } sig := in.Sig in.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := sha3.New384() raw, _ = proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } rows, err := tcap.tca.readCertificates(id, in.Ts.Seconds) if err != nil { return nil, err } defer rows.Close() var certs [][]byte var kdfKey []byte for rows.Next() { var raw []byte if err = rows.Scan(&raw, &kdfKey); err != nil { return nil, err } certs = append(certs, raw) } if err = rows.Err(); err != nil { return nil, err } return &pb.CertSet{in.Ts, in.Id, kdfKey, certs}, nil }
func newOpenPGPPubKey(intPubKey *packet.PublicKey) *openpgpPubKey { h := sha3.New384() h.Write(v1Header) err := intPubKey.Serialize(h) if err != nil { panic("internal error: cannot compute public key sha3-384") } sha3_384, err := EncodeDigest(crypto.SHA3_384, h.Sum(nil)) if err != nil { panic("internal error: cannot compute public key sha3-384") } return &openpgpPubKey{pubKey: intPubKey, sha3_384: sha3_384} }
// ReadUserSet returns a list of users matching the parameters set in the read request. // func (ecaa *ECAA) ReadUserSet(ctx context.Context, in *pb.ReadUserSetReq) (*pb.UserSet, error) { Trace.Println("grpc ECAA:ReadUserSet") req := in.Req.Id if ecaa.eca.readRole(req)&int(pb.Role_AUDITOR) == 0 { return nil, errors.New("access denied") } raw, err := ecaa.eca.readCertificate(req, x509.KeyUsageDigitalSignature) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } sig := in.Sig in.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := sha3.New384() raw, _ = proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } rows, err := ecaa.eca.readUsers(int(in.Role)) if err != nil { return nil, err } defer rows.Close() var users []*pb.User if err == nil { for rows.Next() { var id string var role int err = rows.Scan(&id, &role) users = append(users, &pb.User{&pb.Identity{id}, pb.Role(role)}) } err = rows.Err() } return &pb.UserSet{users}, err }
func makeHash(name string) hash.Hash { switch strings.ToLower(name) { case "ripemd160": return ripemd160.New() case "md4": return md4.New() case "md5": return md5.New() case "sha1": return sha1.New() case "sha256": return sha256.New() case "sha384": return sha512.New384() case "sha3-224": return sha3.New224() case "sha3-256": return sha3.New256() case "sha3-384": return sha3.New384() case "sha3-512": return sha3.New512() case "sha512": return sha512.New() case "sha512-224": return sha512.New512_224() case "sha512-256": return sha512.New512_256() case "crc32-ieee": return crc32.NewIEEE() case "crc64-iso": return crc64.New(crc64.MakeTable(crc64.ISO)) case "crc64-ecma": return crc64.New(crc64.MakeTable(crc64.ECMA)) case "adler32": return adler32.New() case "fnv32": return fnv.New32() case "fnv32a": return fnv.New32a() case "fnv64": return fnv.New64() case "fnv64a": return fnv.New64a() case "xor8": return new(xor8) case "fletch16": return &fletch16{} } return nil }
func main() { flag.Parse() hashAlgorithm := sha1.New() if *sha1Flag { hashAlgorithm = sha1.New() } if *md5Flag { hashAlgorithm = md5.New() } if *sha256Flag { hashAlgorithm = sha256.New() } if *sha384Flag { hashAlgorithm = sha512.New384() } if *sha3256Flag { hashAlgorithm = sha3.New256() } if *sha3384Flag { hashAlgorithm = sha3.New384() } if *sha3512Flag { hashAlgorithm = sha3.New512() } if *whirlpoolFlag { hashAlgorithm = whirlpool.New() } if *blakeFlag { hashAlgorithm = blake2.NewBlake2B() } if *ripemd160Flag { hashAlgorithm = ripemd160.New() } for _, fileName := range flag.Args() { f, _ := os.Open(fileName) defer f.Close() hashAlgorithm.Reset() output := genericHashFile(f, hashAlgorithm) if *b64Flag { r64Output := base64.StdEncoding.EncodeToString(output) fmt.Printf("%s %s\n", r64Output, fileName) } else { fmt.Printf("%x %s\n", output, fileName) } } }
func getHashSHA3(bitsize int) (hash.Hash, error) { switch bitsize { case 224: return sha3.New224(), nil case 256: return sha3.New256(), nil case 384: return sha3.New384(), nil case 512: return sha3.New512(), nil case 521: return sha3.New512(), nil default: return nil, fmt.Errorf("Invalid bitsize. It was [%d]. Expected [224, 256, 384, 512, 521]", bitsize) } }
// CreateCertificate requests the creation of a new transaction certificate by the TCA. // func (tcap *TCAP) CreateCertificate(ctx context.Context, req *pb.TCertCreateReq) (*pb.Cert, error) { Trace.Println("grpc TCAP:CreateCertificate") id := req.Id.Id raw, err := tcap.tca.eca.readCertificate(id) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } sig := req.Sig req.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) raw = req.Pub.Key if req.Pub.Type != pb.CryptoType_ECDSA { Error.Println("unsupported key type") return nil, errors.New("unsupported key type") } pub, err := x509.ParsePKIXPublicKey(req.Pub.Key) if err != nil { Error.Println(err) return nil, err } hash := sha3.New384() raw, _ = proto.Marshal(req) hash.Write(raw) if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { Error.Println("signature does not verify") return nil, errors.New("signature does not verify") } if raw, err = tcap.tca.newCertificate(id, pub.(*ecdsa.PublicKey), req.Ts.Seconds); err != nil { Error.Println(err) return nil, err } return &pb.Cert{raw}, nil }
func (ca *CA) createCertificate(id string, pub interface{}, usage x509.KeyUsage, timestamp int64, kdfKey []byte, opt ...pkix.Extension) ([]byte, error) { Trace.Println("Creating certificate for " + id + ".") raw, err := ca.newCertificate(id, pub, usage, opt) if err != nil { Error.Println(err) return nil, err } hash := sha3.New384() hash.Write(raw) if _, err = ca.db.Exec("INSERT INTO Certificates (id, timestamp, usage, cert, hash, kdfkey) VALUES (?, ?, ?, ?, ?, ?)", id, timestamp, usage, raw, hash.Sum(nil), kdfKey); err != nil { Error.Println(err) } return raw, err }
// CreateCertificate requests the creation of a new enrollment certificate by the ECA. // func (ecap *ECAP) CreateCertificate(ctx context.Context, req *pb.ECertCreateReq) (*pb.Creds, error) { Trace.Println("grpc ECAP:CreateCertificate") id := req.Id.Id if pw, err := ecap.eca.readPassword(id); err != nil || pw != req.Pw.Pw { Error.Println("identity or password do not match") return nil, errors.New("identity or password do not match") } sig := req.Sig req.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) raw := req.Pub.Key if req.Pub.Type != pb.CryptoType_ECDSA { Error.Println("unsupported key type") return nil, errors.New("unsupported key type") } pub, err := x509.ParsePKIXPublicKey(req.Pub.Key) if err != nil { Error.Println(err) return nil, err } hash := sha3.New384() raw, _ = proto.Marshal(req) hash.Write(raw) if ecdsa.Verify(pub.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { Error.Println("signature does not verify") return nil, errors.New("signature does not verify") } raw, err = ecap.eca.readCertificate(id) if err != nil { if raw, err = ecap.eca.newCertificate(id, pub.(*ecdsa.PublicKey), time.Now().UnixNano()); err != nil { Error.Println(err) return nil, err } } return &pb.Creds{&pb.Cert{Cert: raw}, ecap.eca.obcKey}, nil }
func TestSHA(t *testing.T) { for i := 0; i < 100; i++ { b, err := GetRandomBytes(i) if err != nil { t.Fatalf("Failed getting random bytes [%s]", err) } h1, err := currentBCCSP.Hash(b, &bccsp.SHAOpts{}) if err != nil { t.Fatalf("Failed computing SHA [%s]", err) } var h hash.Hash switch currentTestConfig.hashFamily { case "SHA2": switch currentTestConfig.securityLevel { case 256: h = sha256.New() case 384: h = sha512.New384() default: t.Fatalf("Invalid security level [%d]", currentTestConfig.securityLevel) } case "SHA3": switch currentTestConfig.securityLevel { case 256: h = sha3.New256() case 384: h = sha3.New384() default: t.Fatalf("Invalid security level [%d]", currentTestConfig.securityLevel) } default: t.Fatalf("Invalid hash family [%s]", currentTestConfig.hashFamily) } h.Write(b) h2 := h.Sum(nil) if !bytes.Equal(h1, h2) { t.Fatalf("Discrempancy found in HASH result [%x], [%x]!=[%x]", b, h1, h2) } } }
// ReadCertificate reads a transaction certificate from the TCA. // func (tcap *TCAP) ReadCertificate(ctx context.Context, in *pb.TCertReadReq) (*pb.Cert, error) { Trace.Println("grpc TCAP:ReadCertificate") req := in.Req.Id id := in.Id.Id if req != id && tcap.tca.eca.readRole(req)&(int(pb.Role_VALIDATOR)|int(pb.Role_AUDITOR)) == 0 { return nil, errors.New("access denied") } raw, err := tcap.tca.eca.readCertificate(req, x509.KeyUsageDigitalSignature) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } sig := in.Sig in.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := sha3.New384() raw, _ = proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } if in.Ts.Seconds != 0 { raw, err = tcap.tca.readCertificate1(id, in.Ts.Seconds) } else { raw, err = tcap.tca.readCertificateByHash(in.Hash.Hash) } if err != nil { return nil, err } return &pb.Cert{raw}, nil }
// GetHash returns and instance of hash.Hash using options opts. // If opts is nil then the default hash function is returned. func (csp *impl) GetHash(opts bccsp.HashOpts) (h hash.Hash, err error) { if opts == nil { return csp.conf.hashFunction(), nil } switch opts.(type) { case *bccsp.SHAOpts: return csp.conf.hashFunction(), nil case *bccsp.SHA256Opts: return sha256.New(), nil case *bccsp.SHA384Opts: return sha512.New384(), nil case *bccsp.SHA3_256Opts: return sha3.New256(), nil case *bccsp.SHA3_384Opts: return sha3.New384(), nil default: return nil, fmt.Errorf("Algorithm not recognized [%s]", opts.Algorithm()) } }
func computeHash(msg []byte, bitsize int) ([]byte, error) { var hash hash.Hash switch bitsize { case 224: hash = sha3.New224() case 256: hash = sha3.New256() case 384: hash = sha3.New384() case 512: hash = sha3.New512() case 521: hash = sha3.New512() default: return nil, fmt.Errorf("Invalid bitsize. It was [%d]. Expected [224, 256, 384, 512, 521]", bitsize) } hash.Write(msg) return hash.Sum(nil), nil }
// Hash hashes messages msg using options opts. func (csp *impl) Hash(msg []byte, opts bccsp.HashOpts) (digest []byte, err error) { var h hash.Hash if opts == nil { h = csp.conf.hashFunction() } else { switch opts.(type) { case *bccsp.SHAOpts: h = csp.conf.hashFunction() case *bccsp.SHA256Opts: h = sha256.New() case *bccsp.SHA384Opts: h = sha512.New384() case *bccsp.SHA3_256Opts: h = sha3.New256() case *bccsp.SHA3_384Opts: h = sha3.New384() default: return nil, fmt.Errorf("Algorithm not recognized [%s]", opts.Algorithm()) } } h.Write(msg) return h.Sum(nil), nil }
// CreateCertificateSet requests the creation of a new transaction certificate set by the TCA. // func (tcap *TCAP) CreateCertificateSet(ctx context.Context, req *pb.TCertCreateSetReq) (*pb.TCertCreateSetResp, error) { Trace.Println("grpc TCAP:CreateCertificateSet") id := req.Id.Id raw, err := tcap.tca.eca.readCertificate(id, x509.KeyUsageDigitalSignature) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } pub := cert.PublicKey.(*ecdsa.PublicKey) sig := req.Sig req.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := sha3.New384() raw, _ = proto.Marshal(req) hash.Write(raw) if ecdsa.Verify(pub, hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } nonce := make([]byte, 16) // 8 bytes rand, 8 bytes timestamp rand.Reader.Read(nonce[:8]) binary.LittleEndian.PutUint64(nonce[8:], uint64(req.Ts.Seconds)) mac := hmac.New(sha3.New384, tcap.tca.hmacKey) raw, _ = x509.MarshalPKIXPublicKey(pub) mac.Write(raw) kdfKey := mac.Sum(nil) num := int(req.Num) if num == 0 { num = 1 } var set [][]byte for i := 0; i < num; i++ { tidx := []byte(strconv.Itoa(i)) tidx = append(tidx[:], nonce[:]...) mac = hmac.New(sha3.New384, kdfKey) mac.Write([]byte{1}) extKey := mac.Sum(nil)[:32] mac = hmac.New(sha3.New384, kdfKey) mac.Write([]byte{2}) mac = hmac.New(sha3.New384, mac.Sum(nil)) mac.Write(tidx) one := new(big.Int).SetInt64(1) k := new(big.Int).SetBytes(mac.Sum(nil)) k.Mod(k, new(big.Int).Sub(pub.Curve.Params().N, one)) k.Add(k, one) tmpX, tmpY := pub.ScalarBaseMult(k.Bytes()) txX, txY := pub.Curve.Add(pub.X, pub.Y, tmpX, tmpY) txPub := ecdsa.PublicKey{Curve: pub.Curve, X: txX, Y: txY} ext, err := CBCEncrypt(extKey, tidx) if err != nil { return nil, err } if raw, err = tcap.tca.createCertificate(id, &txPub, x509.KeyUsageDigitalSignature, req.Ts.Seconds, kdfKey, pkix.Extension{Id: TCertEncTCertIndex, Critical: true, Value: ext}); err != nil { Error.Println(err) return nil, err } set = append(set, raw) } return &pb.TCertCreateSetResp{&pb.CertSet{kdfKey, set}}, nil }
// ReadCertificateSets returns all certificates matching the filter criteria of the request. // func (tcaa *TCAA) ReadCertificateSets(ctx context.Context, in *pb.TCertReadSetsReq) (*pb.CertSets, error) { Trace.Println("grpc TCAA:ReadCertificateSets") req := in.Req.Id if tcaa.tca.eca.readRole(req)&int(pb.Role_AUDITOR) == 0 { return nil, errors.New("access denied") } raw, err := tcaa.tca.eca.readCertificate(req, x509.KeyUsageDigitalSignature) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } sig := in.Sig in.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := sha3.New384() raw, _ = proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } users, err := tcaa.tca.eca.readUsers(int(in.Role)) if err != nil { return nil, err } defer users.Close() begin := int64(0) end := int64(math.MaxInt64) if in.Begin != nil { begin = in.Begin.Seconds } if in.End != nil { end = in.End.Seconds } var sets []*pb.CertSet for users.Next() { var id string var role int if err = users.Scan(&id, &role); err != nil { return nil, err } rows, err := tcaa.tca.eca.readCertificateSets(id, begin, end) if err != nil { return nil, err } defer rows.Close() var certs [][]byte var kdfKey []byte var timestamp int64 timestamp = 0 for rows.Next() { var cert []byte var ts int64 if err = rows.Scan(&cert, &kdfKey, &ts); err != nil { return nil, err } if ts != timestamp { sets = append(sets, &pb.CertSet{&protobuf.Timestamp{Seconds: timestamp, Nanos: 0}, &pb.Identity{id}, kdfKey, certs}) timestamp = ts certs = nil } certs = append(certs, cert) } if err = rows.Err(); err != nil { return nil, err } sets = append(sets, &pb.CertSet{&protobuf.Timestamp{Seconds: timestamp, Nanos: 0}, &pb.Identity{id}, kdfKey, certs}) } if err = users.Err(); err != nil { return nil, err } return &pb.CertSets{sets}, nil }
// CreateCertificatePair requests the creation of a new enrollment certificate pair by the ECA. // func (ecap *ECAP) CreateCertificatePair(ctx context.Context, in *pb.ECertCreateReq) (*pb.ECertCreateResp, error) { Trace.Println("grpc ECAP:CreateCertificate") // validate token var tok, prev []byte var role, state int id := in.Id.Id err := ecap.eca.readUser(id).Scan(&role, &tok, &state, &prev) if err != nil || !bytes.Equal(tok, in.Tok.Tok) { return nil, errors.New("identity or token do not match") } ekey, err := x509.ParsePKIXPublicKey(in.Enc.Key) if err != nil { return nil, err } switch { case state == 0: // initial request, create encryption challenge tok = []byte(randomString(12)) _, err = ecap.eca.db.Exec("UPDATE Users SET token=?, state=?, key=? WHERE id=?", tok, 1, in.Enc.Key, id) if err != nil { Error.Println(err) return nil, err } // out, err := rsa.EncryptPKCS1v15(rand.Reader, ekey.(*rsa.PublicKey), tok) spi := ecies.NewSPI() eciesKey, err := spi.NewPublicKey(nil, ekey.(*ecdsa.PublicKey)) if err != nil { return nil, err } ecies, err := spi.NewAsymmetricCipherFromPublicKey(eciesKey) if err != nil { return nil, err } out, err := ecies.Process(tok) return &pb.ECertCreateResp{nil, nil, nil, &pb.Token{out}}, err case state == 1: // ensure that the same encryption key is signed that has been used for the challenge if subtle.ConstantTimeCompare(in.Enc.Key, prev) != 1 { return nil, errors.New("encryption keys don't match") } // validate request signature sig := in.Sig in.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) if in.Sign.Type != pb.CryptoType_ECDSA { return nil, errors.New("unsupported key type") } skey, err := x509.ParsePKIXPublicKey(in.Sign.Key) if err != nil { return nil, err } hash := sha3.New384() raw, _ := proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(skey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } // create new certificate pair ts := time.Now().UnixNano() sraw, err := ecap.eca.createCertificate(id, skey.(*ecdsa.PublicKey), x509.KeyUsageDigitalSignature, ts, nil, pkix.Extension{Id: ECertSubjectRole, Critical: true, Value: []byte(strconv.Itoa(ecap.eca.readRole(id)))}) if err != nil { Error.Println(err) return nil, err } eraw, err := ecap.eca.createCertificate(id, ekey.(*ecdsa.PublicKey), x509.KeyUsageDataEncipherment, ts, nil, pkix.Extension{Id: ECertSubjectRole, Critical: true, Value: []byte(strconv.Itoa(ecap.eca.readRole(id)))}) if err != nil { ecap.eca.db.Exec("DELETE FROM Certificates Where id=?", id) Error.Println(err) return nil, err } _, err = ecap.eca.db.Exec("UPDATE Users SET state=? WHERE id=?", 2, id) if err != nil { ecap.eca.db.Exec("DELETE FROM Certificates Where id=?", id) Error.Println(err) return nil, err } var obcECKey []byte if role&(int(pb.Role_VALIDATOR)|int(pb.Role_AUDITOR)) != 0 { obcECKey = ecap.eca.obcPriv } else { obcECKey = ecap.eca.obcPub } return &pb.ECertCreateResp{&pb.CertPair{sraw, eraw}, &pb.Token{ecap.eca.obcKey}, obcECKey, nil}, nil } return nil, errors.New("certificate creation token expired") }
func eciesDecrypt(priv *ecdsa.PrivateKey, s1, s2 []byte, ciphertext []byte) ([]byte, error) { params := priv.Curve.Params() var ( rLen int hLen int = sha3.New384().Size() mStart int mEnd int ) //fmt.Printf("Decrypt\n") switch ciphertext[0] { case 2, 3: rLen = ((priv.PublicKey.Curve.Params().BitSize + 7) / 8) + 1 if len(ciphertext) < (rLen + hLen + 1) { return nil, errors.New("Invalid ciphertext") } break case 4: rLen = 2*((priv.PublicKey.Curve.Params().BitSize+7)/8) + 1 if len(ciphertext) < (rLen + hLen + 1) { return nil, errors.New("Invalid ciphertext") } break default: return nil, errors.New("Invalid ciphertext") } mStart = rLen mEnd = len(ciphertext) - hLen //fmt.Printf("Rb %s\n", utils.EncodeBase64(ciphertext[:rLen])) Rx, Ry := elliptic.Unmarshal(priv.Curve, ciphertext[:rLen]) if Rx == nil { return nil, errors.New("Invalid ephemeral PK") } if !priv.Curve.IsOnCurve(Rx, Ry) { return nil, errors.New("Invalid point on curve") } //fmt.Printf("Rx %s\n", utils.EncodeBase64(Rx.Bytes())) //fmt.Printf("Ry %s\n", utils.EncodeBase64(Ry.Bytes())) // Derive a shared secret field element z from the ephemeral secret key k // and convert z to an octet string Z z, _ := params.ScalarMult(Rx, Ry, priv.D.Bytes()) Z := z.Bytes() //fmt.Printf("Z %s\n", utils.EncodeBase64(Z)) // generate keying data K of length ecnKeyLen + macKeyLen octects from Z // ans s1 kE := make([]byte, 32) kM := make([]byte, 32) hkdf := hkdf.New(sha3.New384, Z, s1, nil) _, err := hkdf.Read(kE) if err != nil { return nil, err } _, err = hkdf.Read(kM) if err != nil { return nil, err } // Use the tagging operation of the MAC scheme to compute // the tag D on EM || s2 and then compare mac := hmac.New(sha3.New384, kM) mac.Write(ciphertext[mStart:mEnd]) if len(s2) > 0 { mac.Write(s2) } D := mac.Sum(nil) //fmt.Printf("EM %s\n", utils.EncodeBase64(ciphertext[mStart:mEnd])) //fmt.Printf("D' %s\n", utils.EncodeBase64(D)) //fmt.Printf("D %s\n", utils.EncodeBase64(ciphertext[mEnd:])) if subtle.ConstantTimeCompare(ciphertext[mEnd:], D) != 1 { return nil, errors.New("Tag check failed") } // Use the decryption operation of the symmetric encryption scheme // to decryptr EM under EK as plaintext plaintext, err := aesDecrypt(kE, ciphertext[mStart:mEnd]) return plaintext, err }