public X509Certificate2 Sign(string certThumbPrint) { if (this.IsSigned) { throw new Exception("Package is already signed"); } IntegrityList integrityList = this.ComputeIntegrityList(out _, out _); byte[] integrityListContent = integrityList.ToByteArray(); X509Certificate2 signingCert = CryptoUtils.CreateDetachedCmsSignature(integrityListContent, certThumbPrint, out byte[] integrityListSignature); _zipFile.AddEntry(_integrityListPath, integrityListContent); _zipFile.AddEntry(_integrityListSignaturePath, integrityListSignature); _zipFile.Save(); return(signingCert); }
public X509Certificate2 Verify(bool skipCertValidation) { if (!this.IsSigned) { throw new Exception("Package is not signed"); } IntegrityList computedIntegrityList = this.ComputeIntegrityList(out byte[] integrityListContent, out byte[] integrityListSignatureContent); IntegrityList embeddedIntegrityList = IntegrityList.FromByteArray(integrityListContent); SignerInfo signerInfo = CryptoUtils.VerifyDetachedCmsSignature(integrityListContent, integrityListSignatureContent, skipCertValidation); if (!computedIntegrityList.SequenceEqual(embeddedIntegrityList)) { throw new InvalidSignatureException("Package content has been altered"); } return(signerInfo.Certificate); }
private IntegrityList ComputeIntegrityList(out byte[] integrityListContent, out byte[] integrityListSignatureContent) { byte[] integrityListContentLocal = null; byte[] integrityListSignatureContentLocal = null; IntegrityList integrityList = new IntegrityList(); foreach (ZipEntry zipEntry in _zipFile.EntriesSorted) { if (zipEntry.IsDirectory) { continue; } if (IsIntegrityList(zipEntry)) { integrityListContentLocal = ReadZipEntryContent(zipEntry); continue; } if (IsIntegrityListSignature(zipEntry)) { integrityListSignatureContentLocal = ReadZipEntryContent(zipEntry); continue; } IntegrityEntry integrityEntry = new IntegrityEntry() { FilePath = zipEntry.FileName, HashAlgorithm = @"http://www.w3.org/2000/09/xmldsig#sha256", HashValue = ComputeHash(zipEntry) }; integrityList.Add(integrityEntry); } integrityListContent = integrityListContentLocal; integrityListSignatureContent = integrityListSignatureContentLocal; return(integrityList); }