<commit_before>package apk

import (
	"bytes"
	"crypto"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"time"

	"github.com/pkg/errors"
	"go.mozilla.org/autograph/signer"
	"go.mozilla.org/pkcs7"
)

const (
	// Type of this signer is "apk"
	Type = "apk"
)

// An APKSigner is configured to issue PKCS7 detached signatures
// for Android application packages.
type APKSigner struct {
	signer.Configuration
	signingKey  crypto.PrivateKey
	signingCert *x509.Certificate
}

// New initializes an apk signer using a configuration
func New(conf signer.Configuration) (s *APKSigner, err error) {
	s = new(APKSigner)
	if conf.Type != Type {
		return nil, errors.Errorf("apk: invalid type %q, must be %q", conf.Type, Type)
	}
	s.Type = conf.Type
	if conf.ID == "" {
		return nil, errors.New("apk: missing signer ID in signer configuration")
	}
	s.ID = conf.ID
	if conf.PrivateKey == "" {
		return nil, errors.New("apk: missing private key in signer configuration")
	}
	s.PrivateKey = conf.PrivateKey
	s.signingKey, err = signer.ParsePrivateKey([]byte(conf.PrivateKey))
	if err != nil {
		return nil, errors.Wrap(err, "apk: failed to parse private key")
	}
	block, _ := pem.Decode([]byte(conf.Certificate))
	if block == nil {
		return nil, errors.New("apk: failed to parse certificate PEM")
	}
	s.signingCert, err = x509.ParseCertificate(block.Bytes)
	if err != nil {
		return nil, errors.Wrap(err, "apk: could not parse X.509 certificate")
	}
	// APK signing certs typically have a 30y expiration, which is fairly useless
	// but requires the validity to be correct
	if time.Now().Before(s.signingCert.NotBefore) || time.Now().After(s.signingCert.NotAfter) {
		return nil, errors.New("apk: signer certificate is not currently valid")
	}
	return
}

// Config returns the configuration of the current signer
func (s *APKSigner) Config() signer.Configuration {
	return signer.Configuration{
		ID:          s.ID,
		Type:        s.Type,
		PrivateKey:  s.PrivateKey,
		Certificate: s.Certificate,
	}
}

// SignData takes input data and returns a PKCS7 detached signature
func (s *APKSigner) SignData(input []byte, options interface{}) (signer.Signature, error) {
	p7sig := new(Signature)
	toBeSigned, err := pkcs7.NewSignedData(input)
	if err != nil {
		return nil, errors.Wrap(err, "apk: cannot initialize signed data")
	}
	err = toBeSigned.AddSigner(s.signingCert, s.signingKey, pkcs7.SignerInfoConfig{})
	if err != nil {
		return nil, errors.Wrap(err, "apk: cannot sign")
	}
	toBeSigned.Detach()
	p7sig.Data, err = toBeSigned.Finish()
	if err != nil {
		return nil, errors.Wrap(err, "apk: cannot finish signing data")
	}
	p7sig.Finished = true
	return p7sig, nil
}
<commit_msg>apk: set the digest algorithm to sha256<commit_after>package apk

import (
	"bytes"
	"crypto"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"time"

	"github.com/pkg/errors"
	"go.mozilla.org/autograph/signer"
	"go.mozilla.org/pkcs7"
)

const (
	// Type of this signer is "apk"
	Type = "apk"
)

// An APKSigner is configured to issue PKCS7 detached signatures
// for Android application packages.
type APKSigner struct {
	signer.Configuration
	signingKey  crypto.PrivateKey
	signingCert *x509.Certificate
}

// New initializes an apk signer using a configuration
func New(conf signer.Configuration) (s *APKSigner, err error) {
	s = new(APKSigner)
	if conf.Type != Type {
		return nil, errors.Errorf("apk: invalid type %q, must be %q", conf.Type, Type)
	}
	s.Type = conf.Type
	if conf.ID == "" {
		return nil, errors.New("apk: missing signer ID in signer configuration")
	}
	s.ID = conf.ID
	if conf.PrivateKey == "" {
		return nil, errors.New("apk: missing private key in signer configuration")
	}
	s.PrivateKey = conf.PrivateKey
	s.signingKey, err = signer.ParsePrivateKey([]byte(conf.PrivateKey))
	if err != nil {
		return nil, errors.Wrap(err, "apk: failed to parse private key")
	}
	block, _ := pem.Decode([]byte(conf.Certificate))
	if block == nil {
		return nil, errors.New("apk: failed to parse certificate PEM")
	}
	s.signingCert, err = x509.ParseCertificate(block.Bytes)
	if err != nil {
		return nil, errors.Wrap(err, "apk: could not parse X.509 certificate")
	}
	// APK signing certs typically have a 30y expiration, which is fairly useless
	// but requires the validity to be correct
	if time.Now().Before(s.signingCert.NotBefore) || time.Now().After(s.signingCert.NotAfter) {
		return nil, errors.New("apk: signer certificate is not currently valid")
	}
	return
}

// Config returns the configuration of the current signer
func (s *APKSigner) Config() signer.Configuration {
	return signer.Configuration{
		ID:          s.ID,
		Type:        s.Type,
		PrivateKey:  s.PrivateKey,
		Certificate: s.Certificate,
	}
}

// SignData takes input data and returns a PKCS7 detached signature
func (s *APKSigner) SignData(input []byte, options interface{}) (signer.Signature, error) {
	p7sig := new(Signature)
	toBeSigned, err := pkcs7.NewSignedData(input)
	if err != nil {
		return nil, errors.Wrap(err, "apk: cannot initialize signed data")
	}

	// APKs are signed with SHA256
	toBeSigned.SetDigestAlgorithm(pkcs7.OIDDigestAlgorithmSHA256)

	err = toBeSigned.AddSigner(s.signingCert, s.signingKey, pkcs7.SignerInfoConfig{})
	if err != nil {
		return nil, errors.Wrap(err, "apk: cannot sign")
	}
	toBeSigned.Detach()
	p7sig.Data, err = toBeSigned.Finish()
	if err != nil {
		return nil, errors.Wrap(err, "apk: cannot finish signing data")
	}
	p7sig.Finished = true
	return p7sig, nil
}

{'fraction_non_alphanumeric': 0.12364901996702693, 'fraction_numerical': 0.01099102399706906, 'mean_word_length': 4.074349442379182, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7512060', 'n_tokens_mistral': 1988, 'n_tokens_neox': 1884, 'n_words': 552}