Skip to main content

apk/sign/
error.rs

1use der::oid::ObjectIdentifier;
2
3use super::{CoverageError, JarError, KeyKind, Scheme, SignatureAlgorithm, SignatureError};
4use crate::archive::ZipError;
5use crate::types::ApiLevel;
6
7/// Why a key, certificate, or keystore could not be used.
8#[derive(Debug, thiserror::Error)]
9#[non_exhaustive]
10pub enum KeyError {
11    #[error("malformed PEM: {0}")]
12    Pem(#[from] pem_rfc7468::Error),
13    #[error("no private key found")]
14    MissingPrivateKey,
15    #[error("no certificate found")]
16    MissingCertificate,
17    #[error("the private key is encrypted; supply its password")]
18    PasswordRequired,
19    #[error("encrypted private keys require the `keystore` feature")]
20    EncryptionDisabled,
21    #[error("the password is incorrect")]
22    WrongPassword,
23    #[error("PKCS#8 private key: {0}")]
24    Pkcs8(#[from] pkcs8::Error),
25    #[error("malformed PKCS#1 RSA private key: {0}")]
26    Pkcs1(#[from] pkcs1::Error),
27    #[error("malformed or unsupported EC private key (P-256 and P-384 are supported)")]
28    InvalidEcKey,
29    #[error("malformed public key: {0}")]
30    PublicKey(#[from] spki::Error),
31    #[error("invalid RSA key: {0}")]
32    Rsa(#[from] rsa::Error),
33    #[error("{bits}-bit RSA keys are too weak to sign with; use at least {min} bits")]
34    RsaKeyTooSmall { bits: u32, min: u32 },
35    #[error("unsupported key algorithm {oid}")]
36    UnsupportedAlgorithm { oid: ObjectIdentifier },
37    #[error("unsupported elliptic curve {oid}")]
38    UnsupportedCurve { oid: ObjectIdentifier },
39    #[error("malformed X.509 certificate: {0}")]
40    Certificate(#[source] der::Error),
41    #[error("the private key does not match the certificate")]
42    CertificateMismatch,
43    #[error("{algorithm} cannot be used with a {key} key")]
44    AlgorithmMismatch { algorithm: SignatureAlgorithm, key: KeyKind },
45    #[error("signing failed: {0}")]
46    Signing(#[source] signature::Error),
47    #[error("encoding a signature block failed: {0}")]
48    Encoding(#[source] der::Error),
49    #[cfg(feature = "keystore")]
50    #[error("JKS keystore: {0}")]
51    Jks(#[from] jks::KeyStoreError),
52    #[cfg(feature = "keystore")]
53    #[error("PKCS#12 keystore: {0}")]
54    Pkcs12(#[from] p12_keystore::error::Error),
55    #[error("the keystore parser rejected malformed input")]
56    MalformedKeystore,
57    #[error("the keystore has no entry {alias:?}")]
58    UnknownAlias { alias: String },
59    #[error("keystore entry {alias:?} is not a private key")]
60    NotAPrivateKey { alias: String },
61    #[error("the keystore has {count} private keys; name one")]
62    AmbiguousAlias { count: usize },
63}
64/// Why an APK could not be signed.
65#[derive(Debug, thiserror::Error)]
66#[non_exhaustive]
67pub enum SignError {
68    #[error(transparent)]
69    Coverage(#[from] CoverageError),
70    #[error("APK Signature Scheme v3 supports one signer; {count} were given")]
71    MultipleV3Signers { count: usize },
72    #[error("Android {min_sdk} cannot verify JAR signatures made with EC keys (API 18+ required)")]
73    EcdsaJarRequiresApi18 { min_sdk: ApiLevel },
74    #[error("the APK has no AndroidManifest.xml; set the minimum SDK explicitly")]
75    UnknownMinSdk,
76    #[error(transparent)]
77    Key(#[from] KeyError),
78    #[error(transparent)]
79    Zip(#[from] ZipError),
80    #[error("signed APK failed its self-check: {0}")]
81    SelfCheck(#[source] Box<VerifyError>),
82}
83
84/// Why an APK's signatures did not verify.
85#[derive(Debug, thiserror::Error)]
86#[non_exhaustive]
87pub enum VerifyError {
88    #[error("the APK is not signed")]
89    Unsigned,
90    #[error(transparent)]
91    Zip(#[from] ZipError),
92    #[error("the APK signing block's size fields do not match its length")]
93    MalformedBlock,
94    #[error("APK signing block entry at offset {offset:#x} has invalid length {len}")]
95    InvalidBlockPair { offset: u64, len: u64 },
96    #[error("malformed {scheme} block near offset {offset:#x}")]
97    MalformedScheme { scheme: Scheme, offset: u64 },
98    #[error("{scheme} block has no signers")]
99    NoSigners { scheme: Scheme },
100    #[error("{scheme} signer {signer} has no signatures")]
101    NoSignatures { scheme: Scheme, signer: usize },
102    #[error("{scheme} signer {signer} uses no supported algorithm (IDs {ids:x?})")]
103    NoSupportedAlgorithm { scheme: Scheme, signer: usize, ids: Vec<u32> },
104    #[error("{scheme} signer {signer}: {algorithm} signature: {source}")]
105    BadSignature { scheme: Scheme, signer: usize, algorithm: SignatureAlgorithm, source: SignatureError },
106    #[error("{scheme} signer {signer}: digests and signatures name different algorithms")]
107    AlgorithmListMismatch { scheme: Scheme, signer: usize },
108    #[error("{scheme} signer {signer} has no certificates")]
109    NoCertificates { scheme: Scheme, signer: usize },
110    #[error("{scheme} signer {signer}: public key does not match the certificate")]
111    PublicKeyMismatch { scheme: Scheme, signer: usize },
112    #[error("{scheme} signer {signer}: SDK range differs between signed and unsigned data")]
113    SdkRangeMismatch { scheme: Scheme, signer: usize },
114    #[error("{scheme} signer {signer}: SDK range {min}..={max} is empty")]
115    InvalidSdkRange { scheme: Scheme, signer: usize, min: u32, max: u32 },
116    #[error("{scheme} signers do not cover API level {sdk} exactly once")]
117    SdkCoverage { scheme: Scheme, sdk: u32 },
118    #[error("{scheme} signer {signer}: no digest for {algorithm}")]
119    MissingDigest { scheme: Scheme, signer: usize, algorithm: SignatureAlgorithm },
120    #[error("{scheme} signer {signer}: the APK's contents do not match the signed digest")]
121    DigestMismatch { scheme: Scheme, signer: usize },
122    #[error("{protected_by} declares a {scheme} signature that is missing (stripping attack?)")]
123    StrippedScheme { scheme: Scheme, protected_by: Scheme },
124    #[error("{first} and {second} were signed by different signers")]
125    SignerMismatch { first: Scheme, second: Scheme },
126    #[error("the APK uses signing key rotation, which this crate cannot verify")]
127    KeyRotationUnsupported,
128    #[error("the APK's signatures do not cover the releases it supports: {0}")]
129    Coverage(#[from] CoverageError),
130    #[error(transparent)]
131    Key(#[from] KeyError),
132    #[error(transparent)]
133    Jar(#[from] JarError),
134}