bool InstallChecker::verifyPackage( const QString &filePath, bool ) { QProcess proc; proc.start( "hdiutil", QStringList() << "verify" << filePath ); proc.waitForFinished(); if( proc.exitCode() ) return false; QString path = mountPackage( filePath ); if( path.isEmpty() ) return false; xar_t xar = xar_open( path.toUtf8().constData(), 0 ); if( !xar ) return false; QSslCertificate cert; xar_signature_t sig = xar_signature_first( xar ); int32_t count = xar_signature_get_x509certificate_count( sig ); for( int32_t i = 0; i < count; ++i ) { uint32_t size = 0; const uint8_t *data = 0; if( xar_signature_get_x509certificate_data( sig, i, &data, &size ) ) continue; QSslCertificate c( QByteArray( (const char*)data, size ), QSsl::Der ); #if QT_VERSION >= 0x050000 QString cn = c.subjectInfo( QSslCertificate::CommonName ).value(0); #else QString cn = c.subjectInfo( QSslCertificate::CommonName ); #endif if( cn == "Estonian Informatics Centre" || cn == "Developer ID Installer: Riigi Infosüsteemi Amet" ) cert = c; } if( cert.isNull() ) { xar_close( xar ); return false; } uint8_t *data = 0, *signature = 0; uint32_t dataSize = 0, signatureSize = 0; off_t offset = 0; if( xar_signature_copy_signed_data( sig, &data, &dataSize, &signature, &signatureSize, &offset ) ) { xar_close( xar ); return false; } int result = RSA_verify( NID_sha1, data, dataSize, signature, signatureSize, (RSA*)cert.publicKey().handle() ); xar_close( xar ); free( data ); free( signature ); return result; }
static CFArrayRef copyCertChainFromSignature(xar_signature_t sig) { unsigned count = xar_signature_get_x509certificate_count(sig); CFRef<CFMutableArrayRef> certs = makeCFMutableArray(0); for (unsigned ix = 0; ix < count; ix++) { const uint8_t *data; uint32_t length; if (xar_signature_get_x509certificate_data(sig, ix, &data, &length) == 0) { CFTempData cdata(data, length); CFRef<SecCertificateRef> cert = SecCertificateCreateWithData(NULL, cdata); CFArrayAppendValue(certs, cert.get()); } } return certs.yield(); }
static void extract_certs(char *filename, char *cert_base_path) { xar_signature_t sig; xar_t x; int32_t count; int i; const uint8_t *cert_data; uint32_t cert_len; FILE *file; char *cert_path; // open xar, get signature x = xar_open(filename, READ); if ( x == NULL ) { fprintf(stderr, "Could not open %s to extract certificates!\n", filename); exit(1); } sig = xar_signature_first(x); if ( !sig ) { fprintf(stderr, "No signatures found to extract data from.\n"); exit(E_NOSIG); } // iterate through all certificates associated with that signature, write them to disk count = xar_signature_get_x509certificate_count(sig); if (!count) { fprintf(stderr, "Signature bears no certificates. Odd.\n"); exit(1); } for (i=0; i<count; i++) { xar_signature_get_x509certificate_data(sig, i, &cert_data, &cert_len); asprintf(&cert_path, "%s/cert%02i", cert_base_path, i); file = fopen(cert_path, "w"); if (!file) { fprintf(stderr, "Could not save certificate %i to %s.\n", i, cert_path); exit(1); } int n = fwrite(cert_data, cert_len, 1, file); if (n < 0) { fprintf(stderr, "Failed to write certificate to %s (fwrite() returned %i)!\n", cert_path, n); exit(1); } fclose(file); free(cert_path); } // clean up xar_close(x); }