AndyQ / NFCPassportReader

NFCPassportReader for iOS 13
MIT License
738 stars 239 forks source link

Active Authentication with ECDSA signature not working #125

Closed pauphi closed 2 years ago

pauphi commented 2 years ago

Hi!

I've noticed that Active Authentication with ECDSA signature does not work. Have tested on documents with both ecdsa-plain-SHA224 and ecdsa-plain-SHA384. The logs are not very helpful, just displaying Error verifying Active Authentication ECDSA signature. Active Authentication with RSA signature works as expected.

If I'm not mistaken it's not a huge problem as most documents either support Chip Authentication as well, or use Active Authentication with RSA signature - however, I've seen specimen from Japan that only have Active Authentication w/ ECDSA.

nRes = EVP_DigestVerifyFinal(ctx, fixedSignature, fixedSignature.count); in OpenSSLUtils.verifySignature returns 0

pauphi commented 2 years ago

Found a fix for this. It's actually two things that need to be done:

1) in OpenSSLUtils.verifyECDSASignature we need to change from this:

sigData.withUnsafeBufferPointer { (unsafeBufPtr) in
    let unsafePointer = unsafeBufPtr.baseAddress!
    let r = BN_bin2bn(unsafePointer, 32, nil)
    let s = BN_bin2bn(unsafePointer + 32, 32, nil)
    ECDSA_SIG_set0(ecsig, r, s)
}

to this:

let l = sigData.count / 2
sigData.withUnsafeBufferPointer { (unsafeBufPtr) in
    let unsafePointer = unsafeBufPtr.baseAddress!
    let r = BN_bin2bn(unsafePointer, Int32(l), nil)
    let s = BN_bin2bn((unsafePointer + l), Int32(l), nil)
    ECDSA_SIG_set0(ecsig, r, s)
}

Found inspiration from jllarraz's Kotlin wrapper around JMRTD: https://github.com/jllarraz/AndroidPassportReader/blob/86856e5616a0f84b377a5cfafe16086c798d2602/app/src/main/java/example/jllarraz/com/passportreader/utils/PassportNFC.kt#L713

2) we need to pass in a new parameter to verifyECDSASignature - digestType. We get the digestType by parsing the SecurityInfos in DG14 to a new object ActiveAuthenticationInfo based on the existence of the id-AA OID, and then get the signature algorithm OID. For example, for the Japenese specimen I've tested this is ecdsa-plain-sha384, and for Belgian specimen it is ecdsa-plain-sha224.

I can submit a PR with these changes later today

pauphi commented 2 years ago

Opened a pull request: #129

AndyQ commented 2 years ago

Thanks I'll get this added for the next release!

AndyQ commented 2 years ago

Merged and in 1.1.9 - thanks!