apkverifier

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 30, 2021 License: LGPL-3.0 Imports: 31 Imported by: 2

README

apkverifier

GoDoc Build Status

APK signature verification, should support all algorithms and both scheme v1 and v2, including downgrade attack protection.

Works with Go 1.9 or higher.

Documentation on GoDoc

go get github.com/appflight/apkverifier

Vendored stuff

Because Android can handle even broken x509 cerficates and ZIP files, apkverifier is using the ZipReader from apkparser package and vendors crypto/x509 in internal/x509andr and github.com/fullsailor/pkcs7 in the fullsailor/pkcs7 folder. The last two have some changes to handle some not-entirely-according-to-spec certificates.

Example

package main

import (
	"fmt"
	"github.com/appflight/apkverifier"
	"os"
)

func main() {
	res, err := apkverifier.Verify(os.Args[1], nil)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Verification failed: %s\n", err.Error())
	}

	fmt.Printf("Verification scheme used: v%d\n", res.SigningSchemeId)
	cert, _ := apkverifier.PickBestApkCert(res.SignerCerts)
	if cert == nil {
		fmt.Printf("No certificate found.\n")
	} else {
		fmt.Println(cert)
	}
}

Documentation

Overview

Package apkverifier does APK signature verification. It should support all algorithms and schemes supported Android, including scheme v2 verification and checks for downgrade attack to v1.

Example
package main

import (
	"fmt"
	"github.com/appflight/apkverifier"
	"os"
)

func main() {
	res, err := apkverifier.Verify(os.Args[1], nil)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Verification failed: %s\n", err.Error())
	}

	fmt.Printf("Verification scheme used: v%d\n", res.SigningSchemeId)
	cert, _ := apkverifier.PickBestApkCert(res.SignerCerts)
	if cert == nil {
		fmt.Printf("No certificate found.\n")
	} else {
		fmt.Println(cert)
	}
}
Output:

Index

Examples

Constants

View Source
const (
	SHA224WithRSA x509.SignatureAlgorithm = iota + 65535
	DSAWithSHA224
	ECDSAWithSHA224
)

Variables

View Source
var ErrMixedDexApkFile = errors.New("This file is both DEX and ZIP archive! Exploit?")

Returned from the Verify method if the file starts with the DEX magic value, but otherwise looks like a properly signed APK.

This detect 'Janus' Android vulnerability where a DEX is prepended to a valid, signed APK file. The signature verification passes because with v1 scheme, only the APK portion of the file is checked, but Android then loads the prepended, unsigned DEX file instead of the one from APK. https://www.guardsquare.com/en/blog/new-android-vulnerability-allows-attackers-modify-apps-without-affecting-their-signatures

If this error is returned, the signature is otherwise valid (the err would be nil had it not have the DEX file prepended).

Functions

func ExtractCerts

func ExtractCerts(path string, optionalZip *apkparser.ZipReader) ([][]*x509.Certificate, error)

Extract certs without verifying the signature.

func ExtractCertsReader

func ExtractCertsReader(r io.ReadSeeker, optionalZip *apkparser.ZipReader) ([][]*x509.Certificate, error)

Types

type CertInfo

type CertInfo struct {
	Md5                string
	Sha1               string
	Sha256             string
	ValidFrom, ValidTo time.Time
	Issuer, Subject    string
	SignatureAlgorithm string
	SerialNumber       *big.Int
}

Nicer looking certificate info

func NewCertInfo

func NewCertInfo(cert *x509.Certificate) *CertInfo

Returns new CertInfo with information from the x509.Certificate.

func PickBestApkCert

func PickBestApkCert(chains [][]*x509.Certificate) (*CertInfo, *x509.Certificate)

Picks the "best-looking" (most likely the correct one) certificate from the chain extracted from APK. Is noop for most APKs, as they usually contain only one certificate.

func (*CertInfo) Fill

func (ci *CertInfo) Fill(cert *x509.Certificate)

Replaces CertInfo's data with information from the x509.Certificate.

func (*CertInfo) String

func (ci *CertInfo) String() string

Returns description of the cert, like this: Cert 90d0f1ac70d647edfdf905ff129379bfae469ad6, valid from 2015-08-05 08:01:53 +0000 UTC to 2045-07-28 08:01:53 +0000 UTC, Subject C=US, O=Android, CN=Android Debug, Issuer C=US, O=Android, CN=Android Debug

type Result

type Result struct {
	SigningSchemeId    int
	SignerCerts        [][]*x509.Certificate
	SigningBlockResult *signingblock.VerificationResult
}

Contains result of Apk verification

func Verify

func Verify(path string, optionalZip *apkparser.ZipReader) (res Result, err error)

Calls VerifyWithSdkVersion with sdk versions <apilevel.V_AnyMin; apilevel.V_AnyMax>

func VerifyReader

func VerifyReader(r io.ReadSeeker, optionalZip *apkparser.ZipReader) (res Result, err error)

Calls VerifyWithSdkVersionReader with sdk versions <apilevel.V_AnyMin; apilevel.V_AnyMax>

func VerifyWithSdkVersion

func VerifyWithSdkVersion(path string, optionalZip *apkparser.ZipReader, minSdkVersion, maxSdkVersion int32) (res Result, err error)

see VerifyWithSdkVersionReader

func VerifyWithSdkVersionReader

func VerifyWithSdkVersionReader(r io.ReadSeeker, optionalZip *apkparser.ZipReader, minSdkVersion, maxSdkVersion int32) (res Result, err error)

Verify the application signature. If err is nil, the signature is correct, otherwise it is not and res may or may not contain extracted certificates, depending on how the signature verification failed. Path is required, pass optionalZip if you have the ZipReader already opened and want to reuse it. This method will not close it. minSdkVersion and maxSdkVersion means the apk has to successfuly verify on real devices with sdk version inside the <minSdkVersion;maxSdkVersion> interval. minSdkVersion == apilevel.V_AnyMin means it will obtain the minSdkVersion from AndroidManifest.

Directories

Path Synopsis
fullsailor
pkcs7
Package pkcs7 implements parsing and generation of some PKCS#7 structures.
Package pkcs7 implements parsing and generation of some PKCS#7 structures.
internal
asn1andr
Package asn1 implements parsing of DER-encoded ASN.1 data structures, as defined in ITU-T Rec X.690.
Package asn1 implements parsing of DER-encoded ASN.1 data structures, as defined in ITU-T Rec X.690.
x509andr
Package x509 parses X.509-encoded keys and certificates.
Package x509 parses X.509-encoded keys and certificates.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL