diff --git a/app/src/main/cpp/api.cpp b/app/src/main/cpp/api.cpp index 8472282..6c06861 100644 --- a/app/src/main/cpp/api.cpp +++ b/app/src/main/cpp/api.cpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "api.h" #include "consts.h" @@ -448,6 +450,25 @@ ASN1_SEQUENCE(EncapsulatedContent) = { } ASN1_SEQUENCE_END(EncapsulatedContent) IMPLEMENT_ASN1_FUNCTIONS(EncapsulatedContent) +#include + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +typedef struct ECDSA_SIG_st { + BIGNUM *r; + BIGNUM *s; +} ECDSA_SIG; + +typedef struct bignum_st +{ +BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ +int top; /* Index of last used d +1. */ +/* The next are internal book keeping for bn_expand. */ +int dmax; /* Size of the d array. */ +int neg; /* one if the number is negative */ +int flags; +}; +#endif + void Connector::readEFSOD() { auto content = readFileBySFI(EFSOD_SFI); bytes digest(256 / 8); @@ -494,7 +515,7 @@ void Connector::readEFSOD() { bytes encapsulatedDigest(256 / 8); SHA256(encapsulatedBytes.data(), encapsulatedBytes.size(), encapsulatedDigest.data()); - logBytes("FILE SOD encapsulated digest %s", encapsulatedDigest); + logBytes("FILE SOD calculated encapsulated digest %s", encapsulatedDigest); auto signer = (PKCS7_SIGNER_INFO*)sk_value((OPENSSL_STACK*)pkcs7->d.sign->signer_info, 0); @@ -507,7 +528,7 @@ void Connector::readEFSOD() { if (ASN1_TYPE_get(x) == 4) { auto p = x->value.octet_string; auto pp = bytes(p->data, p->data + p->length); - logBytes("%s", pp); + logBytes("sod stored message digest %s", pp); if (pp != encapsulatedDigest) { throw "Encapsulated digest check with attribute data wrong"; @@ -516,10 +537,62 @@ void Connector::readEFSOD() { } { // now use openssl to verify with no CA - + // If PKCS7_NOVERIFY is set the signer's certificates are not chain verified. + int simple_verify = PKCS7_verify(pkcs7, nullptr, nullptr, nullptr, nullptr, PKCS7_NOVERIFY); + LOGI("certificate basic check status %d", simple_verify); } - { // extract certificate and check with CA pubkey + { // extract certificate's signature and check with CA pubkey + auto cert = (X509*)sk_value((OPENSSL_STACK*)pkcs7->d.sign->cert, 0); + const ASN1_BIT_STRING *psig; + const X509_ALGOR *palg; + X509_get0_signature(&psig, &palg, cert); + bytes signature(psig->data, psig->data + psig->length); + logBytes("signature raw %s", signature); + + const unsigned char* sig = signature.data(); + ECDSA_SIG* cert_sig; + d2i_ECDSA_SIG(&cert_sig, &sig, signature.size()); + + if (!cert_sig) { + throw "cannot get certificate signature"; + } + + LOGI("certificate get successfully"); + + LOGI("certificate signature: (%s,%s)\n", + BN_bn2hex(ECDSA_SIG_get0_r(cert_sig)), + BN_bn2hex(ECDSA_SIG_get0_s(cert_sig))); + + bytes tbs(1000); + unsigned char* tbsPtr = tbs.data(); + int tbsSize = i2d_re_X509_tbs(cert, &tbsPtr); + printf("%d\n", tbsSize); + logBytes("tbs %s", tbs); + + bytes tbsDigest(384 / 8); + SHA384(tbs.data(), tbsSize, tbsDigest.data()); + logBytes("digest %s", tbsDigest); + + // ca params + BIGNUM* ca_x = nullptr; + BIGNUM* ca_y = nullptr; + BN_dec2bn(&ca_x, "5705586746797687392276527904990313555022905475611271258729414636068323857880334000957361424951661974682935706611888"); + BN_dec2bn(&ca_y, "7821704373206592378644977211567592118672246135776362491204878202396889655625917188376232816427307041739256606332695"); + +// printf("ca pubkey: (%s,%s)\n", +// BN_bn2hex(ca_x), +// BN_bn2hex(ca_y)); + + EC_KEY* ca = EC_KEY_new_by_curve_name(NID_secp384r1); + EC_KEY_set_public_key_affine_coordinates(ca, ca_x, ca_y); + + bool ca_verify = ECDSA_do_verify(tbsDigest.data(), tbsDigest.size(), cert_sig, ca); + LOGI("ca verified status %d\n", ca_verify); + + if (ca_verify != 1) { + throw "verification with CA returns false"; + } } } \ No newline at end of file