private byte[] GetContentHash(ExcelVbaProject proj) { //MS-OVBA 2.4.2 var enc = System.Text.Encoding.GetEncoding(proj.CodePage); BinaryWriter bw = new BinaryWriter(new MemoryStream()); bw.Write(enc.GetBytes(proj.Name)); bw.Write(enc.GetBytes(proj.Constants)); foreach (var reference in proj.References) { if (reference.ReferenceRecordID == 0x0D) { bw.Write((byte)0x7B); } if (reference.ReferenceRecordID == 0x0E) { //var r = (ExcelVbaReferenceProject)reference; //BinaryWriter bwTemp = new BinaryWriter(new MemoryStream()); //bwTemp.Write((uint)r.Libid.Length); //bwTemp.Write(enc.GetBytes(r.Libid)); //bwTemp.Write((uint)r.LibIdRelative.Length); //bwTemp.Write(enc.GetBytes(r.LibIdRelative)); //bwTemp.Write(r.MajorVersion); //bwTemp.Write(r.MinorVersion); foreach (byte b in BitConverter.GetBytes((uint)reference.Libid.Length)) //Length will never be an UInt with 4 bytes that aren't 0 (> 0x00FFFFFF), so no need for the rest of the properties. { if (b != 0) { bw.Write(b); } else { break; } } } } foreach (var module in proj.Modules) { var lines = module.Code.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { if (!line.StartsWith("attribute", StringComparison.OrdinalIgnoreCase)) { bw.Write(enc.GetBytes(line)); } } } var buffer = (bw.BaseStream as MemoryStream).ToArray(); var hp = System.Security.Cryptography.MD5.Create(); return(hp.ComputeHash(buffer)); }
internal byte[] SignProject(ExcelVbaProject proj) { if (!Certificate.HasPrivateKey) { //throw (new InvalidOperationException("The certificate doesn't have a private key")); Certificate = null; return(null); } var hash = GetContentHash(proj); BinaryWriter bw = new BinaryWriter(new MemoryStream()); bw.Write((byte)0x30); //Constructed Type bw.Write((byte)0x32); //Total length bw.Write((byte)0x30); //Constructed Type bw.Write((byte)0x0E); //Length SpcIndirectDataContent bw.Write((byte)0x06); //Oid Tag Indentifier bw.Write((byte)0x0A); //Lenght OId bw.Write(new byte[] { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x1D }); //Encoded Oid 1.3.6.1.4.1.311.2.1.29 bw.Write((byte)0x04); //Octet String Tag Identifier bw.Write((byte)0x00); //Zero length bw.Write((byte)0x30); //Constructed Type (DigestInfo) bw.Write((byte)0x20); //Length DigestInfo bw.Write((byte)0x30); //Constructed Type (Algorithm) bw.Write((byte)0x0C); //length AlgorithmIdentifier bw.Write((byte)0x06); //Oid Tag Indentifier bw.Write((byte)0x08); //Lenght OId bw.Write(new byte[] { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 }); //Encoded Oid for 1.2.840.113549.2.5 (AlgorithmIdentifier MD5) bw.Write((byte)0x05); //Null type identifier bw.Write((byte)0x00); //Null length bw.Write((byte)0x04); //Octet String Identifier bw.Write((byte)hash.Length); //Hash length bw.Write(hash); //Content hash ContentInfo contentInfo = new ContentInfo(((MemoryStream)bw.BaseStream).ToArray()); contentInfo.ContentType.Value = "1.3.6.1.4.1.311.2.1.4"; #if (Core) Verifier = new EnvelopedCms(contentInfo); var r = new CmsRecipient(Certificate); Verifier.Encrypt(r); return(Verifier.Encode()); #else Verifier = new SignedCms(contentInfo); var signer = new CmsSigner(Certificate); Verifier.ComputeSignature(signer, false); return(Verifier.Encode()); #endif }
/// <summary> /// Create an empty VBA project. /// </summary> public void CreateVBAProject() { #if !MONO if (_vba != null || _package.Package.PartExists(new Uri(ExcelVbaProject.PartUri, UriKind.Relative))) { throw (new InvalidOperationException("VBA project already exists.")); } _vba = new ExcelVbaProject(this); _vba.Create(); #endif #if MONO throw new NotSupportedException("Creating a VBA project is not supported under Mono."); #endif }
public void Dispose() { _sharedStrings.Clear(); _sharedStringsList.Clear(); _sharedStrings = null; _sharedStringsList = null; _vba = null; if (_worksheets != null) { _worksheets.Dispose(); _worksheets = null; } _package = null; _properties = null; if (_formulaParser != null) { _formulaParser.Dispose(); _formulaParser = null; } }
internal ExcelVbaModuleCollection(ExcelVbaProject project) { _project = project; }
//Create Oid from a bytearray //private string ReadHash(byte[] content) //{ // StringBuilder builder = new StringBuilder(); // int offset = 0x6; // if (0 < (content.Length)) // { // byte num = content[offset]; // byte num2 = (byte)(num / 40); // builder.Append(num2.ToString(null, null)); // builder.Append("."); // num2 = (byte)(num % 40); // builder.Append(num2.ToString(null, null)); // ulong num3 = 0L; // for (int i = offset + 1; i < content.Length; i++) // { // num2 = content[i]; // num3 = (ulong)(ulong)(num3 << 7) + ((byte)(num2 & 0x7f)); // if ((num2 & 0x80) == 0) // { // builder.Append("."); // builder.Append(num3.ToString(null, null)); // num3 = 0L; // } // //1.2.840.113549.2.5 // } // } // string oId = builder.ToString(); // return oId; //} internal void Save(ExcelVbaProject proj) { if (Certificate == null) { return; } if (Certificate.HasPrivateKey == false) //No signature. Remove any Signature part { var storeCert = GetCertFromStore(StoreLocation.CurrentUser); if (storeCert == null) { storeCert = GetCertFromStore(StoreLocation.LocalMachine); } if (storeCert != null && storeCert.HasPrivateKey == true) { Certificate = storeCert; } else { foreach (var r in Part.GetRelationships()) { Part.DeleteRelationship(r.Id); } Part.Package.DeletePart(Part.Uri); return; } } var ms = new MemoryStream(); var bw = new BinaryWriter(ms); byte[] certStore = GetCertStore(); byte[] cert = SignProject(proj); bw.Write((uint)cert.Length); bw.Write((uint)44); //?? 36 ref inside cert ?? bw.Write((uint)certStore.Length); //cbSigningCertStore bw.Write((uint)(cert.Length + 44)); //certStoreOffset bw.Write((uint)0); //cbProjectName bw.Write((uint)(cert.Length + certStore.Length + 44)); //projectNameOffset bw.Write((uint)0); //fTimestamp bw.Write((uint)0); //cbTimestampUrl bw.Write((uint)(cert.Length + certStore.Length + 44 + 2)); //timestampUrlOffset bw.Write(cert); bw.Write(certStore); bw.Write((ushort)0); //rgchProjectNameBuffer bw.Write((ushort)0); //rgchTimestampBuffer bw.Write((ushort)0); bw.Flush(); var rel = proj.Part.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault(); if (Part == null) { if (rel != null) { Uri = rel.TargetUri; Part = proj._pck.GetPart(rel.TargetUri); } else { Uri = new Uri("/xl/vbaProjectSignature.bin", UriKind.Relative); Part = proj._pck.CreatePart(Uri, ExcelPackage.schemaVBASignature); } } if (rel == null) { proj.Part.CreateRelationship(UriHelper.ResolvePartUri(proj.Uri, Uri), Packaging.TargetMode.Internal, schemaRelVbaSignature); } var b = ms.ToArray(); Part.GetStream(FileMode.Create).Write(b, 0, b.Length); }
private byte[] GetContentHash(ExcelVbaProject proj) { //MS-OVBA 2.4.2 var enc = System.Text.Encoding.GetEncoding(proj.CodePage); BinaryWriter bw = new BinaryWriter(new MemoryStream()); bw.Write(enc.GetBytes(proj.Name)); bw.Write(enc.GetBytes(proj.Constants)); foreach (var reference in proj.References) { if (reference.ReferenceRecordID == 0x0D) { bw.Write((byte)0x7B); } if (reference.ReferenceRecordID == 0x0E) { //var r = (ExcelVbaReferenceProject)reference; //BinaryWriter bwTemp = new BinaryWriter(new MemoryStream()); //bwTemp.Write((uint)r.Libid.Length); //bwTemp.Write(enc.GetBytes(r.Libid)); //bwTemp.Write((uint)r.LibIdRelative.Length); //bwTemp.Write(enc.GetBytes(r.LibIdRelative)); //bwTemp.Write(r.MajorVersion); //bwTemp.Write(r.MinorVersion); foreach (byte b in BitConverter.GetBytes((uint)reference.Libid.Length)) //Length will never be an UInt with 4 bytes that aren't 0 (> 0x00FFFFFF), so no need for the rest of the properties. { if (b != 0) { bw.Write(b); } else { break; } } } } foreach (var module in proj.Modules) { var lines = module.Code.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { if (!line.StartsWith("attribute", true, null)) { bw.Write(enc.GetBytes(line)); } } } var buffer = (bw.BaseStream as MemoryStream).ToArray(); var hp = System.Security.Cryptography.MD5CryptoServiceProvider.Create(); return hp.ComputeHash(buffer); }
internal byte[] SignProject(ExcelVbaProject proj) { if (!Certificate.HasPrivateKey) { //throw (new InvalidOperationException("The certificate doesn't have a private key")); Certificate = null; return null; } var hash = GetContentHash(proj); BinaryWriter bw = new BinaryWriter(new MemoryStream()); bw.Write((byte)0x30); //Constructed Type bw.Write((byte)0x32); //Total length bw.Write((byte)0x30); //Constructed Type bw.Write((byte)0x0E); //Length SpcIndirectDataContent bw.Write((byte)0x06); //Oid Tag Indentifier bw.Write((byte)0x0A); //Lenght OId bw.Write(new byte[] { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x1D }); //Encoded Oid 1.3.6.1.4.1.311.2.1.29 bw.Write((byte)0x04); //Octet String Tag Identifier bw.Write((byte)0x00); //Zero length bw.Write((byte)0x30); //Constructed Type (DigestInfo) bw.Write((byte)0x20); //Length DigestInfo bw.Write((byte)0x30); //Constructed Type (Algorithm) bw.Write((byte)0x0C); //length AlgorithmIdentifier bw.Write((byte)0x06); //Oid Tag Indentifier bw.Write((byte)0x08); //Lenght OId bw.Write(new byte[] { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 }); //Encoded Oid for 1.2.840.113549.2.5 (AlgorithmIdentifier MD5) bw.Write((byte)0x05); //Null type identifier bw.Write((byte)0x00); //Null length bw.Write((byte)0x04); //Octet String Identifier bw.Write((byte)hash.Length); //Hash length bw.Write(hash); //Content hash ContentInfo contentInfo = new ContentInfo(((MemoryStream)bw.BaseStream).ToArray()); contentInfo.ContentType.Value = "1.3.6.1.4.1.311.2.1.4"; Verifier = new SignedCms(contentInfo); var signer = new CmsSigner(Certificate); Verifier.ComputeSignature(signer, false); return Verifier.Encode(); }
//Create Oid from a bytearray //private string ReadHash(byte[] content) //{ // StringBuilder builder = new StringBuilder(); // int offset = 0x6; // if (0 < (content.Length)) // { // byte num = content[offset]; // byte num2 = (byte)(num / 40); // builder.Append(num2.ToString(null, null)); // builder.Append("."); // num2 = (byte)(num % 40); // builder.Append(num2.ToString(null, null)); // ulong num3 = 0L; // for (int i = offset + 1; i < content.Length; i++) // { // num2 = content[i]; // num3 = (ulong)(ulong)(num3 << 7) + ((byte)(num2 & 0x7f)); // if ((num2 & 0x80) == 0) // { // builder.Append("."); // builder.Append(num3.ToString(null, null)); // num3 = 0L; // } // //1.2.840.113549.2.5 // } // } // string oId = builder.ToString(); // return oId; //} internal void Save(ExcelVbaProject proj) { if (Certificate == null || Certificate.HasPrivateKey==false) //No signature. Remove any Signature part { if (Part != null) { foreach (var r in Part.GetRelationships()) { Part.DeleteRelationship(r.Id); } Part.Package.DeletePart(Part.Uri); } return; } var ms = new MemoryStream(); var bw = new BinaryWriter(ms); byte[] certStore = GetCertStore(); byte[] cert = SignProject(proj); bw.Write((uint)cert.Length); bw.Write((uint)44); //?? 36 ref inside cert ?? bw.Write((uint)certStore.Length); //cbSigningCertStore bw.Write((uint)(cert.Length + 44)); //certStoreOffset bw.Write((uint)0); //cbProjectName bw.Write((uint)(cert.Length + certStore.Length + 44)); //projectNameOffset bw.Write((uint)0); //fTimestamp bw.Write((uint)0); //cbTimestampUrl bw.Write((uint)(cert.Length + certStore.Length + 44 + 2)); //timestampUrlOffset bw.Write(cert); bw.Write(certStore); bw.Write((ushort)0);//rgchProjectNameBuffer bw.Write((ushort)0);//rgchTimestampBuffer bw.Write((ushort)0); bw.Flush(); var rel = proj.Part.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault(); if (Part == null) { if (rel != null) { Uri = rel.TargetUri; Part = proj._pck.GetPart(rel.TargetUri); } else { Uri = new Uri("/xl/vbaProjectSignature.bin", UriKind.Relative); Part = proj._pck.CreatePart(Uri, ExcelPackage.schemaVBASignature); } } if (rel == null) { proj.Part.CreateRelationship(PackUriHelper.ResolvePartUri(proj.Uri, Uri), TargetMode.Internal, schemaRelVbaSignature, PackagePartForMono.NextRelationshipID); } var b = ms.ToArray(); Part.GetStream(FileMode.Create).Write(b, 0, b.Length); }
internal ExcelVbaProtection(ExcelVbaProject project) { _project = project; VisibilityState = true; }
/// <summary> /// Create an empty VBA project. /// </summary> public void CreateVBAProject() { if (_vba != null || _package.Package.PartExists(new Uri(ExcelVbaProject.PartUri, UriKind.Relative))) { throw (new InvalidOperationException("VBA project already exists.")); } _vba = new ExcelVbaProject(this); _vba.Create(); }