/// <summary> /// Digitaly Sign the OVF /// </summary> /// <param name="x509">Signing Certificate</param> /// <param name="pathToOvf">Absolute path to the OVF files</param> /// <param name="ovfFileName">OVF file name (file.ovf)</param> public static void Sign(X509Certificate2 Certificate, string PackageFolder, string PackageFileName) { if (Certificate == null) { throw new ArgumentException(Messages.CERTIFICATE_IS_INVALID); } string PackageName = PackageNameFromFileName(PackageFileName); string ManifestPath = Path.Combine(PackageFolder, PackageName) + Properties.Settings.Default.manifestFileExtension; // Create the manifest if it doesn't exist. if (!File.Exists(ManifestPath)) { Manifest(PackageFolder, PackageFileName); } // Compute the SHA1 hash of the manifest. byte[] hash = null; using (FileStream stream = new FileStream(ManifestPath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (SHA1 sha1 = SHA1.Create()) { hash = sha1.ComputeHash(stream); } // Describe the file to sign. ManifestFileEntry signed = new ManifestFileEntry(); signed.Algorithm = Properties.Settings.Default.securityAlgorithm; signed.Filename = Path.GetFileName(ManifestPath); // Compute the signature. try { RSACryptoServiceProvider csp = (RSACryptoServiceProvider)Certificate.PrivateKey; signed.Digest = csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")); } catch (Exception exception) { string message = exception.Message; } // Create the signature file. string SignaturePath = Path.Combine(PackageFolder, PackageName) + Properties.Settings.Default.certificateFileExtension; if (File.Exists(SignaturePath)) { File.Delete(SignaturePath); } using (FileStream stream = new FileStream(SignaturePath, FileMode.CreateNew, FileAccess.Write, FileShare.None)) using (StreamWriter writer = new StreamWriter(stream)) { // Describe the signed file. writer.WriteLine(signed.ToString()); // Export the certificate encoded in Base64 using DER. writer.WriteLine("-----BEGIN CERTIFICATE-----"); string b64Cert = Convert.ToBase64String(Certificate.Export(X509ContentType.SerializedCert)); writer.WriteLine(b64Cert); writer.WriteLine("-----END CERTIFICATE-----"); writer.WriteLine("\r\n"); writer.Flush(); } }
/// <summary> /// Digitaly Sign the OVF /// </summary> /// <param name="x509">Signing Certificate</param> /// <param name="pathToOvf">Absolute path to the OVF files</param> /// <param name="ovfFileName">OVF file name (file.ovf)</param> public static void Sign(X509Certificate2 Certificate, string PackageFolder, string PackageFileName) { if (Certificate == null) { throw new ArgumentException(Messages.CERTIFICATE_IS_INVALID); } string PackageName = PackageNameFromFileName(PackageFileName); string ManifestPath = Path.Combine(PackageFolder, PackageName) + Properties.Settings.Default.manifestFileExtension; // Create the manifest if it doesn't exist. if (!File.Exists(ManifestPath)) { Manifest(PackageFolder, PackageFileName); } // Compute the SHA1 hash of the manifest. byte[] hash = null; using (FileStream stream = new FileStream(ManifestPath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (SHA1 sha1 = SHA1.Create()) { hash = sha1.ComputeHash(stream); } // Describe the file to sign. ManifestFileEntry signed = new ManifestFileEntry(); signed.Algorithm = Properties.Settings.Default.securityAlgorithm; signed.Filename = Path.GetFileName(ManifestPath); // Compute the signature. try { RSACryptoServiceProvider csp = (RSACryptoServiceProvider)Certificate.PrivateKey; signed.Digest = csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")); } catch (Exception exception) { string message = exception.Message; } // Create the signature file. string SignaturePath = Path.Combine(PackageFolder, PackageName) + Properties.Settings.Default.certificateFileExtension; if (File.Exists(SignaturePath)) File.Delete(SignaturePath); using (FileStream stream = new FileStream(SignaturePath, FileMode.CreateNew, FileAccess.Write, FileShare.None)) using (StreamWriter writer = new StreamWriter(stream)) { // Describe the signed file. writer.WriteLine(signed.ToString()); // Export the certificate encoded in Base64 using DER. writer.WriteLine("-----BEGIN CERTIFICATE-----"); string b64Cert = Convert.ToBase64String(Certificate.Export(X509ContentType.SerializedCert)); writer.WriteLine(b64Cert); writer.WriteLine("-----END CERTIFICATE-----"); writer.WriteLine("\r\n"); writer.Flush(); } }
/// <summary> /// Create a Manifest for the OVF /// </summary> /// <param name="pathToOvf">Absolute path to the OVF files</param> /// <param name="ovfFileName">OVF file name (file.ovf)</param> public static void Manifest(string pathToOvf, string ovfFileName) { List <ManifestFileEntry> mfes = new List <ManifestFileEntry>(); SHA1 sha1 = SHA1.Create(); EnvelopeType ovfenv; try { using (FileStream stream = new FileStream(Path.Combine(pathToOvf, ovfFileName), FileMode.Open, FileAccess.Read)) { ManifestFileEntry mfe = new ManifestFileEntry(); mfe.Algorithm = Properties.Settings.Default.securityAlgorithm; mfe.Filename = ovfFileName; mfe.Digest = sha1.ComputeHash(stream); mfes.Add(mfe); stream.Position = 0; using (StreamReader sr = new StreamReader(stream)) ovfenv = (EnvelopeType)Deserialize(sr.ReadToEnd()); } } catch (Exception ex) { log.ErrorFormat("OVF.Security.Manifest: {0}", ex.Message); throw; } if (ovfenv != null && ovfenv.References != null && ovfenv.References.File != null && ovfenv.References.File.Length > 0) { File_Type[] files = ovfenv.References.File; foreach (File_Type file in files) { string currentfile = Path.Combine(pathToOvf, file.href); if (!File.Exists(currentfile)) { continue; } ManifestFileEntry mfe = new ManifestFileEntry(); using (FileStream computestream = new FileStream(currentfile, FileMode.Open, FileAccess.Read)) { mfe.Algorithm = Properties.Settings.Default.securityAlgorithm; mfe.Filename = file.href; mfe.Digest = sha1.ComputeHash(computestream); mfes.Add(mfe); } } } string manifest = Path.Combine(pathToOvf, string.Format("{0}{1}", Path.GetFileNameWithoutExtension(ovfFileName), Properties.Settings.Default.manifestFileExtension)); File.Delete(manifest); //no exception is thrown if file does not exist, so no need to check using (FileStream stream = new FileStream(manifest, FileMode.CreateNew, FileAccess.Write)) { using (StreamWriter sw = new StreamWriter(stream)) { foreach (ManifestFileEntry mf in mfes) { sw.WriteLine(mf.ToString()); } sw.Flush(); } } log.Debug("OVF.Manifest completed"); }
/// <summary> /// Create a Manifest for the OVF /// </summary> /// <param name="pathToOvf">Absolute path to the OVF files</param> /// <param name="ovfFileName">OVF file name (file.ovf)</param> public static void Manifest(string pathToOvf, string ovfFileName) { List<ManifestFileEntry> mfes = new List<ManifestFileEntry>(); SHA1 sha1 = SHA1.Create(); EnvelopeType ovfenv; try { using (FileStream stream = new FileStream(Path.Combine(pathToOvf, ovfFileName), FileMode.Open, FileAccess.Read)) { ManifestFileEntry mfe = new ManifestFileEntry(); mfe.Algorithm = Properties.Settings.Default.securityAlgorithm; mfe.Filename = ovfFileName; mfe.Digest = sha1.ComputeHash(stream); mfes.Add(mfe); stream.Position = 0; using (StreamReader sr = new StreamReader(stream)) ovfenv = (EnvelopeType)Deserialize(sr.ReadToEnd()); } } catch (Exception ex) { Log.Error("OVF.Security.Manifest: {0}", ex.Message); throw ex; } if (ovfenv != null && ovfenv.References != null && ovfenv.References.File != null && ovfenv.References.File.Length > 0) { File_Type[] files = ovfenv.References.File; foreach (File_Type file in files) { string currentfile = Path.Combine(pathToOvf, file.href); if (!File.Exists(currentfile)) continue; ManifestFileEntry mfe = new ManifestFileEntry(); using (FileStream computestream = new FileStream(currentfile, FileMode.Open, FileAccess.Read)) { mfe.Algorithm = Properties.Settings.Default.securityAlgorithm; mfe.Filename = file.href; mfe.Digest = sha1.ComputeHash(computestream); mfes.Add(mfe); } } } string manifest = Path.Combine(pathToOvf, string.Format("{0}{1}", Path.GetFileNameWithoutExtension(ovfFileName), Properties.Settings.Default.manifestFileExtension)); File.Delete(manifest); //no exception is thrown if file does not exist, so no need to check using (FileStream stream = new FileStream(manifest, FileMode.CreateNew, FileAccess.Write)) { using (StreamWriter sw = new StreamWriter(stream)) { foreach (ManifestFileEntry mf in mfes) sw.WriteLine(mf.ToString()); sw.Flush(); } } Log.Debug("OVF.Manifest completed"); }