Example #1
0
File: avp.go Project: keysonZZZ/kmg
//you need set packet before encode
func (a *PasswordAVP) Encode() (b []byte, err error) {
	m := crypto.Hash(crypto.MD5).New()
	m.Write(a.packet.Secret)
	m.Write(a.packet.Authenticator[:])
	md := m.Sum(nil)
	if len(a.Value) > 128 {
		return nil, fmt.Errorf("[PasswordAVP.Encode] len(data)[%d]>128", len(a.Value))
	}
	inPassLen := len(a.Value) / 16 * 16
	if len(a.Value)%16 != 0 {
		inPassLen += 16
	}
	pass := make([]byte, inPassLen)
	outPass := make([]byte, inPassLen)
	copy(pass, a.Value)
	blockNum := inPassLen / 16
	for i := 0; i < blockNum; i++ {
		for j := 0; j < 16; j++ {
			outPass[i*16+j] = pass[i*16+j] ^ md[j]
		}
		m := crypto.Hash(crypto.MD5).New()
		m.Write(a.packet.Secret)
		m.Write(outPass[i*16 : i*16+16])
		md = m.Sum(nil)
	}
	return encodeWithByteSlice(AVPTypeUserPassword, outPass)
}
Example #2
0
File: avp.go Project: keysonZZZ/kmg
func avpPassword(p *Packet, typ AVPType, data []byte) (avp AVP, err error) {
	fmt.Printf("%#v\n", data)
	if len(data) < 16 {
		return nil, fmt.Errorf("[avpPassword] len(data)[%d]<16", len(data))
	}
	if len(data) > 128 {
		return nil, fmt.Errorf("[avpPassword] len(data)[%d]>128", len(data))
	}
	//Decode password. XOR against md5(p.server.secret+Authenticator)
	m := crypto.Hash(crypto.MD5).New()
	m.Write(p.Secret)
	m.Write(p.Authenticator[:])
	md := m.Sum(nil)
	pass := append([]byte(nil), data...)
	blockNum := len(pass) / 16
	if len(pass)%16 != 0 {
		return nil, fmt.Errorf("[avpPassword] blockNum[%d]%%16!=0", blockNum)
	}
	outputPass := make([]byte, len(pass))
	for i := 0; i < blockNum; i++ {
		for j := 0; j < 16; j++ {
			outputPass[i*16+j] = pass[i*16+j] ^ md[j]
		}
		m := crypto.Hash(crypto.MD5).New()
		m.Write(p.Secret)
		m.Write(pass[i*16 : i*16+16])
		md = m.Sum(nil)
	}
	outputPass = bytes.TrimRight(outputPass, string([]rune{0}))
	avpP := &PasswordAVP{
		Value: string(outputPass),
	}
	avpP.SetPacket(p)
	return avpP, nil
}
Example #3
0
func fetchCert(address string) (*cert, error) {
	//fetch cert over network
	addr, err := net.ResolveTCPAddr("tcp", address)
	if err != nil {
		return nil, err
	}
	netCon, err := net.DialTCP("tcp", nil, addr)
	if err != nil {
		return nil, err
	}
	host := strings.Split(address, ":")[0]

	config := &tls.Config{
		NextProtos:         []string{"http"},
		ServerName:         host,
		InsecureSkipVerify: true,
	}
	log.Println("getting cert for: ", host)
	client := tls.Client(netCon, config)
	err = client.Handshake()
	if err != nil {
		return nil, err
	}
	state := client.ConnectionState()
	if len(state.PeerCertificates) == 0 {
		return nil, errors.New("no cert recieved from host")
	}
	for i := range state.PeerCertificates {

		log.Println(state.PeerCertificates[i].Subject)
		certRaw := state.PeerCertificates[i].Raw
		sha := crypto.Hash(crypto.SHA1).New()
		sha.Write(certRaw)
		myFP := hex.EncodeToString(sha.Sum(nil))
		myFP = fingerPrintStr(myFP).String()

		log.Println(myFP)
		log.Println("---")
	}
	certRaw := state.PeerCertificates[0].Raw

	sha := crypto.Hash(crypto.SHA1).New()
	sha.Write(certRaw)

	client.Close()
	netCon.Close()

	c := &cert{state.PeerCertificates[0], sha.Sum(nil)}
	return c, nil
}
Example #4
0
func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) {
	switch version {
	case VersionSSL30:
		return prf30, crypto.Hash(0)
	case VersionTLS10, VersionTLS11:
		return prf10, crypto.Hash(0)
	case VersionTLS12:
		if suite.flags&suiteSHA384 != 0 {
			return prf12(sha512.New384), crypto.SHA384
		}
		return prf12(sha256.New), crypto.SHA256
	default:
		panic("unknown version")
	}
}
Example #5
0
func (r NotaryResponse) signResponse(response []byte) ([]byte, error) {
	hash := crypto.Hash(crypto.SHA1).New()
	hash.Write(response)
	hashed := hash.Sum(nil)

	return rsa.SignPKCS1v15(rand.Reader, r.privateKey, crypto.SHA1, hashed)
}
Example #6
0
// Sign signs the given message with priv.
// Ed25519 performs two passes over messages to be signed and therefore cannot
// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
// indicate the message hasn't been hashed. This can be achieved by passing
// crypto.Hash(0) as the value for opts.
func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
	if opts.HashFunc() != crypto.Hash(0) {
		return nil, errors.New("ed25519: cannot sign hashed message")
	}

	return Sign(priv, message), nil
}
Example #7
0
func getHashForOID(oid asn1.ObjectIdentifier) (crypto.Hash, error) {
	switch {
	case oid.Equal(oidDigestAlgorithmSHA1):
		return crypto.SHA1, nil
	}
	return crypto.Hash(0), ErrUnsupportedAlgorithm
}
Example #8
0
func (p *Packet) Encode(b []byte) (n int, ret []byte, err error) {
	b[0] = uint8(p.Code)
	b[1] = uint8(p.Identifier)
	copy(b[4:20], p.Authenticator[:])
	written := 20
	bb := b[20:]
	for i, _ := range p.AVPs {
		n, err = p.AVPs[i].Encode(bb)
		written += n
		if err != nil {
			return written, nil, err
		}
		bb = bb[n:]
	}
	//check if written too big.
	binary.BigEndian.PutUint16(b[2:4], uint16(written))

	// fix up the authenticator
	hasher := crypto.Hash(crypto.MD5).New()
	hasher.Write(b[:written])
	hasher.Write([]byte(p.server.secret))
	copy(b[4:20], hasher.Sum(nil))

	return written, b, err
}
Example #9
0
File: hmac.go Project: vbatts/gossl
// this is ugly.
func getHashName(h hash.Hash) string {
	hn := reflect.TypeOf(h).String()
	fields := strings.Split(hn, ".")
	var hashName string
	hashName = fields[0]
	if strings.HasPrefix(fields[0], "*") {
		hashName = fields[0][1:]
	}
	elem := reflect.ValueOf(h).Elem()
	switch hashName {
	case "sha256":
		f := elem.FieldByName("is224")
		if f.IsValid() {
			if f.Bool() {
				hashName = "sha224"
			}
		}
		break
	case "sha512":
		f := elem.FieldByName("function")
		if f.IsValid() {
			if crypto.Hash(f.Uint()) == crypto.SHA384 {
				hashName = "sha384"
			}
		}
		break
	}
	return hashName
}
Example #10
0
// appleResponse takes an Apple-Challenge header value, and constructs a response for it.
// To derive the response, the IP and MAC of the connection are needed, so the local address
// has to be passed in.
func appleResponse(challenge string, addr net.Addr) (c64 string, err error) {
	// iTunes seems to not pad things. Let's fix that.
	p64 := base64pad(challenge)
	ptext, err := base64.StdEncoding.DecodeString(p64)
	if err != nil {
		return
	}

	ptext = append(ptext, GetIP(addr)...)
	ptext = append(ptext, GetMAC(addr)...)
	for len(ptext) < 0x20 {
		ptext = append(ptext, 0)
	}

	ctext, err := rsa.SignPKCS1v15(nil, rsaPrivKey, crypto.Hash(0), ptext)
	if err != nil {
		return
	}
	c64 = base64.StdEncoding.EncodeToString(ctext)

	// We should respond in kind to iTunes
	if len(p64) != len(challenge) {
		c64 = base64unpad(c64)
	}

	return
}
Example #11
0
// ParseRequest parses an OCSP request in DER form. It only supports
// requests for a single certificate. Signed requests are not supported.
// If a request includes a signature, it will result in a ParseError.
func ParseRequest(bytes []byte) (*Request, error) {
	var req ocspRequest
	rest, err := asn1.Unmarshal(bytes, &req)
	if err != nil {
		return nil, err
	}
	if len(rest) > 0 {
		return nil, ParseError("trailing data in OCSP request")
	}

	if len(req.TBSRequest.RequestList) == 0 {
		return nil, ParseError("OCSP request contains no request body")
	}
	innerRequest := req.TBSRequest.RequestList[0]

	hashFunc := getHashAlgorithmFromOID(innerRequest.Cert.HashAlgorithm.Algorithm)
	if hashFunc == crypto.Hash(0) {
		return nil, ParseError("OCSP request uses unknown hash function")
	}

	return &Request{
		HashAlgorithm:  hashFunc,
		IssuerNameHash: innerRequest.Cert.NameHash,
		IssuerKeyHash:  innerRequest.Cert.IssuerKeyHash,
		SerialNumber:   innerRequest.Cert.SerialNumber,
	}, nil
}
Example #12
0
// Restore resets the digest to the given state.
func (d *digest) Restore(state []byte) error {
	decoder := gob.NewDecoder(bytes.NewReader(state))

	var function uint

	// We decode this way so that we do not have
	// to export these fields of the digest struct.
	vals := []interface{}{
		&d.h, &d.x, &d.nx, &d.len, &function,
	}

	for _, val := range vals {
		if err := decoder.Decode(val); err != nil {
			return err
		}
	}

	switch crypto.Hash(function) {
	case crypto.SHA224:
		d.is224 = true
	case crypto.SHA256:
		d.is224 = false
	default:
		return resumable.ErrBadState
	}

	return nil
}
Example #13
0
// TODO(rlb): This is not taken from crypto/x509, but it's of the same general form.
func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash {
	for hash, oid := range hashOIDs {
		if oid.Equal(target) {
			return hash
		}
	}
	return crypto.Hash(0)
}
Example #14
0
func TestResultUnsupportedAlgorithmWillCauseNewHmacAuthToPanic(t *testing.T) {
	defer func() {
		err := recover()
		assert.Equal(t, err,
			"hmacauth: hash algorithm #0 is unavailable")
	}()
	NewHmacAuth(crypto.Hash(0), nil, "", nil)
}
Example #15
0
func TestUnsupportedHashAlgorithm(t *testing.T) {
	algorithm, err := DigestNameToCryptoHash("unsupported")
	assert.NotEqual(t, err, nil)
	assert.Equal(t, err.Error(),
		"hmacauth: hash algorithm not supported: unsupported")
	assert.Equal(t, algorithm, crypto.Hash(0))
	assert.Equal(t, algorithm.Available(), false)
}
Example #16
0
// hashForServerKeyExchange hashes the given slices and returns their digest
// and the identifier of the hash function used. The sigAndHash argument is
// only used for >= TLS 1.2 and precisely identifies the hash function to use.
func hashForServerKeyExchange(sigAndHash signatureAndHash, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
	if version >= VersionTLS12 {
		if !isSupportedSignatureAndHash(sigAndHash, supportedSignatureAlgorithms) {
			return nil, crypto.Hash(0), errors.New("tls: unsupported hash function used by peer")
		}
		hashFunc, err := lookupTLSHash(sigAndHash.hash)
		if err != nil {
			return nil, crypto.Hash(0), err
		}
		h := hashFunc.New()
		for _, slice := range slices {
			h.Write(slice)
		}
		digest := h.Sum(nil)
		return digest, hashFunc, nil
	}
	if sigAndHash.signature == signatureECDSA {
		return sha1Hash(slices), crypto.SHA1, nil
	}
	return md5SHA1Hash(slices), crypto.MD5SHA1, nil
}
Example #17
0
func TestUnpaddedSignature(t *testing.T) {
	msg := []byte("Thu Dec 19 18:06:16 EST 2013\n")
	// This base64 value was generated with:
	// % echo Thu Dec 19 18:06:16 EST 2013 > /tmp/msg
	// % openssl rsautl -sign -inkey key -out /tmp/sig -in /tmp/msg
	//
	// Where "key" contains the RSA private key given at the bottom of this
	// file.
	expectedSig := decodeBase64("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==")

	sig, err := SignPKCS1v15(nil, rsaPrivateKey, crypto.Hash(0), msg)
	if err != nil {
		t.Fatalf("SignPKCS1v15 failed: %s", err)
	}
	if !bytes.Equal(sig, expectedSig) {
		t.Fatalf("signature is not expected value: got %x, want %x", sig, expectedSig)
	}
	if err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.Hash(0), msg, sig); err != nil {
		t.Fatalf("signature failed to verify: %s", err)
	}
}
Example #18
0
// IssueToken creates a new Token for the authenticated user. Callers should
// prefill the Token with whatever values they like and leave zero values
// to be set.
// The generated token will also be persisted and can be handed to the client
// with no more handling.
func (p *Passenger) IssueToken(ctx context.Context, token *model.Token) (string, error) {
	now := time.Now()

	token.Creation = now

	if token.Expiry == (time.Time{}) {
		token.Expiry = now.Add(defaultValidity)
	} else {
		if token.Expiry.Before(now.Add(minValidity)) {
			return "", fmt.Errorf("passenger: token must be valid at least %s", minValidity)
		}

		if token.Expiry.After(now.Add(maxValidity)) {
			return "", fmt.Errorf("passenger: token must be valid at most %s", maxValidity)
		}
	}

	// TODO(flowlo): This will reject all scopes for now, as we are not using them.
	// As soon as we introduce scopes, this check must be rewritten accordingly.
	if len(token.Scopes) > 0 {
		return "", fmt.Errorf("passenger: unknown scopes: %s", strings.Join(token.Scopes, ", "))
	}

	if len(token.Description) > 512 || len(token.Description) < 4 {
		return "", fmt.Errorf("passenger: description has bad len %d", len(token.Description))
	}

	var raw [tokenLength]byte

	if _, err := rand.Read(raw[:]); err != nil {
		return "", err
	}

	if token.Hash == 0 {
		token.Hash = int(defaultHash)
	}
	token.Digest = crypto.Hash(token.Hash).New().Sum(raw[:])

	// TODO(flowlo): Set token.RemoteAddr.

	clone := Passenger{
		User:  p.User,
		Token: token,
	}

	key, err := clone.Save(ctx)
	if err != nil {
		return "", err
	}

	return encodeToken(key, &raw)
}
Example #19
0
func (p *Passenger) check(raw []byte) error {
	digest := crypto.Hash(p.Token.Hash).New().Sum(raw)

	if subtle.ConstantTimeCompare(digest, p.Token.Digest) != 1 {
		return ErrDigestMismatch
	}

	if p.Token.Expiry.Before(time.Now()) {
		return ErrTokenExpired
	}

	return nil
}
Example #20
0
func (p *Passenger) check(raw []byte) error {
	digest := crypto.Hash(p.AccessToken.Hash).New().Sum(raw)

	if !bytes.Equal(digest, p.AccessToken.Digest) {
		return ErrDigestMismatch
	}

	if p.AccessToken.Expiry.Before(time.Now()) {
		return ErrTokenExpired
	}

	return nil
}
Example #21
0
// hashForServerKeyExchange hashes the given slices and returns their digest
// and the identifier of the hash function used. The hashFunc argument is only
// used for >= TLS 1.2 and precisely identifies the hash function to use.
func hashForServerKeyExchange(sigType, hashFunc uint8, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
	if version >= VersionTLS12 {
		switch hashFunc {
		case hashSHA256:
			return sha256Hash(slices), crypto.SHA256, nil
		case hashSHA1:
			return sha1Hash(slices), crypto.SHA1, nil
		default:
			return nil, crypto.Hash(0), errors.New("tls: unknown hash function used by peer")
		}
	}
	if sigType == signatureECDSA || sigType == signatureDSA {
		return sha1Hash(slices), crypto.SHA1, nil
	}
	return md5SHA1Hash(slices), crypto.MD5SHA1, nil
}
Example #22
0
func DecodeUserPassword(p *Packet, a *AVP) error {
	//Decode password. XOR against md5(p.server.secret+Authenticator)
	secAuth := append([]byte(nil), []byte(p.server.secret)...)
	secAuth = append(secAuth, p.Authenticator[:]...)
	m := crypto.Hash(crypto.MD5).New()
	m.Write(secAuth)
	md := m.Sum(nil)
	pass := a.Value
	if len(pass) == 16 {
		for i := 0; i < len(pass); i++ {
			pass[i] = pass[i] ^ md[i]
		}
		a.Value = bytes.TrimRight(pass, string([]rune{0}))
		return nil
	}
	return errors.New("not implemented for password > 16")
}
Example #23
0
func (r NotaryResponse) VerifySig() (valid bool) {
	fpList, err := json.Marshal(r.FingerprintList)
	if err != nil {
		return false
	}
	hash := crypto.Hash(crypto.SHA1).New()
	hash.Write(fpList)
	hashed := hash.Sum(nil)
	sig, err := base64.StdEncoding.DecodeString(r.Signature)
	if err != nil {
		return false
	}
	err = rsa.VerifyPKCS1v15(r.notary.certificate.PublicKey.(*rsa.PublicKey), crypto.SHA1, hashed, sig)
	if err == nil {
		return true
	}
	return false
}
Example #24
0
//此方法保证不修改包的内容
func (p *Packet) Encode() (b []byte, err error) {
	p = p.Copy()
	p.SetAVP(&BinaryAVP{
		Type:  AVPTypeMessageAuthenticator,
		Value: make([]byte, 16),
	})
	if p.Code == CodeAccessRequest {
		_, err := rand.Read(p.Authenticator[:])
		if err != nil {
			return nil, err
		}
	}
	//TODO request的时候重新计算密码
	b, err = p.encodeNoHash()
	if err != nil {
		return
	}
	//计算Message-Authenticator这个AVP的值,特殊化处理,Message-Authenticator这个AVP被放在最后面
	hasher := hmac.New(crypto.MD5.New, []byte(p.Secret))
	hasher.Write(b)
	copy(b[len(b)-16:len(b)], hasher.Sum(nil))

	// fix up the authenticator
	// handle request and response stuff.
	// here only handle response part.
	switch p.Code {
	case CodeAccessRequest:
	case CodeAccessAccept, CodeAccessReject, CodeAccessChallenge,
		CodeAccountingRequest, CodeAccountingResponse:
		//rfc2865 page 15 Response Authenticator
		//rfc2866 page 6 Response Authenticator
		//rfc2866 page 6 Request Authenticator
		hasher := crypto.Hash(crypto.MD5).New()
		hasher.Write(b)
		hasher.Write([]byte(p.Secret))
		copy(b[4:20], hasher.Sum(nil)) //返回值再把Authenticator写回去
	default:
		return nil, fmt.Errorf("not handle p.Code %d", p.Code)
	}

	return b, err
}
Example #25
0
// ParseTOTPConfig parses a serialised TOTP configuration.
func ParseTOTPConfig(in []byte) (*TOTPConfig, error) {
	var size int32
	var algo int8
	var provider []byte

	var config = new(TOTPConfig)
	dec := tlv.NewDecoder(in)
	err := dec.Decode(&config.Key)
	if err != nil {
		return nil, errInvalidTOTPConfig
	}

	err = dec.Decode(&config.Start)
	if err != nil {
		return nil, errInvalidTOTPConfig
	}

	err = dec.Decode(&config.Step)
	if err != nil {
		return nil, errInvalidTOTPConfig
	}

	err = dec.Decode(&size)
	if err != nil {
		return nil, errInvalidTOTPConfig
	}
	config.Size = int(size)

	err = dec.Decode(&algo)
	if err != nil {
		return nil, errInvalidTOTPConfig
	}
	config.Algo = crypto.Hash(algo)

	err = dec.Decode(&provider)
	if err != nil {
		return nil, errInvalidTOTPConfig
	}
	config.Provider = string(provider)
	return config, nil
}
Example #26
0
File: avp.go Project: Kidapt/radius
func (s avpPasswordt) Value(p *Packet, a AVP) interface{} {
	if p == nil {
		return ""
	}
	//Decode password. XOR against md5(p.server.secret+Authenticator)
	secAuth := append([]byte(nil), []byte(p.Secret)...)
	secAuth = append(secAuth, p.Authenticator[:]...)
	m := crypto.Hash(crypto.MD5).New()
	m.Write(secAuth)
	md := m.Sum(nil)
	pass := append([]byte(nil), a.Value...)
	if len(pass) == 16 {
		for i := 0; i < len(pass); i++ {
			pass[i] = pass[i] ^ md[i]
		}
		pass = bytes.TrimRight(pass, string([]rune{0}))
		return string(pass)
	}
	fmt.Println("[GetPassword] warning: not implemented for password > 16")
	return ""
}
Example #27
0
// New returns a new hash.Hash which calculates the given hash function.
func (h Hash) New() hash.Hash {
	return crypto.Hash(h).New()
}
Example #28
0
// Size returns the size in bytes of the hash output.
func (h Hash) Size() int {
	return crypto.Hash(h).Size()
}
Example #29
0
// Available returns if the given hash function is available at runtime.
func (h Hash) Available() bool {
	return crypto.Hash(h).Available()
}
Example #30
0
var hashOIDs = map[crypto.Hash]asn1.ObjectIdentifier{
	crypto.SHA1:   asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}),
	crypto.SHA256: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}),
	crypto.SHA384: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2}),
	crypto.SHA512: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3}),
}

// TODO(rlb): This is also from crypto/x509, so same comment as AGL's below
var signatureAlgorithmDetails = []struct {
	algo       x509.SignatureAlgorithm
	oid        asn1.ObjectIdentifier
	pubKeyAlgo x509.PublicKeyAlgorithm
	hash       crypto.Hash
}{
	{x509.MD2WithRSA, oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */},
	{x509.MD5WithRSA, oidSignatureMD5WithRSA, x509.RSA, crypto.MD5},
	{x509.SHA1WithRSA, oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1},
	{x509.SHA256WithRSA, oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256},
	{x509.SHA384WithRSA, oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384},
	{x509.SHA512WithRSA, oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512},
	{x509.DSAWithSHA1, oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1},
	{x509.DSAWithSHA256, oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256},
	{x509.ECDSAWithSHA1, oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1},
	{x509.ECDSAWithSHA256, oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256},
	{x509.ECDSAWithSHA384, oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384},
	{x509.ECDSAWithSHA512, oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512},
}

// TODO(rlb): This is also from crypto/x509, so same comment as AGL's below
func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {