diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index bc5f08a09b..7ca7d93416 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -1550,6 +1550,53 @@ namespace OpenSim.Framework
}
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void ConvertPemToPKCS12(string certFileName, string fullChainPath, string privateKeyPath)
+ {
+ ConvertPemToPKCS12Certificate(certFileName, fullChainPath, privateKeyPath, null);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void ConvertPemToPKCS12(string certFileName, string fullChainPath, string privateKeyPath, string outputPassword)
+ {
+ ConvertPemToPKCS12Certificate(certFileName, fullChainPath, privateKeyPath, outputPassword);
+ }
+
+ ///
+ /// Convert or renew .pem certificate to PKCS12 .pfx and .p12 usable by OpenSim.
+ /// the parameters are set in the startup section of OpenSim.ini
+ ///
+ /// The output certificate file name.
+ /// The path of fullchain.pem. If your CA don't provide
+ /// the fullchain file, you can set the cert.pem instead.
+ /// The path of the private key (privkey.pem).
+ /// The output certificates password.
+ private static void ConvertPemToPKCS12Certificate(string certFileName, string certPath, string keyPath, string outputPassword)
+ {
+ if(string.IsNullOrEmpty(certPath) || string.IsNullOrEmpty(keyPath)){
+ m_log.ErrorFormat("[UTIL]: Missing or invalid fullchain.pem / privkey.pem path!.");
+ return;
+ }
+ // Create the SSL folder and sub folders if not exists.
+ if (!Directory.Exists("SSL\\ssl\\"))
+ Directory.CreateDirectory("SSL\\ssl\\");
+
+ // Convert .pem (like Let's Encrypt files) to X509Certificate2 certificate.
+ X509Certificate2 certificate = X509Certificate2.CreateFromPemFile(certPath, keyPath);
+
+ // Export and store the .pfx and .p12 certificates in SSL\ssl\.
+ byte[] pfxCertBytes = string.IsNullOrEmpty(outputPassword)
+ ? certificate.Export(X509ContentType.Pfx)
+ : certificate.Export(X509ContentType.Pfx, outputPassword);
+ File.WriteAllBytes($"SSL\\ssl\\{certFileName}.pfx", pfxCertBytes);
+
+ byte[] p12CertBytes = string.IsNullOrEmpty(outputPassword)
+ ? certificate.Export(X509ContentType.Pkcs12)
+ : certificate.Export(X509ContentType.Pkcs12, outputPassword);
+ File.WriteAllBytes($"SSL\\ssl\\{certFileName}.p12", p12CertBytes);
+
+ }
+
public static int fast_distance2d(int x, int y)
{
x = Math.Abs(x);
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 2971f61326..03c8fdd36f 100755
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -367,6 +367,16 @@ namespace OpenSim
);
}
}
+
+ if(startupConfig.GetBoolean("EnableCertConverter", false))
+ {
+ Util.ConvertPemToPKCS12(
+ string.IsNullOrEmpty(startupConfig.GetString("outputCertName")) ? "letsencrypt" : startupConfig.GetString("outputCertName"),
+ string.IsNullOrEmpty(startupConfig.GetString("PemCertPublicKey")) ? string.Empty : startupConfig.GetString("PemCertPublicKey"),
+ string.IsNullOrEmpty(startupConfig.GetString("PemCertPrivateKey")) ? string.Empty : startupConfig.GetString("PemCertPrivateKey"),
+ string.IsNullOrEmpty(startupConfig.GetString("outputCertPassword")) ? string.Empty : startupConfig.GetString("outputCertPassword")
+ );
+ }
if(m_networkServersInfo.HttpUsesSSL)
{
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 4f49f1f46d..3c2ff30b47 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -309,12 +309,37 @@
;; default is false
; TelehubAllowLandmark = false
+
+ ;; Let's Encrypt and others ".pem" certificates converter settings.
+ ;; Enabling this feature will automatically convert the CA .pem certificates to
+ ;; OpenSim compatible PKCS12 .p12 and .pfx certificates on every server startup.
+ ;; The resulting certificates are stored in the bin\SSL\ssl folder.
+ ;# {EnableCertConverter} {} {Enable pem to pkcs12 certificates converter} {true false} false
+ EnableCertConverter = false
+
+ ;; Set the absolute path of the "fullchain.pem". If your CA don't provide this file,
+ ;; you can use the "cert.pem" instead.
+ ;# {PemCertPublicKey} {} {Set the path of the public key .pem} {} ""
+ PemCertPublicKey = ""
+
+ ;; Set the absolute path of the pem private key "privkey.pem".
+ ;# {PemCertPrivateKey} {} {Set the path of the private key .pem} {} ""
+ PemCertPrivateKey = ""
+
+ ;; Set the name of the resulting .p12 and .pfx.
+ ;# {outputCertName} {} {Set the name of the resulting .p12 and .pfx} {} "letsencrypt"
+ outputCertName = "letsencrypt"
+
+ ;; Set the .p12 and .pfx password.
+ ;# {outputCertPassword} {} {Set the .p12 and .pfx password} {} ""
+ outputCertPassword = ""
+
;; SSL selfsigned certificate settings.
;; Enable selfsigned certificate creation for local and external use. When set to true, will create a folder SSL\ and 2 sub folders SSL\ssl\ and SSL\src\.
;; Next creates and store an RSA private key in SSL\src\ and the derived selfsigned certificate in SSL\ssl\ folder.
;;Is also possible to renew the certificate on every server restart if CertRenewOnStartup is set to true.
- ;# {EnbleSelfsignedCertSupport} {} {Enable selfsigned certificate creation and renew} {true false} false
+ ;# {EnableSelfsignedCertSupport} {} {Enable selfsigned certificate creation and renew} {true false} false
EnableSelfsignedCertSupport = false
;; Renew the selfsigned certificate on every server startup ?
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 57c20cd414..3da8fe1dd6 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -399,6 +399,33 @@
; routing and land at the landmark coordinates when set to true
; default is false
; TelehubAllowLandmark = false
+
+ ; #
+ ; # Let's Encrypt and others ".pem" certificates converter settings.
+ ; #
+
+ ;; Enabling this feature will automatically convert the CA .pem certificates to
+ ;; OpenSim compatible PKCS12 .p12 and .pfx certificates on every server startup.
+ ;; The resulting certificates are stored in the bin\SSL\ssl folder.
+ ;# {EnableCertConverter} {} {Enable pem to pkcs12 certificates converter} {true false} false
+ EnableCertConverter = false
+
+ ;; Set the absolute path of the "fullchain.pem". If your CA don't provide this file,
+ ;; you can use the "cert.pem" instead.
+ ;# {PemCertPublicKey} {} {Set the path of the public key .pem} {} ""
+ PemCertPublicKey = ""
+
+ ;; Set the absolute path of the pem private key "privkey.pem".
+ ;# {PemCertPrivateKey} {} {Set the path of the private key .pem} {} ""
+ PemCertPrivateKey = ""
+
+ ;; Set the name of the resulting .p12 and .pfx.
+ ;# {outputCertName} {} {Set the name of the resulting .p12 and .pfx} {} "letsencrypt"
+ outputCertName = "letsencrypt"
+
+ ;; Set the .p12 and .pfx password.
+ ;# {outputCertPassword} {} {Set the .p12 and .pfx password} {} ""
+ outputCertPassword = ""
; #
; # SSL selfsigned certificate settings.