From c90bd11389820e9f10a2b91514fc620be62e116b Mon Sep 17 00:00:00 2001 From: sgrampone Date: Fri, 2 Aug 2024 12:02:03 -0300 Subject: [PATCH 01/16] GAM Cryptography EO migration from SVN to GamUtils EO on Github --- dotnet/DotNetStandardClasses.sln | 35 +++ .../DotNetFramework/GamUtils/GamUtils.csproj | 25 ++ .../DotNetFramework/GamUtils/GamUtilsEO.cs | 50 ++++ .../GamUtils/Properties/AssemblyInfo.cs | 8 + .../GamUtils/Utils/CertificateExt.cs | 174 ++++++++++++++ .../DotNetFramework/GamUtils/Utils/Hash.cs | 34 +++ .../src/DotNetFramework/GamUtils/Utils/Jwk.cs | 199 ++++++++++++++++ .../DotNetFramework/GamUtils/Utils/Jwks.cs | 51 ++++ .../src/DotNetFramework/GamUtils/Utils/Jwt.cs | 74 ++++++ .../DotNetFramework/GamUtils/Utils/Random.cs | 51 ++++ .../DotNetFramework/GamTest/GamTest.csproj | 54 +++++ .../GamTest/Properties/AssemblyInfo.cs | 0 .../RSA_sha256_2048/sha256_cert.cer | Bin 0 -> 1029 bytes .../RSA_sha256_2048/sha256_cert.crt | Bin 0 -> 1029 bytes .../RSA_sha256_2048/sha256_cert.key | 24 ++ .../RSA_sha256_2048/sha256_cert.p12 | Bin 0 -> 2629 bytes .../RSA_sha256_2048/sha256_cert.pem | 24 ++ .../RSA_sha256_2048/sha256_cert.pkcs12 | Bin 0 -> 2629 bytes .../RSA_sha256_2048/sha256d_key.pem | 27 +++ .../Utils/Resources/CryptographicHash.cs | 46 ++++ .../GamTest/Utils/TestCertificate.cs | 95 ++++++++ .../DotNetFramework/GamTest/Utils/TestHash.cs | 51 ++++ .../DotNetFramework/GamTest/Utils/TestJwk.cs | 87 +++++++ .../DotNetFramework/GamTest/Utils/TestJwks.cs | 45 ++++ .../DotNetFramework/GamTest/Utils/TestJwt.cs | 223 ++++++++++++++++++ .../GamTest/Utils/TestRandom.cs | 60 +++++ 26 files changed, 1437 insertions(+) create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Properties/AssemblyInfo.cs create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/CertificateExt.cs create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Hash.cs create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwk.cs create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwks.cs create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwt.cs create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Random.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/GamTest.csproj create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Properties/AssemblyInfo.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256_cert.cer create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256_cert.crt create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256_cert.key create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256_cert.p12 create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256_cert.pem create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256_cert.pkcs12 create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256d_key.pem create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/Resources/CryptographicHash.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestHash.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwk.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwks.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwt.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestRandom.cs diff --git a/dotnet/DotNetStandardClasses.sln b/dotnet/DotNetStandardClasses.sln index 01e391f0b..9c981c447 100644 --- a/dotnet/DotNetStandardClasses.sln +++ b/dotnet/DotNetStandardClasses.sln @@ -263,6 +263,24 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LogTest", "test\benchmarks\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AccessTokenController_Test", "test\NativeAccessControllerTest\AccessTokenController_Test.csproj", "{A5589382-DB6F-4450-AE2B-6C6AA1643EF1}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gam", "gam", "{BAD7F078-C67E-484A-AF74-EC29F163F1F7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7465132B-47BD-44D1-8193-483465FD94F4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{035C3DAF-553E-4E64-BA9E-113F5C80FD97}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotNet", "DotNet", "{56429994-8A51-48AB-8105-737B77840D18}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotNetFramework", "DotNetFramework", "{B3B988A2-AFF1-41E6-82DC-578D332A5CB8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GamUtils", "src\extensions\gam\src\DotNetFramework\GamUtils\GamUtils.csproj", "{34FE57F2-E45F-4F9B-AFEE-60D9CA8373A7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotNet", "DotNet", "{1942B0FE-49BD-4EC4-9788-F19FDD921E69}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotNetFramework", "DotNetFramework", "{B33F3709-5EA0-4FE8-9E3A-50D3046817D6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GamTest", "src\extensions\gam\test\DotNetFramework\GamTest\GamTest.csproj", "{52B67EA3-B17D-4002-8EC3-0D5DDB62988B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -641,6 +659,14 @@ Global {A5589382-DB6F-4450-AE2B-6C6AA1643EF1}.Debug|Any CPU.Build.0 = Debug|Any CPU {A5589382-DB6F-4450-AE2B-6C6AA1643EF1}.Release|Any CPU.ActiveCfg = Release|Any CPU {A5589382-DB6F-4450-AE2B-6C6AA1643EF1}.Release|Any CPU.Build.0 = Release|Any CPU + {34FE57F2-E45F-4F9B-AFEE-60D9CA8373A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {34FE57F2-E45F-4F9B-AFEE-60D9CA8373A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {34FE57F2-E45F-4F9B-AFEE-60D9CA8373A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {34FE57F2-E45F-4F9B-AFEE-60D9CA8373A7}.Release|Any CPU.Build.0 = Release|Any CPU + {52B67EA3-B17D-4002-8EC3-0D5DDB62988B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52B67EA3-B17D-4002-8EC3-0D5DDB62988B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52B67EA3-B17D-4002-8EC3-0D5DDB62988B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52B67EA3-B17D-4002-8EC3-0D5DDB62988B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -767,6 +793,15 @@ Global {46DAAFD1-FAF5-4904-8EC5-406BE04E5538} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} {A1DBDCE0-4F09-445F-A202-9B260CDD46CF} = {46DAAFD1-FAF5-4904-8EC5-406BE04E5538} {A5589382-DB6F-4450-AE2B-6C6AA1643EF1} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} + {BAD7F078-C67E-484A-AF74-EC29F163F1F7} = {C6AFB6A3-FF0B-4970-B1F1-10BCD3D932B2} + {7465132B-47BD-44D1-8193-483465FD94F4} = {BAD7F078-C67E-484A-AF74-EC29F163F1F7} + {035C3DAF-553E-4E64-BA9E-113F5C80FD97} = {BAD7F078-C67E-484A-AF74-EC29F163F1F7} + {56429994-8A51-48AB-8105-737B77840D18} = {7465132B-47BD-44D1-8193-483465FD94F4} + {B3B988A2-AFF1-41E6-82DC-578D332A5CB8} = {7465132B-47BD-44D1-8193-483465FD94F4} + {34FE57F2-E45F-4F9B-AFEE-60D9CA8373A7} = {B3B988A2-AFF1-41E6-82DC-578D332A5CB8} + {1942B0FE-49BD-4EC4-9788-F19FDD921E69} = {035C3DAF-553E-4E64-BA9E-113F5C80FD97} + {B33F3709-5EA0-4FE8-9E3A-50D3046817D6} = {035C3DAF-553E-4E64-BA9E-113F5C80FD97} + {52B67EA3-B17D-4002-8EC3-0D5DDB62988B} = {B33F3709-5EA0-4FE8-9E3A-50D3046817D6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E18684C9-7D76-45CD-BF24-E3944B7F174C} diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj new file mode 100644 index 000000000..aced046db --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj @@ -0,0 +1,25 @@ + + + net47 + GamUtilsImpl + CA1031, CA1801 + Genexus.Gam.Utils + + + True + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs new file mode 100644 index 000000000..d3a910251 --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs @@ -0,0 +1,50 @@ +using System; +using System.Security; +using GamUtils.Utils; + +namespace GamUtils +{ + [SecuritySafeCritical] + public class GamUtilsEO + { + /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + //**HASH**// + [SecuritySafeCritical] + public static string Sha512(String plainText) + { + return Hash.Sha512(plainText); + } + + //**RANDOM**// + [SecuritySafeCritical] + public static string RandomAlphanumeric(int length) + { + return Utils.Random.RandomAlphanumeric(length); + } + + [SecuritySafeCritical] + public static string RandomNumeric(int length) + { + return Utils.Random.RandomNumeric(length); + } + + + //**JWK**// + [SecuritySafeCritical] + public static string GenerateKeyPair() { return Jwk.GenerateKeyPair(); } + + public static string GetPublicJwk(string jwkString) { return Jwk.GetPublic(jwkString); } + + public static string Jwk_createJwt(string jwkString, string payload, string header) { return Jwk.CreateJwt(jwkString, payload, header); } + + public static bool Jwk_verifyJWT(string jwkString, string token) { return Jwk.VerifyJWT(jwkString, token); } + + //**JWKS**// + + public static bool Jwks_verifyJWT(string jwksString, string token, string kid) { return Jwks.VerifyJWT(jwksString, token, kid); } + + //**JWT**// + public static bool VerifyJWTWithFile(string path, string alias, string password, string token) { return Jwt.Verify(path, alias, password, token); } + } +} diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Properties/AssemblyInfo.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..0753e0690 --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Properties/AssemblyInfo.cs @@ -0,0 +1,8 @@ +using System.Security; +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("GamTest")] +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AllowPartiallyTrustedCallers] \ No newline at end of file diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/CertificateExt.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/CertificateExt.cs new file mode 100644 index 000000000..dc05c3793 --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/CertificateExt.cs @@ -0,0 +1,174 @@ +using System; +using System.IO; +using System.Security; +using log4net; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.OpenSsl; +using Org.BouncyCastle.Pkcs; +using Microsoft.IdentityModel.Tokens; +using Org.BouncyCastle.Security; +using System.Security.Cryptography.X509Certificates; +using System.Security.Cryptography; + +namespace GamUtils.Utils +{ + [SecuritySafeCritical] + internal enum CertificateExt + { + NONE, crt, cer, pfx, jks, pkcs12, p12, pem, key + } + + + [SecuritySafeCritical] + internal static class CertificateUtil + { + private static readonly ILog logger = LogManager.GetLogger(typeof(CertificateUtil)); + public static CertificateExt Value(string ext) + { + switch (ext.ToLower().Trim()) + { + case "crt": + return CertificateExt.crt; + case "cer": + return CertificateExt.cer; + case "pfx": + return CertificateExt.pfx; + case "jks": + return CertificateExt.jks; + case "pkcs12": + return CertificateExt.pkcs12; + case "p12": + return CertificateExt.p12; + case "pem": + return CertificateExt.pem; + case "key": + return CertificateExt.key; + default: + logger.Error("Invalid certificate file extension"); + return CertificateExt.NONE; + } + } + + public static RSAParameters GetCertificate(string path, string alias, string password) + { + CertificateExt ext = CertificateUtil.Value(Path.GetExtension(path).Replace(".", String.Empty).Trim()); + if (ext == CertificateExt.NONE) + { + logger.Error("Error reading certificate path"); + return new RSAParameters(); + } + switch (ext) + { + case CertificateExt.crt: + case CertificateExt.cer: + return GetPublicRSAParameters(LoadFromDer(path)); + case CertificateExt.pfx: + case CertificateExt.jks: + case CertificateExt.pkcs12: + case CertificateExt.p12: + return GetPublicRSAParameters(LoadFromPkcs12(path, alias, password)); + case CertificateExt.pem: + case CertificateExt.key: + return GetPublicRSAParameters(LoadFromPkcs8(path)); + default: + logger.Error("Invalid certificate file extension"); + return new RSAParameters(); + } + } + + private static RSAParameters GetPublicRSAParameters(Org.BouncyCastle.X509.X509Certificate cert) + { + X509Certificate2 cert2 = new X509Certificate2(DotNetUtilities.ToX509Certificate(cert)); + return cert2.GetRSAPublicKey().ExportParameters(false); + } + + private static Org.BouncyCastle.X509.X509Certificate LoadFromPkcs12(string path, string alias, string password) + { + logger.Debug("Loading pkcs12 certificate"); + if (password.IsNullOrEmpty()) + { + logger.Error("LoadFromPkcs12: password is null or empty"); + return null; + } + + try + { + Pkcs12Store pkcs12 = new Pkcs12StoreBuilder().Build(); + using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) + { + pkcs12.Load(fs, password.ToCharArray()); + foreach (string n in pkcs12.Aliases) + { + if (pkcs12.IsKeyEntry(n)) + { + return pkcs12.GetCertificate(n).Certificate; + } + } + } + + + } + + catch (Exception e) + { + logger.Error("LoadFromPkcs12", e); + return null; + } + logger.Error("LoadFromPkcs12: path not found"); + return null; + + } + private static Org.BouncyCastle.X509.X509Certificate LoadFromPkcs8(string path) + { + logger.Debug("Loading pkcs8 certificate"); + using (StreamReader streamReader = new StreamReader(path)) + { + PemReader pemReader = null; + try + { + pemReader = new PemReader(streamReader); + Object obj = pemReader.ReadObject(); + + if (obj.GetType() == typeof(System.Security.Cryptography.X509Certificates.X509Certificate) || obj.GetType() == typeof(Org.BouncyCastle.X509.X509Certificate) || obj.GetType() == typeof(X509CertificateStructure)) + { + return (Org.BouncyCastle.X509.X509Certificate)obj; + } + else + { + logger.Error("Unknown certificate type: " + obj.GetType().FullName); + return null; + } + } + catch (Exception e) + { + logger.Error("LoadFromPkcs8", e); + return null; + } + finally + { + pemReader.Reader.Close(); + } + } + } + + private static Org.BouncyCastle.X509.X509Certificate LoadFromDer(string path) + { + logger.Debug("Loading der certificate"); + try + { + using (FileStream fs = new FileStream(path, FileMode.Open)) + { + X509CertificateParser parser = new X509CertificateParser(); + return parser.ReadCertificate(fs); + } + + } + catch (Exception e) + { + logger.Error("LoadFromDer", e); + return null; + } + } + } +} diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Hash.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Hash.cs new file mode 100644 index 000000000..966134ce9 --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Hash.cs @@ -0,0 +1,34 @@ +using System; +using System.Text; +using log4net; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities.Encoders; +using System.Security; + +namespace GamUtils.Utils +{ + [SecuritySafeCritical] + public class Hash + { + + private static readonly ILog logger = LogManager.GetLogger(typeof(Hash)); + + [SecuritySafeCritical] + internal static string Sha512(string plainText) + { + + if (String.IsNullOrEmpty(plainText)) + { + logger.Error("sha512 plainText is empty"); + return ""; + } + byte[] inputBytes = Encoding.UTF8.GetBytes(plainText); + IDigest alg = new Sha512Digest(); + byte[] retValue = new byte[alg.GetDigestSize()]; + alg.BlockUpdate(inputBytes, 0, inputBytes.Length); + alg.DoFinal(retValue, 0); + return Base64.ToBase64String(retValue); + } + } +} diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwk.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwk.cs new file mode 100644 index 000000000..87aeb1ec0 --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwk.cs @@ -0,0 +1,199 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Security; +using Jose; +using log4net; +using Newtonsoft.Json; +using Microsoft.IdentityModel.Tokens; + +namespace GamUtils.Utils +{ + [SecuritySafeCritical] + public class Jwk + { + private static readonly ILog logger = LogManager.GetLogger(typeof(Jwk)); + + /******** EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + [SecuritySafeCritical] + internal static string GenerateKeyPair() + { + Jose.Jwk jwk = CreateJwk(); + if (jwk == null) { return ""; } + return jwk.ToJson(); + } + + + [SecuritySafeCritical] + internal static string GetPublic(string jwkString) + { + if (String.IsNullOrEmpty(jwkString)) + { + logger.Error("GetPublicJwk jwkString parameter is empty"); + return ""; + } + else + { + logger.Debug("GetPublicJwk jwkString parameter: " + jwkString); + } + try + { + Jose.Jwk jwk = Jose.Jwk.FromJson(jwkString); + var dict = new Dictionary + { + ["kty"] = jwk.Kty, + ["e"] = jwk.E, + ["use"] = jwk.Use, + ["kid"] = jwk.KeyId, + ["alg"] = jwk.Alg, + ["n"] = jwk.N, + }; + + return JsonConvert.SerializeObject(dict); + } + catch (Exception e) + { + logger.Error("GetPublicJwk", e); + return ""; + } + } + + [SecuritySafeCritical] + public static string CreateJwt(string jwkString, string payload, string header) + { + if (jwkString.IsNullOrEmpty()) + { + logger.Error("createJwt jwkString parameter is empty"); + return ""; + } + if (payload.IsNullOrEmpty()) + { + logger.Error("createJwt payload parameter is empty"); + return ""; + } + if (header.IsNullOrEmpty()) + { + logger.Error("createJwt header parameter is empty"); + return ""; + } + try + { + return Jwt.Create(GetPrivateKey(jwkString), payload, header); + } + catch (Exception e) + { + logger.Error("createJwt", e); + return ""; + } + } + + [SecuritySafeCritical] + public static bool VerifyJWT(string jwkString, string token) + { + if (jwkString.IsNullOrEmpty()) + { + logger.Error("verifyJWT jwkString parameter is empty"); + return false; + } + if (token.IsNullOrEmpty()) + { + logger.Error("verifyJWT token parameter is empty"); + return false; + } + try + { + return Jwt.Verify(GetPublicKey(jwkString), token); + } + catch (Exception e) + { + logger.Error("verifyJWT", e); + return false; + } + + } + + /******** EXTERNAL OBJECT PUBLIC METHODS - END ********/ + + [SecuritySafeCritical] + private static Jose.Jwk CreateJwk() + { + try + { + RSA key = Create(2048); + + RSAParameters parameters = key.ExportParameters(true); + Jose.Jwk jwk = new Jose.Jwk + { + Kty = "RSA", + Alg = "RS256", + Use = "sig", + KeyId = Guid.NewGuid().ToString(), + N = Convert.ToBase64String(parameters.Modulus), + E = Convert.ToBase64String(parameters.Exponent), + P = Convert.ToBase64String(parameters.P), + Q = Convert.ToBase64String(parameters.Q), + DP = Convert.ToBase64String(parameters.DP), + DQ = Convert.ToBase64String(parameters.DQ), + QI = Convert.ToBase64String(parameters.InverseQ), + D = Convert.ToBase64String(parameters.D) + }; + + return jwk; + + } + catch (Exception e) + { + logger.Error("CreateJwk", e); + return null; + } + } + + [SecuritySafeCritical] + private static RSA Create(int keySizeInBits) + { +#if NETCORE + RSA rSA = RSA.Create(); +#else + RSA rSA = (RSA)CryptoConfig.CreateFromName("RSAPSS"); +#endif + rSA.KeySize = keySizeInBits; + if (rSA.KeySize != keySizeInBits) + { + throw new CryptographicException(); + } + + return rSA; + } + + private static RSAParameters GetPrivateKey(string jwkString) + { + Jose.Jwk jwk = Jose.Jwk.FromJson(jwkString); + + RSAParameters privateKey = new RSAParameters(); + + privateKey.Exponent = Base64Url.Decode(jwk.E); + privateKey.Modulus = Base64Url.Decode(jwk.N); + privateKey.D = Base64Url.Decode(jwk.D); + privateKey.DP = Base64Url.Decode(jwk.DP); + privateKey.DQ = Base64Url.Decode(jwk.DQ); + privateKey.P = Base64Url.Decode(jwk.P); + privateKey.Q = Base64Url.Decode(jwk.Q); + privateKey.InverseQ = Base64Url.Decode(jwk.QI); + + return privateKey; + } + + internal static RSAParameters GetPublicKey(string jwkString) + { + Jose.Jwk jwk = Jose.Jwk.FromJson(jwkString); + + RSAParameters publicKey = new RSAParameters(); + + publicKey.Exponent = Base64Url.Decode(jwk.E); + publicKey.Modulus = Base64Url.Decode(jwk.N); + + return publicKey; + } + } +} diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwks.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwks.cs new file mode 100644 index 000000000..75dc4ce18 --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwks.cs @@ -0,0 +1,51 @@ +using System; +using System.Security; +using Jose; +using Microsoft.IdentityModel.Tokens; +using log4net; +namespace GamUtils.Utils +{ + [SecuritySafeCritical] + public class Jwks + { + private static readonly ILog logger = LogManager.GetLogger(typeof(Jwks)); + + [SecuritySafeCritical] + internal static bool VerifyJWT(string jwksString, string token, string kid) + { + if (jwksString.IsNullOrEmpty()) + { + logger.Error("verifyJWT jwksString parameter is empty"); + return false; + } + if (token.IsNullOrEmpty()) + { + logger.Error("verifyJWT token parameter is empty"); + return false; + } + if (kid.IsNullOrEmpty()) + { + logger.Error("verifyJWT kid parameter is empty"); + return false; + } + try + { + JwkSet set = JwkSet.FromJson(jwksString); + foreach (Jose.Jwk jwk in set) + { + if (jwk.KeyId.Equals(kid)) + { + return Jwt.Verify(Jwk.GetPublicKey(jwk.ToJson()), token); + } + } + logger.Error("Could not find indicated kid"); + return false; + } + catch (Exception e) + { + logger.Error("verifyJWT", e); + return false; + } + } + } +} diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwt.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwt.cs new file mode 100644 index 000000000..316c430c4 --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwt.cs @@ -0,0 +1,74 @@ +using System; +using System.IdentityModel.Tokens.Jwt; +using System.Security; +using System.Security.Cryptography; +using Jose; +using log4net; +using Microsoft.IdentityModel.Tokens; + +namespace GamUtils.Utils +{ + [SecuritySafeCritical] + public class Jwt + { + private static readonly ILog logger = LogManager.GetLogger(typeof(Jwt)); + + /******** EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + [SecuritySafeCritical] + public static bool Verify(string path, string alias, string password, string token) + { + return Verify(CertificateUtil.GetCertificate(path, alias, password), token); + } + + /******** EXTERNAL OBJECT PUBLIC METHODS - END ********/ + + [SecuritySafeCritical] + public static bool Verify(RSAParameters publicKey, string token) + { + try + { + using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) + { + rsa.ImportParameters(publicKey); + string payload = JWT.Decode(token, rsa, JwsAlgorithm.RS256); + return payload.IsNullOrEmpty() ? false : true; + } + } + catch (Exception e) + { + logger.Error("verify", e); + return false; + } + } + + + [SecuritySafeCritical] + public static string Create(RSAParameters privateKey, string payload, string header) + { + try + { + using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) + { + rsa.ImportParameters(privateKey); + + return JWT.Encode( + payload: payload, + key: rsa, + algorithm: JwsAlgorithm.RS256, + extraHeaders: JwtHeader.Deserialize(header), + options: new JwtOptions { DetachPayload = false, EncodePayload = true } + ); + } + + } + catch (Exception e) + { + logger.Error("create", e); + return ""; + } + } + + + } +} diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Random.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Random.cs new file mode 100644 index 000000000..bf2d8427f --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Random.cs @@ -0,0 +1,51 @@ +using System; +using System.Security; +using System.Security.Cryptography; +using System.Text; + +namespace GamUtils.Utils +{ + [SecuritySafeCritical] + public class Random + { + internal static string RandomNumeric(int length) + { + string s = ""; + byte[] buffer = new byte[sizeof(uint)]; + using (var rng = RandomNumberGenerator.Create()) + { + + + for (int i = 0; i <= length / 10; i++) + { + rng.GetBytes(buffer); + s += BitConverter.ToUInt32(buffer, 0).ToString(); + } + } + return s.Length >= length ? s.Substring(0, length) : RandomNumeric(length); + } + + [SecuritySafeCritical] + internal static string RandomAlphanumeric(int length) + { + + + char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray(); + byte[] data = new byte[length]; +#if NETCORE + var arraySpan = new Span(data); + System.Security.Cryptography.RandomNumberGenerator.Fill(arraySpan); +#else + RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider(); + crypto.GetBytes(data); +#endif + StringBuilder result = new StringBuilder(length); + foreach (byte b in data) + { + result.Append(chars[b % (chars.Length)]); + } + return result.ToString(); + } + + } +} diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/GamTest.csproj b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/GamTest.csproj new file mode 100644 index 000000000..cf4333cc6 --- /dev/null +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/GamTest.csproj @@ -0,0 +1,54 @@ + + + net471 + false + GamTest + GamTest + CS0618,CA1707 + false + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + \ No newline at end of file diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Properties/AssemblyInfo.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..e69de29bb diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256_cert.cer b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256_cert.cer new file mode 100644 index 0000000000000000000000000000000000000000..bd788b5de7701ce8e1ec5cba0657b3f339fdfdae GIT binary patch literal 1029 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 lO;dbq8Y1H8pEyk_kNS0ynw}bu1yKN4 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 lO;dbq8Y1H8pEyk_ Date: Fri, 2 Aug 2024 15:29:56 -0300 Subject: [PATCH 02/16] Ignore pfx test --- .../gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs index 720a68aed..db84d29ab 100644 --- a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs @@ -58,6 +58,7 @@ public void TestLoadCer() } [Test] + [Ignore("issues with pfx extension in .Net")] public void TestLoadPfx() { bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.pfx", "", password, tokenFile); From 270bb102d7020ee73d8d01594f354f79f85ca35b Mon Sep 17 00:00:00 2001 From: sgrampone Date: Fri, 2 Aug 2024 17:36:10 -0300 Subject: [PATCH 03/16] Fix AssemblyInfo VisibleTo property --- .../src/DotNetFramework/GamUtils/Properties/AssemblyInfo.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Properties/AssemblyInfo.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Properties/AssemblyInfo.cs index 0753e0690..19c0cf3b9 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Properties/AssemblyInfo.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Properties/AssemblyInfo.cs @@ -1,7 +1,4 @@ using System.Security; -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("GamTest")] // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. From c8a7a4ac9bb6968511cf4fe9fba19ee3c80fc2da Mon Sep 17 00:00:00 2001 From: sgrampone Date: Wed, 7 Aug 2024 13:48:07 -0300 Subject: [PATCH 04/16] New features + tests and refactoring --- .../DotNetFramework/GamUtils/GamUtilsEO.cs | 30 ++- .../GamUtils/Utils/Cryprography/Encryption.cs | 46 ++++ .../GamUtils/Utils/{ => Cryprography}/Hash.cs | 0 .../GamUtils/Utils/{ => Json}/Jwk.cs | 8 +- .../GamUtils/Utils/{ => Json}/Jwks.cs | 2 +- .../GamUtils/Utils/{ => Json}/Jwt.cs | 24 +- .../Utils/{ => Keys}/CertificateExt.cs | 51 ++-- .../GamUtils/Utils/Keys/PrivateKeyExt.cs | 223 ++++++++++++++++++ .../DotNetFramework/GamUtils/Utils/Random.cs | 27 ++- .../RSA_sha256_2048/sha256d_key.key | 27 +++ .../GamTest/Utils/TestCertificate.cs | 8 + .../GamTest/Utils/TestEncryption.cs | 23 ++ .../GamTest/Utils/TestPrivateKey.cs | 91 +++++++ .../GamTest/Utils/TestRandom.cs | 12 + 14 files changed, 543 insertions(+), 29 deletions(-) create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Encryption.cs rename dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/{ => Cryprography}/Hash.cs (100%) rename dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/{ => Json}/Jwk.cs (95%) rename dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/{ => Json}/Jwks.cs (93%) rename dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/{ => Json}/Jwt.cs (73%) rename dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/{ => Keys}/CertificateExt.cs (74%) create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256d_key.key create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestEncryption.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestPrivateKey.cs diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs index d3a910251..97fa3a2c4 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs @@ -1,6 +1,7 @@ -using System; using System.Security; using GamUtils.Utils; +using GamUtils.Utils.Cryprography; +using GamUtils.Utils.Json; namespace GamUtils { @@ -11,40 +12,61 @@ public class GamUtilsEO //**HASH**// [SecuritySafeCritical] - public static string Sha512(String plainText) + public static string Sha512(string plainText) { return Hash.Sha512(plainText); } + //**ENCRYPTION**// + + [SecuritySafeCritical] + public static string AesGcm(string input, string key, string nonce, int macSize, bool toEncrypt) + { + return Encryption.AesGcm(input, key, nonce, macSize, toEncrypt); + } + //**RANDOM**// [SecuritySafeCritical] public static string RandomAlphanumeric(int length) { - return Utils.Random.RandomAlphanumeric(length); + return Utils.Random.Alphanumeric(length); } [SecuritySafeCritical] public static string RandomNumeric(int length) { - return Utils.Random.RandomNumeric(length); + return Utils.Random.Numeric(length); } + [SecuritySafeCritical] + public static string RandomHexaBits(int bits) + { + return Utils.Random.HexaBits(bits); + } //**JWK**// [SecuritySafeCritical] public static string GenerateKeyPair() { return Jwk.GenerateKeyPair(); } + [SecuritySafeCritical] public static string GetPublicJwk(string jwkString) { return Jwk.GetPublic(jwkString); } + [SecuritySafeCritical] public static string Jwk_createJwt(string jwkString, string payload, string header) { return Jwk.CreateJwt(jwkString, payload, header); } + [SecuritySafeCritical] public static bool Jwk_verifyJWT(string jwkString, string token) { return Jwk.VerifyJWT(jwkString, token); } //**JWKS**// + [SecuritySafeCritical] public static bool Jwks_verifyJWT(string jwksString, string token, string kid) { return Jwks.VerifyJWT(jwksString, token, kid); } //**JWT**// + [SecuritySafeCritical] public static bool VerifyJWTWithFile(string path, string alias, string password, string token) { return Jwt.Verify(path, alias, password, token); } + + [SecuritySafeCritical] + public static string CreateJWTWithFile(string path, string alias, string password, string payload, string header) { return Jwt.Create(path, alias, password, payload, header); } } } diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Encryption.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Encryption.cs new file mode 100644 index 000000000..7e2dd0336 --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Encryption.cs @@ -0,0 +1,46 @@ +using System; +using System.Security; +using System.Text; +using log4net; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities.Encoders; + +namespace GamUtils.Utils.Cryprography +{ + [SecuritySafeCritical] + internal class Encryption + { + + private static readonly ILog logger = LogManager.GetLogger(typeof(Encryption)); + + [SecuritySafeCritical] + public static string AesGcm(string input, string key, string nonce, int macSize, bool toEncrypt) + { + return toEncrypt ? Base64.ToBase64String(Internal_AesGcm(Encoding.UTF8.GetBytes(input), key, nonce, macSize, toEncrypt)) : Encoding.UTF8.GetString(Internal_AesGcm(Base64.Decode(input), key, nonce, macSize, toEncrypt)); + } + + [SecuritySafeCritical] + private static byte[] Internal_AesGcm(byte[] inputBytes, string key, string nonce, int macSize, bool toEncrypt) + { + logger.Debug("Internal_AesGcm"); + + IAeadBlockCipher cipher = new GcmBlockCipher(new AesEngine()); + AeadParameters AEADparams = new AeadParameters(new KeyParameter(Hex.Decode(key)), macSize, Hex.Decode(nonce)); + try + { + cipher.Init(toEncrypt, AEADparams); + byte[] outputBytes = new byte[cipher.GetOutputSize(inputBytes.Length)]; + int length = cipher.ProcessBytes(inputBytes, 0, inputBytes.Length, outputBytes, 0); + cipher.DoFinal(outputBytes, length); + return outputBytes; + } + catch (Exception e) + { + logger.Error("Internal_AesGcm", e); + return null; + } + } + } +} diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Hash.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Hash.cs similarity index 100% rename from dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Hash.cs rename to dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Hash.cs diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwk.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwk.cs similarity index 95% rename from dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwk.cs rename to dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwk.cs index 87aeb1ec0..7d830efe5 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwk.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwk.cs @@ -7,7 +7,7 @@ using Newtonsoft.Json; using Microsoft.IdentityModel.Tokens; -namespace GamUtils.Utils +namespace GamUtils.Utils.Json { [SecuritySafeCritical] public class Jwk @@ -28,7 +28,7 @@ internal static string GenerateKeyPair() [SecuritySafeCritical] internal static string GetPublic(string jwkString) { - if (String.IsNullOrEmpty(jwkString)) + if (string.IsNullOrEmpty(jwkString)) { logger.Error("GetPublicJwk jwkString parameter is empty"); return ""; @@ -60,7 +60,7 @@ internal static string GetPublic(string jwkString) } [SecuritySafeCritical] - public static string CreateJwt(string jwkString, string payload, string header) + internal static string CreateJwt(string jwkString, string payload, string header) { if (jwkString.IsNullOrEmpty()) { @@ -89,7 +89,7 @@ public static string CreateJwt(string jwkString, string payload, string header) } [SecuritySafeCritical] - public static bool VerifyJWT(string jwkString, string token) + internal static bool VerifyJWT(string jwkString, string token) { if (jwkString.IsNullOrEmpty()) { diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwks.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwks.cs similarity index 93% rename from dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwks.cs rename to dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwks.cs index 75dc4ce18..555a889c7 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwks.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwks.cs @@ -35,7 +35,7 @@ internal static bool VerifyJWT(string jwksString, string token, string kid) { if (jwk.KeyId.Equals(kid)) { - return Jwt.Verify(Jwk.GetPublicKey(jwk.ToJson()), token); + return Jwt.Verify(Json.Jwk.GetPublicKey(jwk.ToJson()), token); } } logger.Error("Could not find indicated kid"); diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwt.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwt.cs similarity index 73% rename from dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwt.cs rename to dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwt.cs index 316c430c4..cfe6171bf 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Jwt.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwt.cs @@ -2,6 +2,7 @@ using System.IdentityModel.Tokens.Jwt; using System.Security; using System.Security.Cryptography; +using GamUtils.Utils.Keys; using Jose; using log4net; using Microsoft.IdentityModel.Tokens; @@ -21,23 +22,44 @@ public static bool Verify(string path, string alias, string password, string tok return Verify(CertificateUtil.GetCertificate(path, alias, password), token); } + [SecuritySafeCritical] + public static string Create(string path, string alias, string password, string payload, string header) + { + return Create(PrivateKeyUtil.GetPrivateKey(path, alias, password), payload, header); + } + /******** EXTERNAL OBJECT PUBLIC METHODS - END ********/ [SecuritySafeCritical] public static bool Verify(RSAParameters publicKey, string token) { + + Console.WriteLine("token: " + token); + try { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { rsa.ImportParameters(publicKey); string payload = JWT.Decode(token, rsa, JwsAlgorithm.RS256); - return payload.IsNullOrEmpty() ? false : true; + + if(payload.IsNullOrEmpty()) + { + Console.WriteLine("payload null or empty"); + return false; + } + else + { + return true; + } + //return payload.IsNullOrEmpty() ? false : true; } } catch (Exception e) { logger.Error("verify", e); + Console.WriteLine("error verify"); + Console.WriteLine(e.Message); return false; } } diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/CertificateExt.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/CertificateExt.cs similarity index 74% rename from dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/CertificateExt.cs rename to dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/CertificateExt.cs index dc05c3793..b8d9e7569 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/CertificateExt.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/CertificateExt.cs @@ -10,13 +10,14 @@ using Org.BouncyCastle.Security; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography; +using Org.BouncyCastle.Utilities.Encoders; -namespace GamUtils.Utils +namespace GamUtils.Utils.Keys { [SecuritySafeCritical] internal enum CertificateExt { - NONE, crt, cer, pfx, jks, pkcs12, p12, pem, key + NONE, crt, cer, pfx, pkcs12, p12, pem, key, b64 } @@ -24,7 +25,9 @@ internal enum CertificateExt internal static class CertificateUtil { private static readonly ILog logger = LogManager.GetLogger(typeof(CertificateUtil)); - public static CertificateExt Value(string ext) + + [SecuritySafeCritical] + internal static CertificateExt Value(string ext) { switch (ext.ToLower().Trim()) { @@ -34,8 +37,6 @@ public static CertificateExt Value(string ext) return CertificateExt.cer; case "pfx": return CertificateExt.pfx; - case "jks": - return CertificateExt.jks; case "pkcs12": return CertificateExt.pkcs12; case "p12": @@ -44,43 +45,61 @@ public static CertificateExt Value(string ext) return CertificateExt.pem; case "key": return CertificateExt.key; + case "b64": + return CertificateExt.b64; default: logger.Error("Invalid certificate file extension"); return CertificateExt.NONE; } } - public static RSAParameters GetCertificate(string path, string alias, string password) + [SecuritySafeCritical] + internal static RSAParameters GetCertificate(string path, string alias, string password) { - CertificateExt ext = CertificateUtil.Value(Path.GetExtension(path).Replace(".", String.Empty).Trim()); - if (ext == CertificateExt.NONE) - { - logger.Error("Error reading certificate path"); - return new RSAParameters(); - } + string extension = Path.GetExtension(path).Replace(".", string.Empty).Trim(); + CertificateExt ext = extension.IsNullOrEmpty() ? Value("b64") : Value(extension); switch (ext) { case CertificateExt.crt: case CertificateExt.cer: return GetPublicRSAParameters(LoadFromDer(path)); case CertificateExt.pfx: - case CertificateExt.jks: case CertificateExt.pkcs12: case CertificateExt.p12: return GetPublicRSAParameters(LoadFromPkcs12(path, alias, password)); case CertificateExt.pem: case CertificateExt.key: return GetPublicRSAParameters(LoadFromPkcs8(path)); + case CertificateExt.b64: + return GetPublicRSAParameters(LoadFromBase64(path)); default: logger.Error("Invalid certificate file extension"); return new RSAParameters(); } } + private static Org.BouncyCastle.X509.X509Certificate LoadFromBase64(string base64) + { + logger.Debug("LoadFromBase64"); + Console.WriteLine("LoadFromBase64"); + try + { + return new X509CertificateParser().ReadCertificate(Base64.Decode(base64)); + + } + catch (Exception e) + { + logger.Error("LoadFromBase64", e); + Console.WriteLine("error LoadFromBase64"); + return null; + } + } + private static RSAParameters GetPublicRSAParameters(Org.BouncyCastle.X509.X509Certificate cert) { - X509Certificate2 cert2 = new X509Certificate2(DotNetUtilities.ToX509Certificate(cert)); - return cert2.GetRSAPublicKey().ExportParameters(false); + X509Certificate2 cert2 = new X509Certificate2(DotNetUtilities.ToX509Certificate(cert)); + Console.WriteLine("GetPublicRSAParameters" + cert2.GetSerialNumberString()); + return cert2.GetRSAPublicKey().ExportParameters(false); } private static Org.BouncyCastle.X509.X509Certificate LoadFromPkcs12(string path, string alias, string password) @@ -128,7 +147,7 @@ private static Org.BouncyCastle.X509.X509Certificate LoadFromPkcs8(string path) try { pemReader = new PemReader(streamReader); - Object obj = pemReader.ReadObject(); + object obj = pemReader.ReadObject(); if (obj.GetType() == typeof(System.Security.Cryptography.X509Certificates.X509Certificate) || obj.GetType() == typeof(Org.BouncyCastle.X509.X509Certificate) || obj.GetType() == typeof(X509CertificateStructure)) { diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs new file mode 100644 index 000000000..68051e171 --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs @@ -0,0 +1,223 @@ +using System; +using System.IO; +using System.Security; +using System.Security.Cryptography; +using log4net; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; +using Microsoft.IdentityModel.Tokens; + +namespace GamUtils.Utils.Keys +{ + [SecuritySafeCritical] + internal enum PrivateKeyExt + { + NONE, pfx, pkcs12, p12, pem, key, b64 + } + + [SecuritySafeCritical] + internal static class PrivateKeyUtil + { + private static readonly ILog logger = LogManager.GetLogger(typeof(PrivateKeyUtil)); + + [SecuritySafeCritical] + internal static PrivateKeyExt Value(string ext) + { + switch (ext.ToLower().Trim()) + { + case "pfx": + return PrivateKeyExt.pfx; + case "pkcs12": + return PrivateKeyExt.pkcs12; + case "p12": + return PrivateKeyExt.p12; + case "pem": + return PrivateKeyExt.pem; + case "key": + return PrivateKeyExt.key; + case "b64": + return PrivateKeyExt.b64; + default: + logger.Error("Invalid certificate file extension"); + return PrivateKeyExt.NONE; + } + } + + [SecuritySafeCritical] + internal static RSAParameters GetPrivateKey(string path, string alias, string password) + { + string extension = Path.GetExtension(path).Replace(".", string.Empty).Trim(); + PrivateKeyExt ext = extension.IsNullOrEmpty() ? Value("b64") : Value(extension); + if (ext == PrivateKeyExt.NONE) + { + logger.Error("Error reading certificate path"); + return new RSAParameters(); + } + switch (ext) + { + case PrivateKeyExt.pfx: + case PrivateKeyExt.pkcs12: + case PrivateKeyExt.p12: + return GetPrivateRSAParameters(LoadFromPkcs12(path, alias, password)); + case PrivateKeyExt.pem: + case PrivateKeyExt.key: + return GetPrivateRSAParameters(LoadFromPkcs8(path)); + case PrivateKeyExt.b64: + return GetPrivateRSAParameters(LoadFromBase64(path)); + default: + logger.Error("Invalid certificate file extension"); + return new RSAParameters(); + } + } + + private static PrivateKeyInfo LoadFromBase64(string base64) + { + logger.Debug("LoadFromBase64"); + byte[] keybytes = Base64.Decode(base64); + using (Asn1InputStream istream = new Asn1InputStream(keybytes)) + { + Asn1Sequence seq = (Asn1Sequence)istream.ReadObject(); + return PrivateKeyInfo.GetInstance(seq); + } + } + + private static RSAParameters GetPrivateRSAParameters(PrivateKeyInfo privateKeyInfo) + { + string serializedPrivate = Convert.ToBase64String(privateKeyInfo.ToAsn1Object().GetDerEncoded()); + RsaPrivateCrtKeyParameters privateKey = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(serializedPrivate)); + +#if NETCORE + +if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) +{ +try + { + RSA rsa = RSA.Create(); + rsa.ImportPkcs8PrivateKey(serializedPrivateBytes, out int outthing); + return rsa.ExportParameters(true); + }catch(Exception e ) + { + logger.Error("CastPrivateKeyInfo", e); + return null; + } +} +#endif + return DotNetUtilities.ToRSA(privateKey).ExportParameters(true); + + } + + private static PrivateKeyInfo LoadFromPkcs8(string path) + { + using (StreamReader streamReader = new StreamReader(path)) + { + Org.BouncyCastle.OpenSsl.PemReader pemReader = null; + try + { + pemReader = new Org.BouncyCastle.OpenSsl.PemReader(streamReader); + Object obj = pemReader.ReadObject(); + if (obj.GetType() == typeof(RsaPrivateCrtKeyParameters)) + { + + AsymmetricKeyParameter asymKeyParm = (AsymmetricKeyParameter)obj; + return CreatePrivateKeyInfo(asymKeyParm); + + } + else if (obj.GetType() == typeof(AsymmetricCipherKeyPair)) + { + AsymmetricCipherKeyPair asymKeyPair = (AsymmetricCipherKeyPair)obj; + return PrivateKeyInfoFactory.CreatePrivateKeyInfo(asymKeyPair.Private); + } + else + { + logger.Error("loadFromPkcs8: Could not load private key"); + return null; + } + }catch(Exception e) + { + logger.Error("LoadFromPkcs8", e); + return null; + }finally + { + pemReader.Reader.Close(); + } + + } + } + private static PrivateKeyInfo LoadFromPkcs12(string path, string alias, string password) + { + logger.Debug("LoadFromPkcs12"); + try + { + Pkcs12Store pkcs12 = new Pkcs12StoreBuilder().Build(); + using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) + { + pkcs12.Load(fs, password.ToCharArray()); + foreach (string n in pkcs12.Aliases) + { + if (pkcs12.IsKeyEntry(n) && pkcs12.GetKey(n).Key.IsPrivate) + { + return PrivateKeyInfoFactory.CreatePrivateKeyInfo(pkcs12.GetKey(n).Key); + } + } + } + }catch (Exception e) + { + logger.Error("LoadFromPkcs12", e); + return null; + } + logger.Error("LoadFromPkcs12: path not found"); + return null; + + } + + private static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter key) + { + if (key is RsaKeyParameters) + { + AlgorithmIdentifier algID = new AlgorithmIdentifier( + PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance); + + RsaPrivateKeyStructure keyStruct; + if (key is RsaPrivateCrtKeyParameters) + { + RsaPrivateCrtKeyParameters _key = (RsaPrivateCrtKeyParameters)key; + + keyStruct = new RsaPrivateKeyStructure( + _key.Modulus, + _key.PublicExponent, + _key.Exponent, + _key.P, + _key.Q, + _key.DP, + _key.DQ, + _key.QInv); + } + else + { + RsaKeyParameters _key = (RsaKeyParameters)key; + + keyStruct = new RsaPrivateKeyStructure( + _key.Modulus, + BigInteger.Zero, + _key.Exponent, + BigInteger.Zero, + BigInteger.Zero, + BigInteger.Zero, + BigInteger.Zero, + BigInteger.Zero); + } + + return new PrivateKeyInfo(algID, keyStruct.ToAsn1Object()); + } + logger.Error("CreatePrivateKeyInfo"); + throw new ArgumentNullException("Class provided is not convertible: " + key.GetType().FullName); + } + } +} diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Random.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Random.cs index bf2d8427f..89b20b1b0 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Random.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Random.cs @@ -2,13 +2,14 @@ using System.Security; using System.Security.Cryptography; using System.Text; +using Org.BouncyCastle.Utilities.Encoders; namespace GamUtils.Utils { [SecuritySafeCritical] public class Random { - internal static string RandomNumeric(int length) + internal static string Numeric(int length) { string s = ""; byte[] buffer = new byte[sizeof(uint)]; @@ -22,11 +23,11 @@ internal static string RandomNumeric(int length) s += BitConverter.ToUInt32(buffer, 0).ToString(); } } - return s.Length >= length ? s.Substring(0, length) : RandomNumeric(length); + return s.Length >= length ? s.Substring(0, length) : Numeric(length); } [SecuritySafeCritical] - internal static string RandomAlphanumeric(int length) + internal static string Alphanumeric(int length) { @@ -47,5 +48,25 @@ internal static string RandomAlphanumeric(int length) return result.ToString(); } + [SecuritySafeCritical] + internal static string HexaBits(int length) + { + Byte[] result = new Byte[length / 8]; + +#if NETCORE + var arraySpan = new Span(result); + System.Security.Cryptography.RandomNumberGenerator.Fill(arraySpan); +#else + + using (System.Security.Cryptography.RNGCryptoServiceProvider rngCsp = new System.Security.Cryptography.RNGCryptoServiceProvider()) + { + + rngCsp.GetBytes(result); + } +#endif + return Hex.ToHexString(result); + + } + } } diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256d_key.key b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256d_key.key new file mode 100644 index 000000000..e41d6f252 --- /dev/null +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Resources/dummycerts/RSA_sha256_2048/sha256d_key.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAtc4GlPloet6fQzVqAMuuNudhL2YzePQGN8dEApwGvCTvT5O8 +50MK8RBVCoGc79BhxGFu/l/rsia+wVuEwOn7iSfGoBP25mUWco3SY6LntBTC+n25 +gmfU7MacXuKc4rKclkPI2E+CpeCN33WTVEp+F0onZwygSEngtOZq3HIQyoSJ6YmA +yePNZbAeCUxLYt0uF8v06CsGOLemrbcOs+UA4QXPmK6PmFKq7pYjgCqnH8m3vZNO +48DArxVTNYa2GCe4cBw0haNzCsGdMtoMNMOkoFQcSxaPimD96ut2+cFYQ/Jc2kof +vFHMohzNv8oxHo+xJ0Rc3XJU0jV0RTWoi5xFXQIDAQABAoIBAQCT/Go7JXE4YrI8 +4OOyVhkvM9RV4tkPIYNWL+taPGr3BxGNMvLXRClJ5EN00+BNDNAoLC9O/AE8+HDZ +r4c2CL/o+umhL98P10UYZfzVgasdWLEFeQVh8ubM/TYXvlp55W20muSHvuDX6RtS +w7/zItfUWVYNeaeWcBxq5Awj+O1WCoBV8OdWT8av5dyCHquD8rngvxD0gKeHvano +u6fOZN4tsolrB4GWh8B4A08dh4Ktcv/vxOfhzcS9jpT6+Zc5TdriD2fUYsdiw4dB +a4rghI61xbEyR8OC0ytOK5HhpXnTLcOv2zk8YmxW4HrkLWNV8xvzNPsZT9p4gWwB +AOGer07BAoGBAOpOy0rIems7JNFvfnROqW3Nx4rDqCiO+q14t/IBEHQrhdODireO +lrbUIeK9fnbHjuDoI17UTEtPuR5sdoxV4zyXsTIC37b628GlaoPVh3pyi/6o+Ypg +p+JFWmuCaNVRxWiGPtW/or/ulmP5XhcRp7QJIvbuD0aIEa1K1i0R/ZHlAoGBAMai +4rIDB0BnKSQxybSNjfh1ICwzdOuT7SpRD/aOlgcAG/OvyJ1Wk6NoJhL5rJTUA2B9 +es3U3M1jB55wcdQdNdiqVA/reQliLzGXbE5zEQ41oXYJucpTfTU/PbeV/Bj76N+l +o7lwCllo3EaHc0YKOe8/WnIQsjCoRlOcgzsYfI4ZAoGAMeq7cKEpQ3MEMwI3xHuF +qPjwC+YHCyz6xr4zIgGMCdPD3P3nLZfZD/Y9idqo+JEnJU8PSgKchmbjn1GoJ9mc +YapHe8oU8xyaeLTO7mstQ67nmEdTcmGJIrF3w/Oydc/H6K7A8DS1bYJc08uqeeuu ++LIBmu24n2QZr/uDiXKNvOkCgYEAuHRlwxxgzYN+hufdANc6cPCC8cjO2DxDzjn8 +ct6xnsqRKlegGctdyi5avOAxTPscL6wWL7FtYSSG3LBaY7jEWfDBow7tFLOiU5Dj +uG3N9r4Cs5QQfTvOV3Xkn+idc63p8FTmlrreQWzIsI3zk6THa84O9UFf1yNMOzRq +AKSadXECgYBEXyOgHyU2irRKX197nUdQd862tWONqaVNk7xiOSdv3CLRDaMkZrci +mA6diNN+vz3ut57iM7N9Yuqv4Qq/U79wBqElSrjy6Qlr+cVTvwT4RrOXcMfNZ1KN +Pz/h9l/Hce4Oez0GOLn+BffhCF3gHWz6nwfBgVu0V9xQ8eTaQfh4fw== +-----END RSA PRIVATE KEY----- diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs index db84d29ab..aa02ed41f 100644 --- a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs @@ -92,5 +92,13 @@ public void TestLoadKey() bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.key", "", password, tokenFile); Assert.IsTrue(result, "TestLoadKey"); } + + [Test] + public void TestLoadBase64() + { + string base64 = "MIIEATCCAumgAwIBAgIJAIAqvKHZ+gFhMA0GCSqGSIb3DQEBCwUAMIGWMQswCQYDVQQGEwJVWTETMBEGA1UECAwKTW9udGV2aWRlbzETMBEGA1UEBwwKTW9udGV2aWRlbzEQMA4GA1UECgwHR2VuZVh1czERMA8GA1UECwwIU2VjdXJpdHkxEjAQBgNVBAMMCXNncmFtcG9uZTEkMCIGCSqGSIb3DQEJARYVc2dyYW1wb25lQGdlbmV4dXMuY29tMB4XDTIwMDcwODE4NTcxN1oXDTI1MDcwNzE4NTcxN1owgZYxCzAJBgNVBAYTAlVZMRMwEQYDVQQIDApNb250ZXZpZGVvMRMwEQYDVQQHDApNb250ZXZpZGVvMRAwDgYDVQQKDAdHZW5lWHVzMREwDwYDVQQLDAhTZWN1cml0eTESMBAGA1UEAwwJc2dyYW1wb25lMSQwIgYJKoZIhvcNAQkBFhVzZ3JhbXBvbmVAZ2VuZXh1cy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1zgaU+Wh63p9DNWoAy64252EvZjN49AY3x0QCnAa8JO9Pk7znQwrxEFUKgZzv0GHEYW7+X+uyJr7BW4TA6fuJJ8agE/bmZRZyjdJjoue0FML6fbmCZ9Tsxpxe4pzispyWQ8jYT4Kl4I3fdZNUSn4XSidnDKBISeC05mrcchDKhInpiYDJ481lsB4JTEti3S4Xy/ToKwY4t6attw6z5QDhBc+Yro+YUqruliOAKqcfybe9k07jwMCvFVM1hrYYJ7hwHDSFo3MKwZ0y2gw0w6SgVBxLFo+KYP3q63b5wVhD8lzaSh+8UcyiHM2/yjEej7EnRFzdclTSNXRFNaiLnEVdAgMBAAGjUDBOMB0GA1UdDgQWBBQtQAWJRWNr/OswPSAdwCQh0Eei/DAfBgNVHSMEGDAWgBQtQAWJRWNr/OswPSAdwCQh0Eei/DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCjHe3JbNKv0Ywc1zlLacUNWcjLbmzvnjs8Wq5oxtf5wG5PUlhLSYZ9MPhuf95PlibnrO/xVY292P5lo4NKhS7VOonpbPQ/PrCMO84Pz1LGfM/wCWQIowh6VHq18PiZka9zbwl6So0tgClKkFSRk4wpKrWX3+M3+Y+D0brd8sEtA6dXeYHDtqV0YgjKdZIIOx0vDT4alCoVQrQ1yAIq5INT3cSLgJezIhEadDv3Tc7bMxMFeL+81qHm9Z/9/KE6Z+JB0ZEOkF/2NSQJd+Z7MBR8CxOdTQis3ltMoXDatNkjZ2Env40sw4NICB8YYhsWMIarew5uNT+RS28YHNlbmogh"; + bool result = GamUtilsEO.VerifyJWTWithFile(base64 , "", "", tokenFile); + Assert.IsTrue(result, "TestLoadKey"); + } } } diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestEncryption.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestEncryption.cs new file mode 100644 index 000000000..9a1d891da --- /dev/null +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestEncryption.cs @@ -0,0 +1,23 @@ +using GamUtils; +using Microsoft.IdentityModel.Tokens; +using NUnit.Framework; + +namespace GamTest.Utils +{ + [TestFixture] + public class TestEncryption + { + [Test] + public void TestAesGcm() + { + string key = GamUtilsEO.RandomHexaBits(256); + string nonce = GamUtilsEO.RandomHexaBits(128); + string txt = "hello world"; + int macSize = 64; + string encrypted = GamUtilsEO.AesGcm(txt, key, nonce, macSize, true); + Assert.IsFalse(encrypted.IsNullOrEmpty(), "testAesGcm encrypt"); + string decrypted = GamUtilsEO.AesGcm(encrypted, key, nonce, macSize, false); + Assert.AreEqual(txt, decrypted, "testAesGcm decrypt"); + } + } +} diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestPrivateKey.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestPrivateKey.cs new file mode 100644 index 000000000..252694100 --- /dev/null +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestPrivateKey.cs @@ -0,0 +1,91 @@ +using System; +using System.IO; +using NUnit.Framework; +using GamUtils; +using Microsoft.IdentityModel.Tokens; + +namespace GamTest.Utils +{ + [TestFixture] + public class TestPrivateKey + { +#pragma warning disable CS0414 + private static string resources; + private static string path_RSA_sha256_2048; + private static string alias; + private static string password; +#pragma warning disable IDE0044 + private static string BASE_PATH; +#pragma warning restore IDE0044 +#pragma warning restore CS0414 + private static string header; + private static string payload; + + [SetUp] + public virtual void SetUp() + { + BASE_PATH = TestJwt.GetStartupDirectory(); + resources = Path.Combine(BASE_PATH, "Resources", "dummycerts"); + path_RSA_sha256_2048 = Path.Combine(resources, "RSA_sha256_2048"); + string kid = Guid.NewGuid().ToString(); + alias = "1"; + password = "dummy"; + header = "{\n" + + " \"alg\": \"RS256\",\n" + + " \"kid\": \"" + kid + "\",\n" + + " \"typ\": \"JWT\"\n" + + "}"; + payload = "{\n" + + " \"sub\": \"1234567890\",\n" + + " \"name\": \"John Doe\",\n" + + " \"iat\": 1516239022\n" + + "}"; + + } + + + [Test] + [Ignore("issues with pfx extension in .Net")] + public void TestLoadPfx() + { + string result = GamUtilsEO.CreateJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.pfx", "", password, payload, header ); + Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadPfx"); + } + + [Test] + public void TestLoadPkcs12() + { + string result = GamUtilsEO.CreateJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.pkcs12", "", password, payload, header); + Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadPkcs12"); + } + + [Test] + public void TestLoadP12() + { + string result = GamUtilsEO.CreateJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.p12", "", password, payload, header); + Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadP12"); + } + + [Test] + public void TestLoadPem() + { + string result = GamUtilsEO.CreateJWTWithFile(path_RSA_sha256_2048 + "\\sha256d_key.pem", "", password, payload, header); + Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadPem"); + } + + [Test] + public void TestLoadKey() + { + string result = GamUtilsEO.CreateJWTWithFile(path_RSA_sha256_2048 + "\\sha256d_key.key", "", password, payload, header); + Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadKey"); + } + + [Test] + public void TestLoadBase64() + { + string base64 = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC1zgaU+Wh63p9DNWoAy64252EvZjN49AY3x0QCnAa8JO9Pk7znQwrxEFUKgZzv0GHEYW7+X+uyJr7BW4TA6fuJJ8agE/bmZRZyjdJjoue0FML6fbmCZ9Tsxpxe4pzispyWQ8jYT4Kl4I3fdZNUSn4XSidnDKBISeC05mrcchDKhInpiYDJ481lsB4JTEti3S4Xy/ToKwY4t6attw6z5QDhBc+Yro+YUqruliOAKqcfybe9k07jwMCvFVM1hrYYJ7hwHDSFo3MKwZ0y2gw0w6SgVBxLFo+KYP3q63b5wVhD8lzaSh+8UcyiHM2/yjEej7EnRFzdclTSNXRFNaiLnEVdAgMBAAECggEBAJP8ajslcThisjzg47JWGS8z1FXi2Q8hg1Yv61o8avcHEY0y8tdEKUnkQ3TT4E0M0CgsL078ATz4cNmvhzYIv+j66aEv3w/XRRhl/NWBqx1YsQV5BWHy5sz9Nhe+WnnlbbSa5Ie+4NfpG1LDv/Mi19RZVg15p5ZwHGrkDCP47VYKgFXw51ZPxq/l3IIeq4PyueC/EPSAp4e9qei7p85k3i2yiWsHgZaHwHgDTx2Hgq1y/+/E5+HNxL2OlPr5lzlN2uIPZ9Rix2LDh0FriuCEjrXFsTJHw4LTK04rkeGledMtw6/bOTxibFbgeuQtY1XzG/M0+xlP2niBbAEA4Z6vTsECgYEA6k7LSsh6azsk0W9+dE6pbc3HisOoKI76rXi38gEQdCuF04OKt46WttQh4r1+dseO4OgjXtRMS0+5Hmx2jFXjPJexMgLftvrbwaVqg9WHenKL/qj5imCn4kVaa4Jo1VHFaIY+1b+iv+6WY/leFxGntAki9u4PRogRrUrWLRH9keUCgYEAxqLisgMHQGcpJDHJtI2N+HUgLDN065PtKlEP9o6WBwAb86/InVaTo2gmEvmslNQDYH16zdTczWMHnnBx1B012KpUD+t5CWIvMZdsTnMRDjWhdgm5ylN9NT89t5X8GPvo36WjuXAKWWjcRodzRgo57z9achCyMKhGU5yDOxh8jhkCgYAx6rtwoSlDcwQzAjfEe4Wo+PAL5gcLLPrGvjMiAYwJ08Pc/ectl9kP9j2J2qj4kSclTw9KApyGZuOfUagn2Zxhqkd7yhTzHJp4tM7uay1DrueYR1NyYYkisXfD87J1z8forsDwNLVtglzTy6p56674sgGa7bifZBmv+4OJco286QKBgQC4dGXDHGDNg36G590A1zpw8ILxyM7YPEPOOfxy3rGeypEqV6AZy13KLlq84DFM+xwvrBYvsW1hJIbcsFpjuMRZ8MGjDu0Us6JTkOO4bc32vgKzlBB9O85XdeSf6J1zrenwVOaWut5BbMiwjfOTpMdrzg71QV/XI0w7NGoApJp1cQKBgERfI6AfJTaKtEpfX3udR1B3zra1Y42ppU2TvGI5J2/cItENoyRmtyKYDp2I036/Pe63nuIzs31i6q/hCr9Tv3AGoSVKuPLpCWv5xVO/BPhGs5dwx81nUo0/P+H2X8dx7g57PQY4uf4F9+EIXeAdbPqfB8GBW7RX3FDx5NpB+Hh/"; + string result = GamUtilsEO.CreateJWTWithFile(base64 , "", "", payload, header); + Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadKey"); + } + } +} diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestRandom.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestRandom.cs index 9c6f1a8da..c5a210899 100644 --- a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestRandom.cs +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestRandom.cs @@ -1,5 +1,6 @@ using NUnit.Framework; using GamUtils; +using Microsoft.IdentityModel.Tokens; namespace GamTest.Utils { @@ -56,5 +57,16 @@ public void TestRandomAlphanumeric() string l256_string = GamUtilsEO.RandomAlphanumeric(l256); Assert.AreEqual(l256, l256_string.Length, "l256 alphanumeric"); } + + [Test] + public void TestHexaBits() + { + int[] lengths = new int[] { 32, 64, 128, 256, 512, 1024 }; + foreach(int n in lengths) + { + string hexa = GamUtilsEO.RandomHexaBits(n); + Assert.IsFalse(hexa.IsNullOrEmpty(), "TestHexaBits"); + } + } } } \ No newline at end of file From 7ff5f04d07458776dc79eb81745636797b5679a9 Mon Sep 17 00:00:00 2001 From: sgrampone Date: Wed, 7 Aug 2024 14:05:24 -0300 Subject: [PATCH 05/16] Fix missing test file --- .../extensions/gam/test/DotNetFramework/GamTest/GamTest.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/GamTest.csproj b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/GamTest.csproj index cf4333cc6..89f44a7bc 100644 --- a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/GamTest.csproj +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/GamTest.csproj @@ -50,5 +50,8 @@ PreserveNewest + + PreserveNewest + \ No newline at end of file From 7903f7bbb17e740ab555304ab2edbee60d9290e9 Mon Sep 17 00:00:00 2001 From: sgrampone Date: Wed, 7 Aug 2024 15:17:36 -0300 Subject: [PATCH 06/16] Complete hexabits test --- .../DotNetFramework/GamTest/Utils/TestRandom.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestRandom.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestRandom.cs index c5a210899..628177cf0 100644 --- a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestRandom.cs +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestRandom.cs @@ -1,6 +1,8 @@ using NUnit.Framework; using GamUtils; using Microsoft.IdentityModel.Tokens; +using Org.BouncyCastle.Utilities.Encoders; +using System; namespace GamTest.Utils { @@ -66,6 +68,17 @@ public void TestHexaBits() { string hexa = GamUtilsEO.RandomHexaBits(n); Assert.IsFalse(hexa.IsNullOrEmpty(), "TestHexaBits"); + try + { + byte[] decoded = Hex.Decode(hexa); + if(decoded.Length*8 != n) + { + Assert.Fail("TestHexaBits wrong hexa length"); + } + }catch(Exception e) + { + Assert.Fail("TestHexaBits nt hexa characters " + e.Message); + } } } } From 697b55d90ffe6dab23403995bc2fe848f2d0dbc5 Mon Sep 17 00:00:00 2001 From: sgrampone Date: Thu, 8 Aug 2024 11:58:50 -0300 Subject: [PATCH 07/16] GamUtils NetCore implementation + tests --- dotnet/DotNetStandardClasses.sln | 14 ++++ .../src/DotNet/GamUtilsNet/GamUtilsNet.csproj | 43 ++++++++++ .../GamUtils/Utils/Keys/PrivateKeyExt.cs | 6 +- .../test/DotNet/GamTestNet/GamTestNet.csproj | 74 ++++++++++++++++++ .../RSA_sha256_2048/sha256_cert.cer | Bin 0 -> 1029 bytes .../RSA_sha256_2048/sha256_cert.crt | Bin 0 -> 1029 bytes .../RSA_sha256_2048/sha256_cert.key | 24 ++++++ .../RSA_sha256_2048/sha256_cert.p12 | Bin 0 -> 2629 bytes .../RSA_sha256_2048/sha256_cert.pem | 24 ++++++ .../RSA_sha256_2048/sha256_cert.pkcs12 | Bin 0 -> 2629 bytes .../RSA_sha256_2048/sha256d_key.key | 27 +++++++ .../RSA_sha256_2048/sha256d_key.pem | 27 +++++++ .../DotNetFramework/GamTest/Utils/TestJwk.cs | 4 +- .../DotNetFramework/GamTest/Utils/TestJwt.cs | 7 +- 14 files changed, 243 insertions(+), 7 deletions(-) create mode 100644 dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj create mode 100644 dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj create mode 100644 dotnet/src/extensions/gam/test/DotNet/GamTestNet/Resources/dummycerts/RSA_sha256_2048/sha256_cert.cer create mode 100644 dotnet/src/extensions/gam/test/DotNet/GamTestNet/Resources/dummycerts/RSA_sha256_2048/sha256_cert.crt create mode 100644 dotnet/src/extensions/gam/test/DotNet/GamTestNet/Resources/dummycerts/RSA_sha256_2048/sha256_cert.key create mode 100644 dotnet/src/extensions/gam/test/DotNet/GamTestNet/Resources/dummycerts/RSA_sha256_2048/sha256_cert.p12 create mode 100644 dotnet/src/extensions/gam/test/DotNet/GamTestNet/Resources/dummycerts/RSA_sha256_2048/sha256_cert.pem create mode 100644 dotnet/src/extensions/gam/test/DotNet/GamTestNet/Resources/dummycerts/RSA_sha256_2048/sha256_cert.pkcs12 create mode 100644 dotnet/src/extensions/gam/test/DotNet/GamTestNet/Resources/dummycerts/RSA_sha256_2048/sha256d_key.key create mode 100644 dotnet/src/extensions/gam/test/DotNet/GamTestNet/Resources/dummycerts/RSA_sha256_2048/sha256d_key.pem diff --git a/dotnet/DotNetStandardClasses.sln b/dotnet/DotNetStandardClasses.sln index 9c981c447..ee757432f 100644 --- a/dotnet/DotNetStandardClasses.sln +++ b/dotnet/DotNetStandardClasses.sln @@ -281,6 +281,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotNetFramework", "DotNetFr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GamTest", "src\extensions\gam\test\DotNetFramework\GamTest\GamTest.csproj", "{52B67EA3-B17D-4002-8EC3-0D5DDB62988B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GamUtilsNet", "src\extensions\gam\src\DotNet\GamUtilsNet\GamUtilsNet.csproj", "{AA93273B-2E0B-4CD3-A921-A462B214F424}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GamTestNet", "src\extensions\gam\test\DotNet\GamTestNet\GamTestNet.csproj", "{D46D0666-AF65-4875-954C-82AB2240B17D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -667,6 +671,14 @@ Global {52B67EA3-B17D-4002-8EC3-0D5DDB62988B}.Debug|Any CPU.Build.0 = Debug|Any CPU {52B67EA3-B17D-4002-8EC3-0D5DDB62988B}.Release|Any CPU.ActiveCfg = Release|Any CPU {52B67EA3-B17D-4002-8EC3-0D5DDB62988B}.Release|Any CPU.Build.0 = Release|Any CPU + {AA93273B-2E0B-4CD3-A921-A462B214F424}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AA93273B-2E0B-4CD3-A921-A462B214F424}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AA93273B-2E0B-4CD3-A921-A462B214F424}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AA93273B-2E0B-4CD3-A921-A462B214F424}.Release|Any CPU.Build.0 = Release|Any CPU + {D46D0666-AF65-4875-954C-82AB2240B17D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D46D0666-AF65-4875-954C-82AB2240B17D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D46D0666-AF65-4875-954C-82AB2240B17D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D46D0666-AF65-4875-954C-82AB2240B17D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -802,6 +814,8 @@ Global {1942B0FE-49BD-4EC4-9788-F19FDD921E69} = {035C3DAF-553E-4E64-BA9E-113F5C80FD97} {B33F3709-5EA0-4FE8-9E3A-50D3046817D6} = {035C3DAF-553E-4E64-BA9E-113F5C80FD97} {52B67EA3-B17D-4002-8EC3-0D5DDB62988B} = {B33F3709-5EA0-4FE8-9E3A-50D3046817D6} + {AA93273B-2E0B-4CD3-A921-A462B214F424} = {56429994-8A51-48AB-8105-737B77840D18} + {D46D0666-AF65-4875-954C-82AB2240B17D} = {1942B0FE-49BD-4EC4-9788-F19FDD921E69} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E18684C9-7D76-45CD-BF24-E3944B7F174C} diff --git a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj new file mode 100644 index 000000000..2b14a8bc2 --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj @@ -0,0 +1,43 @@ + + + + net6.0;net8.0 + GamUtilsNetImpl + 17.4.0 + CA1031, CA1801, SYSLIB0027 + GeneXxus.Gam.Utils.Net + + + + NETCORE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs index 68051e171..20808760a 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs @@ -13,6 +13,7 @@ using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities.Encoders; using Microsoft.IdentityModel.Tokens; +using System.Runtime.InteropServices; namespace GamUtils.Utils.Keys { @@ -90,7 +91,8 @@ private static PrivateKeyInfo LoadFromBase64(string base64) private static RSAParameters GetPrivateRSAParameters(PrivateKeyInfo privateKeyInfo) { - string serializedPrivate = Convert.ToBase64String(privateKeyInfo.ToAsn1Object().GetDerEncoded()); + byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetDerEncoded(); + string serializedPrivate = Convert.ToBase64String(serializedPrivateBytes); RsaPrivateCrtKeyParameters privateKey = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(serializedPrivate)); #if NETCORE @@ -105,7 +107,7 @@ private static RSAParameters GetPrivateRSAParameters(PrivateKeyInfo privateKeyIn }catch(Exception e ) { logger.Error("CastPrivateKeyInfo", e); - return null; + return new RSAParameters(); } } #endif diff --git a/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj b/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj new file mode 100644 index 000000000..aa1e6c526 --- /dev/null +++ b/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj @@ -0,0 +1,74 @@ + + + + net6.0;net8.0 + false + CS0618,CA1707 + false + + + + NETCORE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + diff --git a/dotnet/src/extensions/gam/test/DotNet/GamTestNet/Resources/dummycerts/RSA_sha256_2048/sha256_cert.cer b/dotnet/src/extensions/gam/test/DotNet/GamTestNet/Resources/dummycerts/RSA_sha256_2048/sha256_cert.cer new file mode 100644 index 0000000000000000000000000000000000000000..bd788b5de7701ce8e1ec5cba0657b3f339fdfdae GIT binary patch literal 1029 zcmXqLVqr9BVtToNnTe5!iIbs0YtO=)zZeq@c-c6$+C196^D;7WvoaVoPBY{-;ACSC zWnmL$3XL=rHV_1HIC!{x^Ycnl%Q90^^I?MQD1rh8d?1xvJnZhNd8rYl#fE|g{2&o- z9**GD`$@#ek za^k#31_tH^7KRq4=7#1`K&~l}YYycOUWYd^Dj^3lBP#=Q6C*!^K@%evQxhX2!`5?b zQ+{St-J9=hn#FK>o!Rq5{WRl>FKp(=U6|&u?NNE}KY7n{XReO|p_Pvw+9v?WcUNqRWZJUJpjsh8z*2TqK z2j?2y;xReAWI>3Gw^)By!rxb~%YGh=aQ+l?%S(Pw;F(1-XZN2nl~?m4cpOw5c7jEe&d{0wA)Nkf*8MT|v6*MYUuH97mwYXe&a*#jzy7u*;9F^~sI zE3-%#h&5nWzynes%))BG%*gm3In03x8yMz{42xyop3J$l{$h{JbxZHeqr8zPPUq#k zpJ#0owJzh>^`8gw{DUIAJ=+injZW{};R_xz%ZQ--8^Z))?XqEoR@!~|j3Gv@dRXEF^RU3%Za0}1%`$@#ek za^k#31_tH^7KRq4=7#1`K&~l}YYycOUWYd^Dj^3lBP#=Q6C*!^K@%evQxhX2!`5?b zQ+{St-J9=hn#FK>o!Rq5{WRl>FKp(=U6|&u?NNE}KY7n{XReO|p_Pvw+9v?WcUNqRWZJUJpjsh8z*2TqK z2j?2y;xReAWI>3Gw^)By!rxb~%YGh=aQ+l?%S(Pw;F(1-XZN2nl~?m4cpOw5c7jEe&d{0wA)Nkf*8MT|v6*MYUuH97mwYXe&a*#jzy7u*;9F^~sI zE3-%#h&5nWzynes%))BG%*gm3In03x8yMz{42xyop3J$l{$h{JbxZHeqr8zPPUq#k zpJ#0owJzh>^`8gw{DUIAJ=+injZW{};R_xz%ZQ--8^Z))?XqEoR@!~|j3Gv@dRXEF^RU3%Za0}1%kNS0ynw}bu1yKN4 z&^`hS+Cg9e#s5@5JQk4gCrYECruy^Z|7oZZP$0v<7r@jjH5G@hrj#FPa}Lvw*D z6brDNNWw%xrSSP);WF=Tsq|+w6j635H^}g8#i3eWSJHNh6)N~#b zjT8#zP%g83oD=tCX3FbqmPA_eR3fs?Hhz(6Hr3iy52tF7A?9Jt0va0pW@PO(=-(5u zHw{%sUvS;_dx5Aquj#tN3RGg^jhRthmmYKZO8XY)&aH)7!^;oBUGA(Hi&d)u)A)?= zeF^mpH!3fYVsk{q?!$#dJDPu+ySm_RWLC<&iq)65pbPH){v;T2Uc@W*zRR=Ui_MSY zJ+Wp4UxN1#x22ECZ?Q;fF)E^1T>~5N@YS0QcwMvQpeoL+wA>CM2MxyE%z%lUL3YYb zuRxnRhxA`Nk{>AEfppw58+F^6rHq^0w)z65I3e`|kC~_>1q+$f7>HaUOK3l*8k)|^ zWR{{QBGi+YcW(lm8BD~s7XTyXv5ovy84eR00&;b!dHI{GG#S;ToR2Y3(PGBJM+%~X zX4nEwqQ_@XnB>-c5TG;l*PbB#CI??ukqVz9d-vYVT(SWnD_p7j7iV`p1=8?_=}3R^ zxW|U&tsAPerAQ|zv>XZZ;|(|eI5rc*i8#}|ukL(wcVB83Ar_q7zN#0-sP=l?!|n>ENr}P73BAT77DK``|>{w%(^y$~lyD`fT+D3r#~ru03`2-%UzCbVa2@4AnU z2a0a*Imn(S8rmr17>rwdB1*Q@;&o|3Px8tubh{40%(arsR?9|&{VED%^4~9;%l2mp87M331mAn*6T%vc!wGzPuR!lhl%r6Q`pJo52L6NrR0)wP{ByoS zy4HQhj0%on%{-j8y(KlfA_g@juC0LM!ci0{goBDP4u_}H@t*J9`Urn%ZFDfY8I&hqxQ?!VnL(aUp%|N7|1J@9u{*mdW?oXdG+UTMWQpGGBxlKxPEqmW zCuKpa(?Q!CMvD&!-u=wcaWcyRt<~*oC^2D>jM*mb_VYDW&js@bG`P?Z3^-MCd~V3R zLP2j1^|=Zb)R-cHPv2@Fj$B!g=!aC9r|UrARVFHSy?ED2gc+K_jz2k8 z4Cb#sU2(Pp7DmEUYuxfTEpX1f(Tbu;$jr3Sb#G$dE_@%q{>Yv%ALU<1MR1dXcD&uyP|Dxmfv+Q6sK;CL-U?Tu%|-K z%7Nja{)cD6;jU?Bx$2kO57jdj_J29{cG`VQhG+e9_kVP;4$_>Op*Xf?yZvl<3#`Ja zVaSa*5jJG}9bV#QL%Xm5XE&)R-YdFjo_iClUG}sMkM5Nq-jkKs$Za{BaL8^Kwdd1I zH}ykCxCc^1=8I+FH3NE@EG0f5t9UK_wnNV1LmqL4PD=D&$8~i3s2aJRCCRMARncQP z^_#hj3LRgSz2Em)c(!zgMfld_W5`BjN2hjt&S|@irrigm>Vo+XI~Q#VQgT^d`KKC8 zh{ot(bG4RI>KX6IC5mh1(d+dFgLXU@B!D@Tw>`nkO79kAfgb@#(Z*`rhqg_wzP zmMaX^LWJU>iEtmj~``uK!kgQBnrx($_IzL>VFI6tazU8ub_k?8WO~SOfPx8iga^SBm<@*z84Db7nSa}SspX) zWYuORYEjwQiYYYFFV|ORf zC(;z!Jhrz%(?_hoZW>Zwtxg-N)sE|z5)$PSk_z)1pd6eK6&Y3Yg%RY93{ zcnMJc8Hd;7jMK7IE+f9!x1K-d<>j@lFe>>>_dcP>xOB9Xwq?%BfWte(axP<=~$F|6hvRH?2Wyy8i8eHdN+Q)UC=qI+i0scwOU&LE=%20L{_rk zQ+aS8RU-%^bnt_B$~o4|cNNujXp3()8L70Hwc&cPoAGn*+AnXv?CH68 zG~GJkcaii~8h`Nl`3|#7-EFUpqqp)$%>k(pnqfYH*O`}`e87g{le&E>T)mpj`OxBC z^N}qel~dtM89AcmBq)MDDLF}^$0V<;(NgM)w$Cx_(@u>YG5g7Lzx3E))*rBfiBaBM z3w>#5qJ&VWO}%Hxo?iQA2v|jCWz0LVQGpuv|adXTMZb z{jXZ2FhcOZI)d1d900Z*e}eNy4h}BLEEAp`m}K)kO+PR2uLS>iI(On9TkAB lO;dbq8Y1H8pEyk_kNS0ynw}bu1yKN4 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 lO;dbq8Y1H8pEyk_ Date: Thu, 15 Aug 2024 13:11:21 -0300 Subject: [PATCH 08/16] GamUtilsEO simplification, module refacoring + tests --- .../src/DotNet/GamUtilsNet/GamUtilsNet.csproj | 4 +- .../DotNetFramework/GamUtils/GamUtilsEO.cs | 15 +- .../GamUtils/Utils/Json/Jwk.cs | 86 ------- .../GamUtils/Utils/Json/Jwks.cs | 51 ---- .../GamUtils/Utils/Json/Jwt.cs | 68 ++++-- .../GamUtils/Utils/Json/UnixTimestamp.cs | 16 ++ .../GamUtils/Utils/Keys/PrivateKeyExt.cs | 115 +++++++-- .../{CertificateExt.cs => PublicKeyExt.cs} | 188 ++++++++++---- .../test/DotNet/GamTestNet/GamTestNet.csproj | 4 +- .../GamTest/Utils/TestCertificate.cs | 104 -------- .../DotNetFramework/GamTest/Utils/TestJwk.cs | 44 ---- .../DotNetFramework/GamTest/Utils/TestJwks.cs | 45 ---- .../DotNetFramework/GamTest/Utils/TestJwt.cs | 229 ++++++++---------- .../GamTest/Utils/TestPrivateKey.cs | 91 ------- .../GamTest/Utils/TestUnixTimestamp.cs | 37 +++ 15 files changed, 445 insertions(+), 652 deletions(-) delete mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwks.cs create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/UnixTimestamp.cs rename dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/{CertificateExt.cs => PublicKeyExt.cs} (52%) delete mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs delete mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwks.cs delete mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestPrivateKey.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestUnixTimestamp.cs diff --git a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj index 2b14a8bc2..1432b2164 100644 --- a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj +++ b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj @@ -17,9 +17,9 @@ - - + + diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs index 97fa3a2c4..970a5dd84 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs @@ -1,3 +1,4 @@ +using System; using System.Security; using GamUtils.Utils; using GamUtils.Utils.Cryprography; @@ -51,22 +52,20 @@ public static string RandomHexaBits(int bits) [SecuritySafeCritical] public static string GetPublicJwk(string jwkString) { return Jwk.GetPublic(jwkString); } + //**JWT**// [SecuritySafeCritical] - public static string Jwk_createJwt(string jwkString, string payload, string header) { return Jwk.CreateJwt(jwkString, payload, header); } + public static bool VerifyJwt(string path, string alias, string password, string token) { return Jwt.Verify(path, alias, password, token); } [SecuritySafeCritical] - public static bool Jwk_verifyJWT(string jwkString, string token) { return Jwk.VerifyJWT(jwkString, token); } - - //**JWKS**// + public static string CreateJwt(string path, string alias, string password, string payload, string header) { return Jwt.Create(path, alias, password, payload, header); } [SecuritySafeCritical] - public static bool Jwks_verifyJWT(string jwksString, string token, string kid) { return Jwks.VerifyJWT(jwksString, token, kid); } + public static long CreateUnixTimestamp(DateTime date) { return UnixTimestamp.Create(date); } - //**JWT**// [SecuritySafeCritical] - public static bool VerifyJWTWithFile(string path, string alias, string password, string token) { return Jwt.Verify(path, alias, password, token); } + public static string GetJwtHeader(string token) { return Jwt.GetHeader(token); } [SecuritySafeCritical] - public static string CreateJWTWithFile(string path, string alias, string password, string payload, string header) { return Jwt.Create(path, alias, password, payload, header); } + public static string GetJwtPayload(string token) { return Jwt.GetPayload(token); } } } diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwk.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwk.cs index 7d830efe5..c7491a00f 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwk.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwk.cs @@ -2,10 +2,8 @@ using System.Collections.Generic; using System.Security.Cryptography; using System.Security; -using Jose; using log4net; using Newtonsoft.Json; -using Microsoft.IdentityModel.Tokens; namespace GamUtils.Utils.Json { @@ -59,60 +57,6 @@ internal static string GetPublic(string jwkString) } } - [SecuritySafeCritical] - internal static string CreateJwt(string jwkString, string payload, string header) - { - if (jwkString.IsNullOrEmpty()) - { - logger.Error("createJwt jwkString parameter is empty"); - return ""; - } - if (payload.IsNullOrEmpty()) - { - logger.Error("createJwt payload parameter is empty"); - return ""; - } - if (header.IsNullOrEmpty()) - { - logger.Error("createJwt header parameter is empty"); - return ""; - } - try - { - return Jwt.Create(GetPrivateKey(jwkString), payload, header); - } - catch (Exception e) - { - logger.Error("createJwt", e); - return ""; - } - } - - [SecuritySafeCritical] - internal static bool VerifyJWT(string jwkString, string token) - { - if (jwkString.IsNullOrEmpty()) - { - logger.Error("verifyJWT jwkString parameter is empty"); - return false; - } - if (token.IsNullOrEmpty()) - { - logger.Error("verifyJWT token parameter is empty"); - return false; - } - try - { - return Jwt.Verify(GetPublicKey(jwkString), token); - } - catch (Exception e) - { - logger.Error("verifyJWT", e); - return false; - } - - } - /******** EXTERNAL OBJECT PUBLIC METHODS - END ********/ [SecuritySafeCritical] @@ -165,35 +109,5 @@ private static RSA Create(int keySizeInBits) return rSA; } - - private static RSAParameters GetPrivateKey(string jwkString) - { - Jose.Jwk jwk = Jose.Jwk.FromJson(jwkString); - - RSAParameters privateKey = new RSAParameters(); - - privateKey.Exponent = Base64Url.Decode(jwk.E); - privateKey.Modulus = Base64Url.Decode(jwk.N); - privateKey.D = Base64Url.Decode(jwk.D); - privateKey.DP = Base64Url.Decode(jwk.DP); - privateKey.DQ = Base64Url.Decode(jwk.DQ); - privateKey.P = Base64Url.Decode(jwk.P); - privateKey.Q = Base64Url.Decode(jwk.Q); - privateKey.InverseQ = Base64Url.Decode(jwk.QI); - - return privateKey; - } - - internal static RSAParameters GetPublicKey(string jwkString) - { - Jose.Jwk jwk = Jose.Jwk.FromJson(jwkString); - - RSAParameters publicKey = new RSAParameters(); - - publicKey.Exponent = Base64Url.Decode(jwk.E); - publicKey.Modulus = Base64Url.Decode(jwk.N); - - return publicKey; - } } } diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwks.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwks.cs deleted file mode 100644 index 555a889c7..000000000 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwks.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Security; -using Jose; -using Microsoft.IdentityModel.Tokens; -using log4net; -namespace GamUtils.Utils -{ - [SecuritySafeCritical] - public class Jwks - { - private static readonly ILog logger = LogManager.GetLogger(typeof(Jwks)); - - [SecuritySafeCritical] - internal static bool VerifyJWT(string jwksString, string token, string kid) - { - if (jwksString.IsNullOrEmpty()) - { - logger.Error("verifyJWT jwksString parameter is empty"); - return false; - } - if (token.IsNullOrEmpty()) - { - logger.Error("verifyJWT token parameter is empty"); - return false; - } - if (kid.IsNullOrEmpty()) - { - logger.Error("verifyJWT kid parameter is empty"); - return false; - } - try - { - JwkSet set = JwkSet.FromJson(jwksString); - foreach (Jose.Jwk jwk in set) - { - if (jwk.KeyId.Equals(kid)) - { - return Jwt.Verify(Json.Jwk.GetPublicKey(jwk.ToJson()), token); - } - } - logger.Error("Could not find indicated kid"); - return false; - } - catch (Exception e) - { - logger.Error("verifyJWT", e); - return false; - } - } - } -} diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwt.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwt.cs index cfe6171bf..e7671bf25 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwt.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/Jwt.cs @@ -19,54 +19,84 @@ public class Jwt [SecuritySafeCritical] public static bool Verify(string path, string alias, string password, string token) { - return Verify(CertificateUtil.GetCertificate(path, alias, password), token); + logger.Debug("Verify"); + try + { + return Verify(PublicKeyUtil.GetPublicKey(path, alias, password, token), token); + }catch(Exception e) + { + logger.Error("Verify", e); + return false; + } } [SecuritySafeCritical] public static string Create(string path, string alias, string password, string payload, string header) { - return Create(PrivateKeyUtil.GetPrivateKey(path, alias, password), payload, header); + logger.Debug("Create"); + try + { + return Create(PrivateKeyUtil.GetPrivateKey(path, alias, password), payload, header); + }catch(Exception e) + { + logger.Error("Create", e); + return ""; + } } - /******** EXTERNAL OBJECT PUBLIC METHODS - END ********/ + [SecuritySafeCritical] + public static string GetHeader(string token) + { + logger.Debug("GetHeader"); + return GetParts(token, 0); + } [SecuritySafeCritical] - public static bool Verify(RSAParameters publicKey, string token) + public static string GetPayload(string token) { + logger.Debug("GetPayload"); + return GetParts(token, 1); + } + + /******** EXTERNAL OBJECT PUBLIC METHODS - END ********/ - Console.WriteLine("token: " + token); + private static string GetParts(string token, int part) + { + logger.Debug("GetParts"); + try + { + string[] parts = token.Split('.'); + return System.Text.Encoding.UTF8.GetString(Base64Url.Decode(parts[part])); + } + catch (Exception e) + { + logger.Error("GetParts", e); + return ""; + } + } + [SecuritySafeCritical] + private static bool Verify(RSAParameters publicKey, string token) + { try { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { rsa.ImportParameters(publicKey); string payload = JWT.Decode(token, rsa, JwsAlgorithm.RS256); - - if(payload.IsNullOrEmpty()) - { - Console.WriteLine("payload null or empty"); - return false; - } - else - { - return true; - } - //return payload.IsNullOrEmpty() ? false : true; + return payload.IsNullOrEmpty() ? false : true; } } catch (Exception e) { logger.Error("verify", e); - Console.WriteLine("error verify"); - Console.WriteLine(e.Message); return false; } } [SecuritySafeCritical] - public static string Create(RSAParameters privateKey, string payload, string header) + private static string Create(RSAParameters privateKey, string payload, string header) { try { diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/UnixTimestamp.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/UnixTimestamp.cs new file mode 100644 index 000000000..f33847814 --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Json/UnixTimestamp.cs @@ -0,0 +1,16 @@ +using System; +using System.Globalization; +using System.Security; + +namespace GamUtils.Utils.Json +{ + [SecuritySafeCritical] + internal class UnixTimestamp + { + [SecuritySafeCritical] + internal static long Create(DateTime gxdate) + { + return (long)gxdate.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds; + } + } +} diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs index 20808760a..546ff7494 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PrivateKeyExt.cs @@ -14,13 +14,14 @@ using Org.BouncyCastle.Utilities.Encoders; using Microsoft.IdentityModel.Tokens; using System.Runtime.InteropServices; +using Jose; namespace GamUtils.Utils.Keys { [SecuritySafeCritical] internal enum PrivateKeyExt { - NONE, pfx, pkcs12, p12, pem, key, b64 + NONE, pfx, pkcs12, p12, pem, key, b64, json } [SecuritySafeCritical] @@ -28,34 +29,11 @@ internal static class PrivateKeyUtil { private static readonly ILog logger = LogManager.GetLogger(typeof(PrivateKeyUtil)); - [SecuritySafeCritical] - internal static PrivateKeyExt Value(string ext) - { - switch (ext.ToLower().Trim()) - { - case "pfx": - return PrivateKeyExt.pfx; - case "pkcs12": - return PrivateKeyExt.pkcs12; - case "p12": - return PrivateKeyExt.p12; - case "pem": - return PrivateKeyExt.pem; - case "key": - return PrivateKeyExt.key; - case "b64": - return PrivateKeyExt.b64; - default: - logger.Error("Invalid certificate file extension"); - return PrivateKeyExt.NONE; - } - } [SecuritySafeCritical] internal static RSAParameters GetPrivateKey(string path, string alias, string password) { - string extension = Path.GetExtension(path).Replace(".", string.Empty).Trim(); - PrivateKeyExt ext = extension.IsNullOrEmpty() ? Value("b64") : Value(extension); + PrivateKeyExt ext = PrivateKeyUtil.Value(FixType(path)); if (ext == PrivateKeyExt.NONE) { logger.Error("Error reading certificate path"); @@ -72,12 +50,96 @@ internal static RSAParameters GetPrivateKey(string path, string alias, string pa return GetPrivateRSAParameters(LoadFromPkcs8(path)); case PrivateKeyExt.b64: return GetPrivateRSAParameters(LoadFromBase64(path)); + case PrivateKeyExt.json: + return LoadFromJson(path); default: logger.Error("Invalid certificate file extension"); return new RSAParameters(); } } + [SecuritySafeCritical] + private static RSAParameters LoadFromJson(string json) + { + logger.Debug("LoadFromJson"); + RSAParameters privateKey = new RSAParameters(); + try + { + Jwk jwk = Jwk.FromJson(json); + privateKey.Exponent = Base64Url.Decode(jwk.E); + privateKey.Modulus = Base64Url.Decode(jwk.N); + privateKey.D = Base64Url.Decode(jwk.D); + privateKey.DP = Base64Url.Decode(jwk.DP); + privateKey.DQ = Base64Url.Decode(jwk.DQ); + privateKey.P = Base64Url.Decode(jwk.P); + privateKey.Q = Base64Url.Decode(jwk.Q); + privateKey.InverseQ = Base64Url.Decode(jwk.QI); + + } + catch (Exception e) + { + logger.Error("LoadFromJson", e); + } + return privateKey; + } + + private static string FixType(string input) + { + try + { + string extension = Path.GetExtension(input).Replace(".", string.Empty).Trim(); +#if !NETCORE + return extension.IsNullOrEmpty() ? "b64" : extension; +#else + if (extension.IsNullOrEmpty()) + { + try + { + Base64.Decode(input); + return "b64"; + } + catch (Exception) + { + return "json"; + } + } + else + { + return extension; + } +#endif + } + catch (ArgumentException) + { + return "json"; + } + } + + [SecuritySafeCritical] + private static PrivateKeyExt Value(string ext) + { + switch (ext.ToLower().Trim()) + { + case "pfx": + return PrivateKeyExt.pfx; + case "pkcs12": + return PrivateKeyExt.pkcs12; + case "p12": + return PrivateKeyExt.p12; + case "pem": + return PrivateKeyExt.pem; + case "key": + return PrivateKeyExt.key; + case "b64": + return PrivateKeyExt.b64; + case "json": + return PrivateKeyExt.json; + default: + logger.Error("Invalid certificate file extension"); + return PrivateKeyExt.NONE; + } + } + private static PrivateKeyInfo LoadFromBase64(string base64) { logger.Debug("LoadFromBase64"); @@ -91,6 +153,7 @@ private static PrivateKeyInfo LoadFromBase64(string base64) private static RSAParameters GetPrivateRSAParameters(PrivateKeyInfo privateKeyInfo) { + logger.Debug("GetPrivateRSAParameters"); byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetDerEncoded(); string serializedPrivate = Convert.ToBase64String(serializedPrivateBytes); RsaPrivateCrtKeyParameters privateKey = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(serializedPrivate)); @@ -117,6 +180,7 @@ private static RSAParameters GetPrivateRSAParameters(PrivateKeyInfo privateKeyIn private static PrivateKeyInfo LoadFromPkcs8(string path) { + logger.Debug("LoadFromPkcs8"); using (StreamReader streamReader = new StreamReader(path)) { Org.BouncyCastle.OpenSsl.PemReader pemReader = null; @@ -181,6 +245,7 @@ private static PrivateKeyInfo LoadFromPkcs12(string path, string alias, string p private static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter key) { + logger.Debug("CreatePrivateKeyInfo"); if (key is RsaKeyParameters) { AlgorithmIdentifier algID = new AlgorithmIdentifier( diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/CertificateExt.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PublicKeyExt.cs similarity index 52% rename from dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/CertificateExt.cs rename to dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PublicKeyExt.cs index b8d9e7569..141848d67 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/CertificateExt.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Keys/PublicKeyExt.cs @@ -11,77 +11,175 @@ using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography; using Org.BouncyCastle.Utilities.Encoders; +using Jose; +using System.Collections.Generic; namespace GamUtils.Utils.Keys { [SecuritySafeCritical] - internal enum CertificateExt + internal enum PublicKeyExt { - NONE, crt, cer, pfx, pkcs12, p12, pem, key, b64 + NONE, crt, cer, pfx, pkcs12, p12, pem, key, b64, json } [SecuritySafeCritical] - internal static class CertificateUtil + internal static class PublicKeyUtil { - private static readonly ILog logger = LogManager.GetLogger(typeof(CertificateUtil)); + private static readonly ILog logger = LogManager.GetLogger(typeof(PublicKeyUtil)); + + [SecuritySafeCritical] - internal static CertificateExt Value(string ext) + internal static RSAParameters GetPublicKey(string path, string alias, string password, string token) + { + logger.Debug("GetPublicKey"); + PublicKeyExt ext = PublicKeyUtil.Value(FixType(path)); + switch (ext) + { + case PublicKeyExt.crt: + case PublicKeyExt.cer: + return GetPublicRSAParameters(LoadFromDer(path)); + case PublicKeyExt.pfx: + case PublicKeyExt.pkcs12: + case PublicKeyExt.p12: + return GetPublicRSAParameters(LoadFromPkcs12(path, alias, password)); + case PublicKeyExt.pem: + case PublicKeyExt.key: + return GetPublicRSAParameters(LoadFromPkcs8(path)); + case PublicKeyExt.b64: + return GetPublicRSAParameters(LoadFromBase64(path)); + case PublicKeyExt.json: + return LoadFromJson(path, token); + default: + logger.Error("Invalid certificate file extension"); + return new RSAParameters(); + } + } + + [SecuritySafeCritical] + private static PublicKeyExt Value(string ext) { switch (ext.ToLower().Trim()) { case "crt": - return CertificateExt.crt; + return PublicKeyExt.crt; case "cer": - return CertificateExt.cer; + return PublicKeyExt.cer; case "pfx": - return CertificateExt.pfx; + return PublicKeyExt.pfx; case "pkcs12": - return CertificateExt.pkcs12; + return PublicKeyExt.pkcs12; case "p12": - return CertificateExt.p12; + return PublicKeyExt.p12; case "pem": - return CertificateExt.pem; + return PublicKeyExt.pem; case "key": - return CertificateExt.key; + return PublicKeyExt.key; case "b64": - return CertificateExt.b64; + return PublicKeyExt.b64; + case "json": + return PublicKeyExt.json; default: logger.Error("Invalid certificate file extension"); - return CertificateExt.NONE; + return PublicKeyExt.NONE; } } - [SecuritySafeCritical] - internal static RSAParameters GetCertificate(string path, string alias, string password) + private static RSAParameters LoadFromJson(string json, string token) { - string extension = Path.GetExtension(path).Replace(".", string.Empty).Trim(); - CertificateExt ext = extension.IsNullOrEmpty() ? Value("b64") : Value(extension); - switch (ext) + logger.Debug("LoadFromJson"); + RSAParameters publicKey = new RSAParameters(); + try { - case CertificateExt.crt: - case CertificateExt.cer: - return GetPublicRSAParameters(LoadFromDer(path)); - case CertificateExt.pfx: - case CertificateExt.pkcs12: - case CertificateExt.p12: - return GetPublicRSAParameters(LoadFromPkcs12(path, alias, password)); - case CertificateExt.pem: - case CertificateExt.key: - return GetPublicRSAParameters(LoadFromPkcs8(path)); - case CertificateExt.b64: - return GetPublicRSAParameters(LoadFromBase64(path)); - default: - logger.Error("Invalid certificate file extension"); - return new RSAParameters(); + Jwk jwk = Jwk.FromJson(json); +#if !NETCORE + publicKey.Exponent = Base64Url.Decode(jwk.E); + publicKey.Modulus = Base64Url.Decode(jwk.N); + return publicKey; +#else + if(jwk.E == null) + { + return LoadFromJwks(json, token); + } + else + { + publicKey.Exponent = Base64Url.Decode(jwk.E); + publicKey.Modulus = Base64Url.Decode(jwk.N); + return publicKey; + } +#endif + } + catch(Exception) + { + + return LoadFromJwks(json, token); + } + + } + + private static RSAParameters LoadFromJwks(string json, string token) + { + logger.Debug("LoadFromJwks"); + RSAParameters publicKey = new RSAParameters(); + try + { + JwkSet jwks = JwkSet.FromJson(json); + IDictionary headers = JWT.Headers(token); + string kid = headers["kid"]; + foreach (Jwk jwk in jwks) + { + if (jwk.KeyId.Equals(kid)) + { + publicKey.Exponent = Base64Url.Decode(jwk.E); + publicKey.Modulus = Base64Url.Decode(jwk.N); + } + } + logger.Error("No matching token kid to jwks"); + } + catch(Exception e) + { + logger.Error("LoadFromJwks", e); + } + return publicKey; + } + + + private static string FixType(string input) + { + try + { + string extension = Path.GetExtension(input).Replace(".", string.Empty).Trim(); +#if !NETCORE + return extension.IsNullOrEmpty() ? "b64" : extension; +#else + if (extension.IsNullOrEmpty()) + { + try + { + Base64.Decode(input); + return "b64"; + } + catch (Exception) + { + return "json"; + } + } + else + { + return extension; + } +#endif + } + catch (ArgumentException) + { + return "json"; } } private static Org.BouncyCastle.X509.X509Certificate LoadFromBase64(string base64) { logger.Debug("LoadFromBase64"); - Console.WriteLine("LoadFromBase64"); try { return new X509CertificateParser().ReadCertificate(Base64.Decode(base64)); @@ -97,14 +195,22 @@ private static Org.BouncyCastle.X509.X509Certificate LoadFromBase64(string base6 private static RSAParameters GetPublicRSAParameters(Org.BouncyCastle.X509.X509Certificate cert) { - X509Certificate2 cert2 = new X509Certificate2(DotNetUtilities.ToX509Certificate(cert)); - Console.WriteLine("GetPublicRSAParameters" + cert2.GetSerialNumberString()); - return cert2.GetRSAPublicKey().ExportParameters(false); + logger.Debug("GetPublicRSAParameters"); + try + { + X509Certificate2 cert2 = new X509Certificate2(DotNetUtilities.ToX509Certificate(cert)); + Console.WriteLine("GetPublicRSAParameters" + cert2.GetSerialNumberString()); + return cert2.GetRSAPublicKey().ExportParameters(false); + }catch(Exception e) + { + logger.Error("GetPublicRSAParameters", e); + return new RSAParameters(); + } } private static Org.BouncyCastle.X509.X509Certificate LoadFromPkcs12(string path, string alias, string password) { - logger.Debug("Loading pkcs12 certificate"); + logger.Debug("LoadFromPkcs12"); if (password.IsNullOrEmpty()) { logger.Error("LoadFromPkcs12: password is null or empty"); @@ -140,7 +246,7 @@ private static Org.BouncyCastle.X509.X509Certificate LoadFromPkcs12(string path, } private static Org.BouncyCastle.X509.X509Certificate LoadFromPkcs8(string path) { - logger.Debug("Loading pkcs8 certificate"); + logger.Debug("LoadFromPkcs8"); using (StreamReader streamReader = new StreamReader(path)) { PemReader pemReader = null; @@ -173,7 +279,7 @@ private static Org.BouncyCastle.X509.X509Certificate LoadFromPkcs8(string path) private static Org.BouncyCastle.X509.X509Certificate LoadFromDer(string path) { - logger.Debug("Loading der certificate"); + logger.Debug("LoadFromDer"); try { using (FileStream fs = new FileStream(path, FileMode.Open)) diff --git a/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj b/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj index aa1e6c526..79a4922f0 100644 --- a/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj +++ b/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj @@ -13,14 +13,12 @@ - - - + diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs deleted file mode 100644 index aa02ed41f..000000000 --- a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestCertificate.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.IO; -using NUnit.Framework; -using GamUtils.Utils; -using GamUtils; - -namespace GamTest.Utils -{ - [TestFixture] - public class TestCertificate - { -#pragma warning disable CS0414 - private static string resources; - private static string path_RSA_sha256_2048; - private static string alias; - private static string password; - private static string tokenFile; -#pragma warning disable IDE0044 - private static string BASE_PATH; -#pragma warning restore IDE0044 -#pragma warning restore CS0414 - - [SetUp] - public virtual void SetUp() - { - BASE_PATH = TestJwt.GetStartupDirectory(); - resources = Path.Combine(BASE_PATH, "Resources", "dummycerts"); - path_RSA_sha256_2048 = Path.Combine(resources, "RSA_sha256_2048"); - string kid = Guid.NewGuid().ToString(); - alias = "1"; - password = "dummy"; - string header = "{\n" + - " \"alg\": \"RS256\",\n" + - " \"kid\": \"" + kid + "\",\n" + - " \"typ\": \"JWT\"\n" + - "}"; - string payload = "{\n" + - " \"sub\": \"1234567890\",\n" + - " \"name\": \"John Doe\",\n" + - " \"iat\": 1516239022\n" + - "}"; - tokenFile = Jwt.Create(TestJwt.LoadPrivateKey(path_RSA_sha256_2048 + "\\sha256d_key.pem"), payload, header); - } - - - [Test] - public void TestLoadCrt() - { - bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.crt", "", password, tokenFile); - Assert.IsTrue(result, "TestLoadCrt"); - } - - [Test] - public void TestLoadCer() - { - bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.cer", "", password, tokenFile); - Assert.IsTrue(result, "TestLoadCer"); - } - - [Test] - [Ignore("issues with pfx extension in .Net")] - public void TestLoadPfx() - { - bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.pfx", "", password, tokenFile); - Assert.IsTrue(result, "TestLoadPfx"); - } - - [Test] - public void TestLoadPkcs12() - { - bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.pkcs12", "", password, tokenFile); - Assert.IsTrue(result, "TestLoadPkcs12"); - } - - [Test] - public void TestLoadP12() - { - bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.p12", "", password, tokenFile); - Assert.IsTrue(result, "TestLoadP12"); - } - - [Test] - public void TestLoadPem() - { - bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.pem", "", password, tokenFile); - Assert.IsTrue(result, "TestLoadPem"); - } - - [Test] - public void TestLoadKey() - { - bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.key", "", password, tokenFile); - Assert.IsTrue(result, "TestLoadKey"); - } - - [Test] - public void TestLoadBase64() - { - string base64 = "MIIEATCCAumgAwIBAgIJAIAqvKHZ+gFhMA0GCSqGSIb3DQEBCwUAMIGWMQswCQYDVQQGEwJVWTETMBEGA1UECAwKTW9udGV2aWRlbzETMBEGA1UEBwwKTW9udGV2aWRlbzEQMA4GA1UECgwHR2VuZVh1czERMA8GA1UECwwIU2VjdXJpdHkxEjAQBgNVBAMMCXNncmFtcG9uZTEkMCIGCSqGSIb3DQEJARYVc2dyYW1wb25lQGdlbmV4dXMuY29tMB4XDTIwMDcwODE4NTcxN1oXDTI1MDcwNzE4NTcxN1owgZYxCzAJBgNVBAYTAlVZMRMwEQYDVQQIDApNb250ZXZpZGVvMRMwEQYDVQQHDApNb250ZXZpZGVvMRAwDgYDVQQKDAdHZW5lWHVzMREwDwYDVQQLDAhTZWN1cml0eTESMBAGA1UEAwwJc2dyYW1wb25lMSQwIgYJKoZIhvcNAQkBFhVzZ3JhbXBvbmVAZ2VuZXh1cy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1zgaU+Wh63p9DNWoAy64252EvZjN49AY3x0QCnAa8JO9Pk7znQwrxEFUKgZzv0GHEYW7+X+uyJr7BW4TA6fuJJ8agE/bmZRZyjdJjoue0FML6fbmCZ9Tsxpxe4pzispyWQ8jYT4Kl4I3fdZNUSn4XSidnDKBISeC05mrcchDKhInpiYDJ481lsB4JTEti3S4Xy/ToKwY4t6attw6z5QDhBc+Yro+YUqruliOAKqcfybe9k07jwMCvFVM1hrYYJ7hwHDSFo3MKwZ0y2gw0w6SgVBxLFo+KYP3q63b5wVhD8lzaSh+8UcyiHM2/yjEej7EnRFzdclTSNXRFNaiLnEVdAgMBAAGjUDBOMB0GA1UdDgQWBBQtQAWJRWNr/OswPSAdwCQh0Eei/DAfBgNVHSMEGDAWgBQtQAWJRWNr/OswPSAdwCQh0Eei/DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCjHe3JbNKv0Ywc1zlLacUNWcjLbmzvnjs8Wq5oxtf5wG5PUlhLSYZ9MPhuf95PlibnrO/xVY292P5lo4NKhS7VOonpbPQ/PrCMO84Pz1LGfM/wCWQIowh6VHq18PiZka9zbwl6So0tgClKkFSRk4wpKrWX3+M3+Y+D0brd8sEtA6dXeYHDtqV0YgjKdZIIOx0vDT4alCoVQrQ1yAIq5INT3cSLgJezIhEadDv3Tc7bMxMFeL+81qHm9Z/9/KE6Z+JB0ZEOkF/2NSQJd+Z7MBR8CxOdTQis3ltMoXDatNkjZ2Env40sw4NICB8YYhsWMIarew5uNT+RS28YHNlbmogh"; - bool result = GamUtilsEO.VerifyJWTWithFile(base64 , "", "", tokenFile); - Assert.IsTrue(result, "TestLoadKey"); - } - } -} diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwk.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwk.cs index 51bad2206..3956853e3 100644 --- a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwk.cs +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwk.cs @@ -9,26 +9,10 @@ namespace GamTest.Utils [TestFixture] public class TestJwk { -#pragma warning disable CS0414 - private static string testJWK; - private static string header; - private static string payload; -#pragma warning restore CS0414 [SetUp] public virtual void SetUp() { - testJWK = "{\"p\":\"2XZj5mZxLJlFjN0rK45gg25TtaDUrJ38-EK4F6n60X13Vb4oSeOUNWr7w1S2ibh7RFD687lKY588APrXK1zF33Ape3pRDz3JFZdPx5K_g_hK-ZlLNlHzXTk0okWqIszKdi2v_RLH-zow4GE-rwtW-bKDj3pdKB0_KWafhIv7X5c\",\"kty\":\"RSA\",\"q\":\"1ZsAPTJAcVLDVNFa_cNjzg0NS9DZZYsga22ESKPXy_pPkH0oOzlRm40BcYxiPR2yVDx0Ya7x_ekXQ9K-pKBE_U0YBE2PR6rDUV6Vr21O9BNuWUNXCg_VYosmyVF4hEG0itJty7OYXZPRCr9hAWRl7DjqGKZ1Y5wnaNMCR4gGuss\",\"d\":\"VxkWReeOVfMKlbi2Grf_XIddyMzZ0oid5BRjagXYnmtjxlddcIUrS0vJGPqSSbtyDN7-gPB98rSsJfzDBx3tbN9Vjr6vCs3pk_mi6xnCA1iKbIvW3wM3s4rP_6vCMBdwgSxIHufpLsmB9esPBuwYpOdEXJvRk_F6swSR6J6gBcNR3uL8Ht0OxtfiDP0X3C2aHe5HM9jkLlrqjcNWZDu1dXnDGh2fILF5lAPI7qssYuZzddOE5I7GMh3DuwfQ73W3ITyiezELJMnDKaEQUJAAEDWoqcGCGB14jDJwyKSNROouQtby_RP2uM-IO3_Hq1-u2Wu1QCXNK3R17NVeV_ktZw\",\"e\":\"AQAB\",\"use\":\"sig\",\"kid\":\"c22bd870-634c-4860-9ccf-e38eca0b315b\",\"qi\":\"j5iACnxbBCPfPIv-QcGID0xLFWZAN7wU9t3B_16M-axl8OOQ0ll4ZjQ4hYmw_eYOk9TY7HbzR3SqfLoCh_As5QFvZhO1E_9JHw2IXDBBbkXY5m3vCGtrUwQXPX83nIHlVk6pJh6d5A3tfLm5ECz0nkiYbGdmtISsMiR-zfVryng\",\"dp\":\"prU01o8YGcmSYO-4RZbLdFZiw-18vKwNH0D-od2EU47sqgWyGxrlJqJSSScrHJ8ZmIDAMZGNbpvGwzWJOEvRwX3ZvzhA5f9GpU-vMF7WhNQWngwfdZATkhblu7TOPgli-IAD123Lc1Pj3k-OX2DBF4D7jEWRHsx0_EcY6OLrHRc\",\"alg\":\"RS256\",\"dq\":\"F6f03NIl5Ob_jvMompX7BaTYZh8ZFG_WBU-5qLnMemCcUyopPHXandl94W9kqdQSHdYcJX1Ue4RG-VHrnxvIyCyzjjZwucUloGtTNHxslAda3zPf_dNHFITIpN8K88q7DezEEB0xsJtgOUp8mcTerMyY0GYO9hsjGi7UP8vGwwU\",\"n\":\"tXMsASuh2-d6MJWifChlbsGKpcMYJtpczMeMdtZHdZgPBR-y2obZMOVjiuVOciU6bV8BtmLjc1IF1xENfL0LFgO9G9QvUyFfLHIhZR7c-NsELe5tC0aH_tDqYtjDTb-o9s6FZREFTrFy4R8jc6ZmfHtUPpzrv1SC3-cr1-sCi9TXlUtHRmYOLDbJFqriuRMhWxd7iPqeVac7tqGWCa_ALDERjDaZa0TLLLEbO6EubiLfk5lavO0jWOw9dxsvYouV0JGbxeczyevis5vC3XD3_yQJVC-r37lNDRiMbDD8hclMa75HXYJp7LNvScB5K6YERzfSullL7DF2q09dGVKCvQ\"}"; - header = "{\n" + - " \"alg\": \"RS256\",\n" + - " \"kid\": \"c22bd870-634c-4860-9ccf-e38eca0b315b\",\n" + - " \"typ\": \"JWT\"\n" + - "}"; - payload = "{\n" + - " \"sub\": \"1234567890\",\n" + - " \"name\": \"John Doe\",\n" + - " \"iat\": 1516239022\n" + - "}"; } [Test] @@ -55,33 +39,5 @@ public void TestPublicJwk() Assert.Fail("Exception on testPublicJwk" + e.Message); } } - - - [Test] - public void TestCreateJwt() - { - string jwt = GamUtilsEO.Jwk_createJwt(testJWK, payload, header); - Assert.NotNull(jwt, "testCreateJwt fail"); - } - - - [Test] - public void TestVerifyJwt() - { - string jwt = GamUtilsEO.Jwk_createJwt(testJWK, payload, header); - bool result = GamUtilsEO.Jwk_verifyJWT(testJWK, jwt); - Assert.IsTrue(result, "testVerifyJwt fail"); - } - - - [Test] - public void TestVerifyJwt_wrong() - { - string jwk = GamUtilsEO.GenerateKeyPair(); - string jwt = GamUtilsEO.Jwk_createJwt(jwk, payload, header); - bool result = GamUtilsEO.Jwk_verifyJWT(testJWK, jwt); - Assert.IsFalse(result, "testVerifyJwt_wrong fail"); - } - } } diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwks.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwks.cs deleted file mode 100644 index c099afdb7..000000000 --- a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwks.cs +++ /dev/null @@ -1,45 +0,0 @@ -using NUnit.Framework; -using GamUtils; - -namespace GamTest.Utils -{ - [TestFixture] - public class TestJwks - { -#pragma warning disable CS0414 - private static string testJWKs; - private static string testJWK; - private static string header; - private static string payload; - private static string kid; -#pragma warning restore CS0414 - - [SetUp] - public virtual void SetUp() - { - testJWK = "{\"p\":\"2XZj5mZxLJlFjN0rK45gg25TtaDUrJ38-EK4F6n60X13Vb4oSeOUNWr7w1S2ibh7RFD687lKY588APrXK1zF33Ape3pRDz3JFZdPx5K_g_hK-ZlLNlHzXTk0okWqIszKdi2v_RLH-zow4GE-rwtW-bKDj3pdKB0_KWafhIv7X5c\",\"kty\":\"RSA\",\"q\":\"1ZsAPTJAcVLDVNFa_cNjzg0NS9DZZYsga22ESKPXy_pPkH0oOzlRm40BcYxiPR2yVDx0Ya7x_ekXQ9K-pKBE_U0YBE2PR6rDUV6Vr21O9BNuWUNXCg_VYosmyVF4hEG0itJty7OYXZPRCr9hAWRl7DjqGKZ1Y5wnaNMCR4gGuss\",\"d\":\"VxkWReeOVfMKlbi2Grf_XIddyMzZ0oid5BRjagXYnmtjxlddcIUrS0vJGPqSSbtyDN7-gPB98rSsJfzDBx3tbN9Vjr6vCs3pk_mi6xnCA1iKbIvW3wM3s4rP_6vCMBdwgSxIHufpLsmB9esPBuwYpOdEXJvRk_F6swSR6J6gBcNR3uL8Ht0OxtfiDP0X3C2aHe5HM9jkLlrqjcNWZDu1dXnDGh2fILF5lAPI7qssYuZzddOE5I7GMh3DuwfQ73W3ITyiezELJMnDKaEQUJAAEDWoqcGCGB14jDJwyKSNROouQtby_RP2uM-IO3_Hq1-u2Wu1QCXNK3R17NVeV_ktZw\",\"e\":\"AQAB\",\"use\":\"sig\",\"kid\":\"c22bd870-634c-4860-9ccf-e38eca0b315b\",\"qi\":\"j5iACnxbBCPfPIv-QcGID0xLFWZAN7wU9t3B_16M-axl8OOQ0ll4ZjQ4hYmw_eYOk9TY7HbzR3SqfLoCh_As5QFvZhO1E_9JHw2IXDBBbkXY5m3vCGtrUwQXPX83nIHlVk6pJh6d5A3tfLm5ECz0nkiYbGdmtISsMiR-zfVryng\",\"dp\":\"prU01o8YGcmSYO-4RZbLdFZiw-18vKwNH0D-od2EU47sqgWyGxrlJqJSSScrHJ8ZmIDAMZGNbpvGwzWJOEvRwX3ZvzhA5f9GpU-vMF7WhNQWngwfdZATkhblu7TOPgli-IAD123Lc1Pj3k-OX2DBF4D7jEWRHsx0_EcY6OLrHRc\",\"alg\":\"RS256\",\"dq\":\"F6f03NIl5Ob_jvMompX7BaTYZh8ZFG_WBU-5qLnMemCcUyopPHXandl94W9kqdQSHdYcJX1Ue4RG-VHrnxvIyCyzjjZwucUloGtTNHxslAda3zPf_dNHFITIpN8K88q7DezEEB0xsJtgOUp8mcTerMyY0GYO9hsjGi7UP8vGwwU\",\"n\":\"tXMsASuh2-d6MJWifChlbsGKpcMYJtpczMeMdtZHdZgPBR-y2obZMOVjiuVOciU6bV8BtmLjc1IF1xENfL0LFgO9G9QvUyFfLHIhZR7c-NsELe5tC0aH_tDqYtjDTb-o9s6FZREFTrFy4R8jc6ZmfHtUPpzrv1SC3-cr1-sCi9TXlUtHRmYOLDbJFqriuRMhWxd7iPqeVac7tqGWCa_ALDERjDaZa0TLLLEbO6EubiLfk5lavO0jWOw9dxsvYouV0JGbxeczyevis5vC3XD3_yQJVC-r37lNDRiMbDD8hclMa75HXYJp7LNvScB5K6YERzfSullL7DF2q09dGVKCvQ\"}"; - string public_jwk = GamUtilsEO.GetPublicJwk(testJWK); - testJWKs = "{\"keys\": [" + public_jwk + "]}"; - header = "{\n" + - " \"alg\": \"RS256\",\n" + - " \"kid\": \"c22bd870-634c-4860-9ccf-e38eca0b315b\",\n" + - " \"typ\": \"JWT\"\n" + - "}"; - payload = "{\n" + - " \"sub\": \"1234567890\",\n" + - " \"name\": \"John Doe\",\n" + - " \"iat\": 1516239022\n" + - "}"; - kid = "c22bd870-634c-4860-9ccf-e38eca0b315b"; - } - - - [Test] - public void TestverifyJWT() - { - string jwt = GamUtilsEO.Jwk_createJwt(testJWK, payload, header); - bool result = GamUtilsEO.Jwks_verifyJWT(testJWKs, jwt, kid); - Assert.IsTrue(result, "testverifyJWT fail "); - } - } -} diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwt.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwt.cs index 374618ec9..60c727fa4 100644 --- a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwt.cs +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestJwt.cs @@ -3,16 +3,8 @@ using System.Reflection; using NUnit.Framework; using GamUtils; -using GamUtils.Utils; -using System.Security.Cryptography; using Microsoft.IdentityModel.Tokens; -using Org.BouncyCastle.Asn1.Pkcs; -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.OpenSsl; -using Org.BouncyCastle.Pkcs; -using Org.BouncyCastle.Security; -using System.Runtime.InteropServices; + @@ -25,12 +17,9 @@ public class TestJwt private static string resources; private static string header; private static string payload; - private static string kid; - private static RSAParameters keypair; private static string path_RSA_sha256_2048; private static string alias; private static string password; - private static string tokenFile; #pragma warning disable IDE0044 private static string BASE_PATH; #pragma warning restore IDE0044 @@ -43,7 +32,9 @@ public virtual void SetUp() { BASE_PATH = GetStartupDirectory(); resources = Path.Combine(BASE_PATH, "Resources", "dummycerts"); - kid = Guid.NewGuid().ToString(); + + string kid = Guid.NewGuid().ToString(); + header = "{\n" + " \"alg\": \"RS256\",\n" + " \"kid\": \"" + kid + "\",\n" + @@ -54,171 +45,143 @@ public virtual void SetUp() " \"name\": \"John Doe\",\n" + " \"iat\": 1516239022\n" + "}"; - keypair = GenerateKeys(); - path_RSA_sha256_2048 = Path.Combine(resources, "RSA_sha256_2048"); + alias = "1"; password = "dummy"; - tokenFile = Jwt.Create(LoadPrivateKey(path_RSA_sha256_2048 + "\\sha256d_key.pem"), payload, header); + path_RSA_sha256_2048 = Path.Combine(resources, "RSA_sha256_2048"); + } - internal static string GetStartupDirectory() + [Test] + public void Test_pkcs8_pem() { -#pragma warning disable SYSLIB0044 - string dir = Assembly.GetCallingAssembly().GetName().CodeBase; -#pragma warning restore SYSLIB0044 - Uri uri = new Uri(dir); - return Path.GetDirectoryName(uri.LocalPath); + string token = GamUtilsEO.CreateJwt(Path.Combine(path_RSA_sha256_2048, "sha256d_key.pem"), "", "", payload, header); + Assert.IsFalse(token.IsNullOrEmpty(), "Test_pkcs8_pem"); + bool result = GamUtilsEO.VerifyJwt(Path.Combine(path_RSA_sha256_2048, "sha256_cert.cer"), "", "", token); + Assert.IsTrue(result, "test_pkcs8 verify cer"); } - - private static RSAParameters GenerateKeys() + [Test] + public void Test_get() { - try - { - RSA rsa = RSA.Create(); - return rsa.ExportParameters(true); - } - catch (Exception) - { - return new RSAParameters(); - } + string token = GamUtilsEO.CreateJwt(Path.Combine(path_RSA_sha256_2048, "sha256d_key.pem"), "", "", payload, header); + Assert.IsFalse(token.IsNullOrEmpty(), "test_get create"); + string header_get = GamUtilsEO.GetJwtHeader(token); + Assert.IsFalse(header_get.IsNullOrEmpty(), "test_get getHeader"); + string payload_get = GamUtilsEO.GetJwtPayload(token); + Assert.IsFalse(payload_get.IsNullOrEmpty(), "test_get getPayload"); } - [Test] - public void TestCreate() + public void Test_pkcs8_key() { - try - { - string token = Jwt.Create(keypair, payload, header); - Assert.IsFalse(token.IsNullOrEmpty(), "testCreate fail"); - } - catch (Exception e) - { - Assert.Fail("testCreate fail. Exception: " + e.Message); - } + string token = GamUtilsEO.CreateJwt(Path.Combine(path_RSA_sha256_2048, "sha256d_key.key"), "", "", payload, header); + Assert.IsFalse(token.IsNullOrEmpty(), "test_pkcs8 create"); + bool result = GamUtilsEO.VerifyJwt(Path.Combine(path_RSA_sha256_2048, "sha256_cert.crt"), "", "", token); + Assert.IsTrue(result, "test_pkcs8 verify crt"); } - [Test] - public void TestVerify() + public void Test_pkcs12_p12() { - try - { - string token = Jwt.Create(keypair, payload, header); - bool verifies = Jwt.Verify(keypair, token); - Assert.IsTrue(verifies, "testVerify fail"); - } - catch (Exception e) - { - Assert.Fail("testVerify fail. Exception: " + e.Message); - } + string token = GamUtilsEO.CreateJwt(Path.Combine(path_RSA_sha256_2048, "sha256_cert.p12"), alias, password, payload, header); + Assert.IsFalse(token.IsNullOrEmpty(), "test_pkcs12_p12 create"); + bool result = GamUtilsEO.VerifyJwt(Path.Combine(path_RSA_sha256_2048, "sha256_cert.p12"), alias, password, token); + Assert.IsTrue(result, "test_pkcs12_p12 verify"); } - [Test] - public void TestVerify_wrong() + public void Test_pkcs12_pkcs12() { - try - { - string token = Jwt.Create(keypair, payload, header); - bool verifies = Jwt.Verify(GenerateKeys(), token); - Assert.IsFalse(verifies, "TestVerify_wrong fail"); - } - catch (Exception e) - { - Assert.Fail("testVerify_wrong fail. Exception: " + e.Message); - } + string token = GamUtilsEO.CreateJwt(Path.Combine(path_RSA_sha256_2048, "sha256_cert.pkcs12"), alias, password, payload, header); + Assert.IsFalse(token.IsNullOrEmpty(), "test_pkcs12_pkcs12 create"); + bool result = GamUtilsEO.VerifyJwt(Path.Combine(path_RSA_sha256_2048, "sha256_cert.pkcs12"), alias, password, token); + Assert.IsTrue(result, "test_pkcs12_pkcs12 verify"); } - [Test] - public void TestVerifyPkcs8() + [Ignore("issues with pfx extension in .Net")] + public void Test_pkcs12_pfx() { - bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.pem", "", "", tokenFile); - Assert.IsTrue(result, "testVerifyPkcs8"); + string token = GamUtilsEO.CreateJwt(Path.Combine(path_RSA_sha256_2048, "sha256_cert.pfx"), alias, password, payload, header); + Assert.IsFalse(token.IsNullOrEmpty(), "test_pkcs12_pfx create"); + bool result = GamUtilsEO.VerifyJwt(Path.Combine(path_RSA_sha256_2048, "sha256_cert.pfx"), alias, password, token); + Assert.IsTrue(result, "test_pkcs12_pfx verify"); } - [Test] - public void TestVerifyDer() + public void Test_pkcs12_noalias() { - bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.cer", "", "", tokenFile); - Assert.IsTrue(result, "testVerifyDer"); + string token = GamUtilsEO.CreateJwt(Path.Combine(path_RSA_sha256_2048, "sha256_cert.p12"), "", password, payload, header); + Assert.IsFalse(token.IsNullOrEmpty(), "test_pkcs12_noalias jks create"); + bool result = GamUtilsEO.VerifyJwt(Path.Combine(path_RSA_sha256_2048, "sha256_cert.p12"), "", password, token); + Assert.IsTrue(result, "test_pkcs12_noalias jks verify"); } - [Test] - public void TestVerifyPkcs12() + public void Test_b64() { - bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.p12", alias, password, tokenFile); - Assert.IsTrue(result, "testVerifyPkcs12"); + string publicKey = "MIIEATCCAumgAwIBAgIJAIAqvKHZ+gFhMA0GCSqGSIb3DQEBCwUAMIGWMQswCQYDVQQGEwJVWTETMBEGA1UECAwKTW9udGV2aWRlbzETMBEGA1UEBwwKTW9udGV2aWRlbzEQMA4GA1UECgwHR2VuZVh1czERMA8GA1UECwwIU2VjdXJpdHkxEjAQBgNVBAMMCXNncmFtcG9uZTEkMCIGCSqGSIb3DQEJARYVc2dyYW1wb25lQGdlbmV4dXMuY29tMB4XDTIwMDcwODE4NTcxN1oXDTI1MDcwNzE4NTcxN1owgZYxCzAJBgNVBAYTAlVZMRMwEQYDVQQIDApNb250ZXZpZGVvMRMwEQYDVQQHDApNb250ZXZpZGVvMRAwDgYDVQQKDAdHZW5lWHVzMREwDwYDVQQLDAhTZWN1cml0eTESMBAGA1UEAwwJc2dyYW1wb25lMSQwIgYJKoZIhvcNAQkBFhVzZ3JhbXBvbmVAZ2VuZXh1cy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1zgaU+Wh63p9DNWoAy64252EvZjN49AY3x0QCnAa8JO9Pk7znQwrxEFUKgZzv0GHEYW7+X+uyJr7BW4TA6fuJJ8agE/bmZRZyjdJjoue0FML6fbmCZ9Tsxpxe4pzispyWQ8jYT4Kl4I3fdZNUSn4XSidnDKBISeC05mrcchDKhInpiYDJ481lsB4JTEti3S4Xy/ToKwY4t6attw6z5QDhBc+Yro+YUqruliOAKqcfybe9k07jwMCvFVM1hrYYJ7hwHDSFo3MKwZ0y2gw0w6SgVBxLFo+KYP3q63b5wVhD8lzaSh+8UcyiHM2/yjEej7EnRFzdclTSNXRFNaiLnEVdAgMBAAGjUDBOMB0GA1UdDgQWBBQtQAWJRWNr/OswPSAdwCQh0Eei/DAfBgNVHSMEGDAWgBQtQAWJRWNr/OswPSAdwCQh0Eei/DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCjHe3JbNKv0Ywc1zlLacUNWcjLbmzvnjs8Wq5oxtf5wG5PUlhLSYZ9MPhuf95PlibnrO/xVY292P5lo4NKhS7VOonpbPQ/PrCMO84Pz1LGfM/wCWQIowh6VHq18PiZka9zbwl6So0tgClKkFSRk4wpKrWX3+M3+Y+D0brd8sEtA6dXeYHDtqV0YgjKdZIIOx0vDT4alCoVQrQ1yAIq5INT3cSLgJezIhEadDv3Tc7bMxMFeL+81qHm9Z/9/KE6Z+JB0ZEOkF/2NSQJd+Z7MBR8CxOdTQis3ltMoXDatNkjZ2Env40sw4NICB8YYhsWMIarew5uNT+RS28YHNlbmogh"; + string privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC1zgaU+Wh63p9DNWoAy64252EvZjN49AY3x0QCnAa8JO9Pk7znQwrxEFUKgZzv0GHEYW7+X+uyJr7BW4TA6fuJJ8agE/bmZRZyjdJjoue0FML6fbmCZ9Tsxpxe4pzispyWQ8jYT4Kl4I3fdZNUSn4XSidnDKBISeC05mrcchDKhInpiYDJ481lsB4JTEti3S4Xy/ToKwY4t6attw6z5QDhBc+Yro+YUqruliOAKqcfybe9k07jwMCvFVM1hrYYJ7hwHDSFo3MKwZ0y2gw0w6SgVBxLFo+KYP3q63b5wVhD8lzaSh+8UcyiHM2/yjEej7EnRFzdclTSNXRFNaiLnEVdAgMBAAECggEBAJP8ajslcThisjzg47JWGS8z1FXi2Q8hg1Yv61o8avcHEY0y8tdEKUnkQ3TT4E0M0CgsL078ATz4cNmvhzYIv+j66aEv3w/XRRhl/NWBqx1YsQV5BWHy5sz9Nhe+WnnlbbSa5Ie+4NfpG1LDv/Mi19RZVg15p5ZwHGrkDCP47VYKgFXw51ZPxq/l3IIeq4PyueC/EPSAp4e9qei7p85k3i2yiWsHgZaHwHgDTx2Hgq1y/+/E5+HNxL2OlPr5lzlN2uIPZ9Rix2LDh0FriuCEjrXFsTJHw4LTK04rkeGledMtw6/bOTxibFbgeuQtY1XzG/M0+xlP2niBbAEA4Z6vTsECgYEA6k7LSsh6azsk0W9+dE6pbc3HisOoKI76rXi38gEQdCuF04OKt46WttQh4r1+dseO4OgjXtRMS0+5Hmx2jFXjPJexMgLftvrbwaVqg9WHenKL/qj5imCn4kVaa4Jo1VHFaIY+1b+iv+6WY/leFxGntAki9u4PRogRrUrWLRH9keUCgYEAxqLisgMHQGcpJDHJtI2N+HUgLDN065PtKlEP9o6WBwAb86/InVaTo2gmEvmslNQDYH16zdTczWMHnnBx1B012KpUD+t5CWIvMZdsTnMRDjWhdgm5ylN9NT89t5X8GPvo36WjuXAKWWjcRodzRgo57z9achCyMKhGU5yDOxh8jhkCgYAx6rtwoSlDcwQzAjfEe4Wo+PAL5gcLLPrGvjMiAYwJ08Pc/ectl9kP9j2J2qj4kSclTw9KApyGZuOfUagn2Zxhqkd7yhTzHJp4tM7uay1DrueYR1NyYYkisXfD87J1z8forsDwNLVtglzTy6p56674sgGa7bifZBmv+4OJco286QKBgQC4dGXDHGDNg36G590A1zpw8ILxyM7YPEPOOfxy3rGeypEqV6AZy13KLlq84DFM+xwvrBYvsW1hJIbcsFpjuMRZ8MGjDu0Us6JTkOO4bc32vgKzlBB9O85XdeSf6J1zrenwVOaWut5BbMiwjfOTpMdrzg71QV/XI0w7NGoApJp1cQKBgERfI6AfJTaKtEpfX3udR1B3zra1Y42ppU2TvGI5J2/cItENoyRmtyKYDp2I036/Pe63nuIzs31i6q/hCr9Tv3AGoSVKuPLpCWv5xVO/BPhGs5dwx81nUo0/P+H2X8dx7g57PQY4uf4F9+EIXeAdbPqfB8GBW7RX3FDx5NpB+Hh/"; + string token = GamUtilsEO.CreateJwt(privateKey, "", "", payload, header); + Assert.IsFalse(token.IsNullOrEmpty(), "test_b64 create"); + bool result = GamUtilsEO.VerifyJwt(publicKey, "", "", token); + Assert.IsTrue(result, "test_b64 verify"); } - [Test] - public void TestVerifyPkcs12_withoutalias() + public void Test_json_jwk() { - bool result = GamUtilsEO.VerifyJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.p12", "", password, tokenFile); - Assert.IsTrue(result, "testVerifyPkcs12_withoutalias"); + string keyPair = GamUtilsEO.GenerateKeyPair(); + string token = GamUtilsEO.CreateJwt(keyPair, "", "", payload, header); + Assert.IsFalse(token.IsNullOrEmpty(), "test_json_jwk create"); + string publicJwk = GamUtilsEO.GetPublicJwk(keyPair); + bool result = GamUtilsEO.VerifyJwt(publicJwk, "", "", token); + Assert.IsTrue(result, "test_json_jwk verify"); } - internal static RSAParameters LoadPrivateKey(string path) + [Test] + public void Test_json_jwks() { - using (StreamReader streamReader = new StreamReader(path)) - { - PemReader pemReader = new PemReader(streamReader); - try - { - Object obj = pemReader.ReadObject(); - if (obj.GetType() == typeof(AsymmetricCipherKeyPair)) - { - AsymmetricCipherKeyPair asymKeyPair = (AsymmetricCipherKeyPair)obj; - PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(asymKeyPair.Private); - return CastPrivateKey(privateKeyInfo).ExportParameters(true); - }else - { - Assert.Fail("LoadPrivateKey unknown private key type"); - return new RSAParameters(); - } - } - catch (Exception e) - { - Assert.Fail("LoadPrivateKey fail with exception " + e.Message); - return new RSAParameters(); - } - finally - { - pemReader.Reader.Close(); - } - } - + string keyPair = GamUtilsEO.GenerateKeyPair(); + string publicJwk = GamUtilsEO.GetPublicJwk(keyPair); + string header_jwks = MakeHeader(publicJwk); + string token = GamUtilsEO.CreateJwt(keyPair, "", "", payload, header_jwks); + Assert.IsFalse(token.IsNullOrEmpty(), "test_json_jwks create"); + string publicJwks = "{\"keys\": [" + publicJwk + "]}"; + bool result = GamUtilsEO.VerifyJwt(publicJwks, "", "", token); + Assert.IsTrue(result, "test_json_jwks verify"); } - private static RSA CastPrivateKey(PrivateKeyInfo privateKeyInfo) + private static string GetStartupDirectory() { - byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetDerEncoded(); - string serializedPrivate = Convert.ToBase64String(serializedPrivateBytes); - RsaPrivateCrtKeyParameters privateKey = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(serializedPrivate)); - -#if NETCORE +#pragma warning disable SYSLIB0044 + string dir = Assembly.GetCallingAssembly().GetName().CodeBase; +#pragma warning restore SYSLIB0044 + Uri uri = new Uri(dir); + return Path.GetDirectoryName(uri.LocalPath); + } -if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) -{ -try - { - RSA rsa = RSA.Create(); - rsa.ImportPkcs8PrivateKey(serializedPrivateBytes, out int outthing); - return rsa; - }catch(Exception) - { - return null; - } -} -#endif - return DotNetUtilities.ToRSA(privateKey); + private static string MakeHeader(string publicJwk) + { + try + { + Jose.Jwk jwk = Jose.Jwk.FromJson(publicJwk); + return "{\n" + + " \"alg\": \"RS256\",\n" + + " \"kid\": \"" + jwk.KeyId + "\",\n" + + " \"typ\": \"JWT\"\n" + + "}"; + } + catch (Exception e) + { + Console.WriteLine(e.StackTrace); + return ""; + } } + + } } diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestPrivateKey.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestPrivateKey.cs deleted file mode 100644 index 252694100..000000000 --- a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestPrivateKey.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.IO; -using NUnit.Framework; -using GamUtils; -using Microsoft.IdentityModel.Tokens; - -namespace GamTest.Utils -{ - [TestFixture] - public class TestPrivateKey - { -#pragma warning disable CS0414 - private static string resources; - private static string path_RSA_sha256_2048; - private static string alias; - private static string password; -#pragma warning disable IDE0044 - private static string BASE_PATH; -#pragma warning restore IDE0044 -#pragma warning restore CS0414 - private static string header; - private static string payload; - - [SetUp] - public virtual void SetUp() - { - BASE_PATH = TestJwt.GetStartupDirectory(); - resources = Path.Combine(BASE_PATH, "Resources", "dummycerts"); - path_RSA_sha256_2048 = Path.Combine(resources, "RSA_sha256_2048"); - string kid = Guid.NewGuid().ToString(); - alias = "1"; - password = "dummy"; - header = "{\n" + - " \"alg\": \"RS256\",\n" + - " \"kid\": \"" + kid + "\",\n" + - " \"typ\": \"JWT\"\n" + - "}"; - payload = "{\n" + - " \"sub\": \"1234567890\",\n" + - " \"name\": \"John Doe\",\n" + - " \"iat\": 1516239022\n" + - "}"; - - } - - - [Test] - [Ignore("issues with pfx extension in .Net")] - public void TestLoadPfx() - { - string result = GamUtilsEO.CreateJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.pfx", "", password, payload, header ); - Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadPfx"); - } - - [Test] - public void TestLoadPkcs12() - { - string result = GamUtilsEO.CreateJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.pkcs12", "", password, payload, header); - Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadPkcs12"); - } - - [Test] - public void TestLoadP12() - { - string result = GamUtilsEO.CreateJWTWithFile(path_RSA_sha256_2048 + "\\sha256_cert.p12", "", password, payload, header); - Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadP12"); - } - - [Test] - public void TestLoadPem() - { - string result = GamUtilsEO.CreateJWTWithFile(path_RSA_sha256_2048 + "\\sha256d_key.pem", "", password, payload, header); - Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadPem"); - } - - [Test] - public void TestLoadKey() - { - string result = GamUtilsEO.CreateJWTWithFile(path_RSA_sha256_2048 + "\\sha256d_key.key", "", password, payload, header); - Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadKey"); - } - - [Test] - public void TestLoadBase64() - { - string base64 = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC1zgaU+Wh63p9DNWoAy64252EvZjN49AY3x0QCnAa8JO9Pk7znQwrxEFUKgZzv0GHEYW7+X+uyJr7BW4TA6fuJJ8agE/bmZRZyjdJjoue0FML6fbmCZ9Tsxpxe4pzispyWQ8jYT4Kl4I3fdZNUSn4XSidnDKBISeC05mrcchDKhInpiYDJ481lsB4JTEti3S4Xy/ToKwY4t6attw6z5QDhBc+Yro+YUqruliOAKqcfybe9k07jwMCvFVM1hrYYJ7hwHDSFo3MKwZ0y2gw0w6SgVBxLFo+KYP3q63b5wVhD8lzaSh+8UcyiHM2/yjEej7EnRFzdclTSNXRFNaiLnEVdAgMBAAECggEBAJP8ajslcThisjzg47JWGS8z1FXi2Q8hg1Yv61o8avcHEY0y8tdEKUnkQ3TT4E0M0CgsL078ATz4cNmvhzYIv+j66aEv3w/XRRhl/NWBqx1YsQV5BWHy5sz9Nhe+WnnlbbSa5Ie+4NfpG1LDv/Mi19RZVg15p5ZwHGrkDCP47VYKgFXw51ZPxq/l3IIeq4PyueC/EPSAp4e9qei7p85k3i2yiWsHgZaHwHgDTx2Hgq1y/+/E5+HNxL2OlPr5lzlN2uIPZ9Rix2LDh0FriuCEjrXFsTJHw4LTK04rkeGledMtw6/bOTxibFbgeuQtY1XzG/M0+xlP2niBbAEA4Z6vTsECgYEA6k7LSsh6azsk0W9+dE6pbc3HisOoKI76rXi38gEQdCuF04OKt46WttQh4r1+dseO4OgjXtRMS0+5Hmx2jFXjPJexMgLftvrbwaVqg9WHenKL/qj5imCn4kVaa4Jo1VHFaIY+1b+iv+6WY/leFxGntAki9u4PRogRrUrWLRH9keUCgYEAxqLisgMHQGcpJDHJtI2N+HUgLDN065PtKlEP9o6WBwAb86/InVaTo2gmEvmslNQDYH16zdTczWMHnnBx1B012KpUD+t5CWIvMZdsTnMRDjWhdgm5ylN9NT89t5X8GPvo36WjuXAKWWjcRodzRgo57z9achCyMKhGU5yDOxh8jhkCgYAx6rtwoSlDcwQzAjfEe4Wo+PAL5gcLLPrGvjMiAYwJ08Pc/ectl9kP9j2J2qj4kSclTw9KApyGZuOfUagn2Zxhqkd7yhTzHJp4tM7uay1DrueYR1NyYYkisXfD87J1z8forsDwNLVtglzTy6p56674sgGa7bifZBmv+4OJco286QKBgQC4dGXDHGDNg36G590A1zpw8ILxyM7YPEPOOfxy3rGeypEqV6AZy13KLlq84DFM+xwvrBYvsW1hJIbcsFpjuMRZ8MGjDu0Us6JTkOO4bc32vgKzlBB9O85XdeSf6J1zrenwVOaWut5BbMiwjfOTpMdrzg71QV/XI0w7NGoApJp1cQKBgERfI6AfJTaKtEpfX3udR1B3zra1Y42ppU2TvGI5J2/cItENoyRmtyKYDp2I036/Pe63nuIzs31i6q/hCr9Tv3AGoSVKuPLpCWv5xVO/BPhGs5dwx81nUo0/P+H2X8dx7g57PQY4uf4F9+EIXeAdbPqfB8GBW7RX3FDx5NpB+Hh/"; - string result = GamUtilsEO.CreateJWTWithFile(base64 , "", "", payload, header); - Assert.IsFalse(result.IsNullOrEmpty(), "TestLoadKey"); - } - } -} diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestUnixTimestamp.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestUnixTimestamp.cs new file mode 100644 index 000000000..64321c0a7 --- /dev/null +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestUnixTimestamp.cs @@ -0,0 +1,37 @@ +using System; +using NUnit.Framework; +using System.Globalization; +using GamUtils; + +namespace GamTest.Utils +{ + [TestFixture] + public class TestUnixTimestamp + { + + [Test] + public void TestCreate() + { + DateTime one = CreateDate("2024/02/02 02:02:02"); //1706839322 + DateTime two = CreateDate("2023/03/03 03:03:03"); //1677812583 + DateTime three = CreateDate("2022/04/04 04:04:04"); //1649045044 + DateTime four = CreateDate("2020/02/02 02:22:22"); //1580610142 + DateTime five = CreateDate("2010/05/05 05:05:05"); //1273035905 + DateTime six = CreateDate("2000/05/05 05:05:05"); //957503105 + + DateTime[] arrayDates = new DateTime[] { one, two, three, four, five, six }; + long[] arrayStamps = new long[] { 1706839322L, 1677812583L, 1649045044L, 1580610142L, 1273035905L, 957503105L}; + + for (int i = 0; i < arrayDates.Length; i++) + { + Assert.AreEqual(GamUtilsEO.CreateUnixTimestamp(arrayDates[i]), arrayStamps[i], "testCreate"); + } + } + + private static DateTime CreateDate(string date) + { + return DateTime.ParseExact(date, "yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture); + } + + } +} From de01a25de1ced788a31a37a22966570483b95839 Mon Sep 17 00:00:00 2001 From: sgrampone Date: Thu, 15 Aug 2024 15:19:05 -0300 Subject: [PATCH 09/16] Fix GamUtils projects PackageId --- .../extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj | 2 +- .../extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj index 1432b2164..3998721ce 100644 --- a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj +++ b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj @@ -5,7 +5,7 @@ GamUtilsNetImpl 17.4.0 CA1031, CA1801, SYSLIB0027 - GeneXxus.Gam.Utils.Net + Gam.Utils.Net diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj index aced046db..5ba330b65 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj @@ -3,7 +3,7 @@ net47 GamUtilsImpl CA1031, CA1801 - Genexus.Gam.Utils + Gam.Utils True From d7893b91a128b6f5bd2f12984538f81a51a59d09 Mon Sep 17 00:00:00 2001 From: sgrampone Date: Mon, 19 Aug 2024 12:16:37 -0300 Subject: [PATCH 10/16] Add DynamicCall EO to GamUtils --- .../src/DotNet/GamUtilsNet/GamUtilsNet.csproj | 1 + .../GamUtils/Utils/DynamicCall.cs | 207 ++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/DynamicCall.cs diff --git a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj index 3998721ce..2c289eaa9 100644 --- a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj +++ b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj @@ -16,6 +16,7 @@ + diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/DynamicCall.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/DynamicCall.cs new file mode 100644 index 000000000..23041618c --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/DynamicCall.cs @@ -0,0 +1,207 @@ +using System; +using System.Text; +using System.Reflection; +using System.IO; +using System.Globalization; +using GeneXus.Application; +using log4net; + +#if NETCORE +using GxClasses.Helpers; +using GeneXus.Utils; +#endif + +namespace GamUtils.Utils +{ + public class DynamicCall + { + + private IGxContext mGxContext; + private static readonly ILog logger = LogManager.GetLogger(typeof(DynamicCall)); + + /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + public DynamicCall(IGxContext context) + { + mGxContext = context; + } + + public bool Execute(string assembly, string typeName, bool useContext, string method, string jsonParms, out string jsonOutput) + { + logger.Debug("Execute"); + return DoCall(assembly, typeName, useContext, method, false, "", jsonParms, out jsonOutput); + } + + public bool ExecuteEventHandler(string assembly, string typeName, bool useContext, string method, string eventType, string jsonInput, out string jsonOutput) + { + logger.Debug("ExecuteEventHandler"); + return DoCall(assembly, typeName, useContext, method, true, eventType, jsonInput, out jsonOutput); + } + + + /********EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/ + + + private bool DoCall(string assembly, string typeName, bool useContext, string method, bool isEventHandler, string input1, string input2, out string jsonOutput) + { + logger.Debug("DoCall"); + try + { + jsonOutput = "{}"; + Assembly assm; + if (Path.IsPathRooted(assembly)) + assm = Assembly.LoadFrom(assembly); + else + assm = Assembly.LoadFrom(Path.Combine(GetStartupDirectory(), assembly)); + + if (assm != null) + { + Type type = assm.GetType(typeName); + if (type != null) + { + object instance = null; + if (useContext && (mGxContext != null)) + { + ConstructorInfo constructorWithContext = type.GetConstructor(new Type[] { typeof(IGxContext) }); + if (constructorWithContext != null) + { + instance = constructorWithContext.Invoke(new object[] { mGxContext }); + } + } + if (instance == null) + instance = assm.CreateInstance(typeName); + + if (instance != null) + { + MethodInfo methodInfo; + object[] parameters; + + if (isEventHandler) + { + methodInfo = instance.GetType().GetMethod(method, new Type[] { input1.GetType(), input2.GetType(), jsonOutput.GetType().MakeByRefType() }); + parameters = new object[] { input1, input2, jsonOutput }; + } + else + { + methodInfo = instance.GetType().GetMethod(method, new Type[] { input2.GetType(), jsonOutput.GetType().MakeByRefType() }); + parameters = new object[] { input2, jsonOutput }; + } + + if (methodInfo != null) + { + object result = methodInfo.Invoke(instance, parameters); + if (methodInfo.ReturnType == typeof(void) && (parameters.Length > 0)) + jsonOutput = (string)parameters[parameters.Length - 1]; + else + jsonOutput = result.ToString(); + + return true; + } + else + { + logger.Error("error: " + method + "(String, out String)" + " in " + assembly + " not found"); + jsonOutput = "{\"error\":\"" + method + "(String, out String)" + " in " + assembly + " not found" + "\"}"; + return false; + } + } + else + { + logger.Error("error: " + "constructor for " + typeName + " in " + assembly + " not found"); + jsonOutput = "{\"error\":\"" + "constructor for " + typeName + " in " + assembly + " not found" + "\"}"; + return false; + } + } + else + { + logger.Error("error: " + typeName + " in " + assembly + " not found"); + jsonOutput = "{\"error\":\"" + typeName + " in " + assembly + " not found" + "\"}"; + return false; + } + } + else + { + logger.Error("error: " + assembly + " not found"); + jsonOutput = "{\"error\":\"" + assembly + " not found" + "\"}"; + return false; + } + } + catch (Exception ex) + { + StringBuilder str = new StringBuilder(); + str.Append(ex.Message); + while (ex.InnerException != null) + { + str.Append(ex.InnerException.Message); + ex = ex.InnerException; + } + logger.Error("error: " + Enquote(str.ToString())); + jsonOutput = "{\"error\":" + Enquote(str.ToString()) + "}"; + return false; + } + } + + private static string GetStartupDirectory() + { + logger.Debug("GetStartupDirectory"); +#if NETCORE + return FileUtil.GetStartupDirectory(); +#else + string dir = Path.GetDirectoryName(Assembly.GetCallingAssembly().GetName().CodeBase); ; + if (dir.StartsWith("file:\\")) + dir = dir.Substring(6); + return dir; +#endif + } + + + private static string Enquote(string s) + { + logger.Debug("Enquote)"); + if (s == null || s.Length == 0) + return "\"\""; + + int length = s.Length; + StringBuilder sb = new StringBuilder(length + 4); + + sb.Append('"'); + + for (int index = 0; index < length; index++) + { + char ch = s[index]; + + if ((ch == '\\') || (ch == '"') || (ch == '>')) + { + sb.Append('\\'); + sb.Append(ch); + } + else if (ch == '\b') + sb.Append("\\b"); + else if (ch == '\t') + sb.Append("\\t"); + else if (ch == '\n') + sb.Append("\\n"); + else if (ch == '\f') + sb.Append("\\f"); + else if (ch == '\r') + sb.Append("\\r"); + else + { + if (ch < ' ') + { + //t = "000" + Integer.toHexString(c); + //string tmp = new string(ch, 1); + string t = "000" + ((int)ch).ToString(CultureInfo.InvariantCulture); + sb.Append("\\u" + t.Substring(t.Length - 4)); + } + else + { + sb.Append(ch); + } + } + } + + sb.Append('"'); + return sb.ToString(); + } + } +} From 6846b23fe5cbe9fb8a4ca650cc940d147a04841a Mon Sep 17 00:00:00 2001 From: sgrampone Date: Fri, 30 Aug 2024 15:53:46 -0300 Subject: [PATCH 11/16] Add sha256 and b64url encoding for PKCE implementation --- .../src/DotNet/GamUtilsNet/GamUtilsNet.csproj | 1 + .../DotNetFramework/GamUtils/GamUtilsEO.cs | 11 ++++- .../GamUtils/Utils/Cryprography/Encryption.cs | 2 +- .../GamUtils/Utils/Cryprography/Hash.cs | 38 +++++++++++---- .../GamUtils/Utils/Encoding.cs | 28 +++++++++++ .../test/DotNet/GamTestNet/GamTestNet.csproj | 1 + .../GamTest/Utils/TestEncoding.cs | 46 +++++++++++++++++++ .../DotNetFramework/GamTest/Utils/TestHash.cs | 12 +++++ 8 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Encoding.cs create mode 100644 dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestEncoding.cs diff --git a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj index 2c289eaa9..31b80e78a 100644 --- a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj +++ b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj @@ -23,6 +23,7 @@ + diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs index 970a5dd84..9f3d51428 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtilsEO.cs @@ -15,7 +15,13 @@ public class GamUtilsEO [SecuritySafeCritical] public static string Sha512(string plainText) { - return Hash.Sha512(plainText); + return HashUtil.Hashing(plainText, Hash.SHA512); + } + + [SecuritySafeCritical] + public static string Sha256(string plainText) + { + return HashUtil.Hashing(plainText, Hash.SHA256); } //**ENCRYPTION**// @@ -67,5 +73,8 @@ public static string RandomHexaBits(int bits) [SecuritySafeCritical] public static string GetJwtPayload(string token) { return Jwt.GetPayload(token); } + + //**ENCODING**// + public static string Base64ToBase64Url(string base64) { return Encoding.B64ToB64Url(base64); } } } diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Encryption.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Encryption.cs index 7e2dd0336..b50517451 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Encryption.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Encryption.cs @@ -18,7 +18,7 @@ internal class Encryption [SecuritySafeCritical] public static string AesGcm(string input, string key, string nonce, int macSize, bool toEncrypt) { - return toEncrypt ? Base64.ToBase64String(Internal_AesGcm(Encoding.UTF8.GetBytes(input), key, nonce, macSize, toEncrypt)) : Encoding.UTF8.GetString(Internal_AesGcm(Base64.Decode(input), key, nonce, macSize, toEncrypt)); + return toEncrypt ? Base64.ToBase64String(Internal_AesGcm(System.Text.Encoding.UTF8.GetBytes(input), key, nonce, macSize, toEncrypt)) : System.Text.Encoding.UTF8.GetString(Internal_AesGcm(Base64.Decode(input), key, nonce, macSize, toEncrypt)); } [SecuritySafeCritical] diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Hash.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Hash.cs index 966134ce9..6fabc32a0 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Hash.cs +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Cryprography/Hash.cs @@ -9,26 +9,46 @@ namespace GamUtils.Utils { [SecuritySafeCritical] - public class Hash + internal enum Hash { + NONE, SHA512, SHA256 + } - private static readonly ILog logger = LogManager.GetLogger(typeof(Hash)); + [SecuritySafeCritical] + public class HashUtil + { + + private static readonly ILog logger = LogManager.GetLogger(typeof(HashUtil)); [SecuritySafeCritical] - internal static string Sha512(string plainText) + internal static string Hashing(string plainText, Hash hash) { + switch (hash) + { + case Hash.SHA256: + return InternalHash(new Sha256Digest(), plainText); + case Hash.SHA512: + return InternalHash(new Sha512Digest(), plainText); + default: + logger.Error("unrecognized hash"); + return ""; + } + } + private static string InternalHash(IDigest digest, string plainText) + { + logger.Debug("InternalHash"); if (String.IsNullOrEmpty(plainText)) { - logger.Error("sha512 plainText is empty"); + logger.Error("hash plainText is empty"); return ""; } - byte[] inputBytes = Encoding.UTF8.GetBytes(plainText); - IDigest alg = new Sha512Digest(); - byte[] retValue = new byte[alg.GetDigestSize()]; - alg.BlockUpdate(inputBytes, 0, inputBytes.Length); - alg.DoFinal(retValue, 0); + byte[] inputBytes = System.Text.Encoding.UTF8.GetBytes(plainText); + byte[] retValue = new byte[digest.GetDigestSize()]; + digest.BlockUpdate(inputBytes, 0, inputBytes.Length); + digest.DoFinal(retValue, 0); return Base64.ToBase64String(retValue); } } } + diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Encoding.cs b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Encoding.cs new file mode 100644 index 000000000..3dc97497e --- /dev/null +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/Utils/Encoding.cs @@ -0,0 +1,28 @@ +using System; +using Org.BouncyCastle.Utilities.Encoders; +using log4net; +using System.Security; + +namespace GamUtils.Utils +{ + [SecuritySafeCritical] + internal class Encoding + { + private static readonly ILog logger = LogManager.GetLogger(typeof(Encoding)); + + [SecuritySafeCritical] + internal static string B64ToB64Url(string input) + { + logger.Debug("B64ToB64Url"); + try + { + return System.Text.Encoding.UTF8.GetString(UrlBase64.Encode(Base64.Decode(input))); + } + catch (Exception e) + { + logger.Error("B64ToB64Url", e); + return ""; + } + } + } +} diff --git a/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj b/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj index 79a4922f0..f4e830680 100644 --- a/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj +++ b/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj @@ -19,6 +19,7 @@ + diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestEncoding.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestEncoding.cs new file mode 100644 index 000000000..add62090e --- /dev/null +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestEncoding.cs @@ -0,0 +1,46 @@ +using System; +using System.Text; +using NUnit.Framework; +using GamUtils; +using Org.BouncyCastle.Utilities.Encoders; + +namespace GamTest.Utils +{ + [TestFixture] + public class TestEncoding + { + [SetUp] + public virtual void SetUp() + { + + } + + [Test] + public void TestB64ToB64Url() + { + int i = 0; + do + { + string randomString = GamUtilsEO.RandomAlphanumeric(128); + string testing = GamUtilsEO.Base64ToBase64Url(Base64.ToBase64String(Encoding.UTF8.GetBytes(randomString))); + Assert.AreEqual(randomString, B64UrlToUtf8(testing), "TestB64ToB64Url"); + i++; + } while (i < 50); + } + + private static string B64UrlToUtf8(string base64Url) + { + try + { + byte[] bytes = UrlBase64.Decode(base64Url); + return Encoding.UTF8.GetString(bytes); + } + catch (Exception e) + { + Console.WriteLine(e.StackTrace); + return ""; + } + } + + } +} diff --git a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestHash.cs b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestHash.cs index 10e3b5227..46a7093e1 100644 --- a/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestHash.cs +++ b/dotnet/src/extensions/gam/test/DotNetFramework/GamTest/Utils/TestHash.cs @@ -1,6 +1,7 @@ using GamTest.Utils.Resources; using NUnit.Framework; using GamUtils; +using System; namespace GamTest.Utils { @@ -47,5 +48,16 @@ public void TestSha512Random() Assert.AreEqual(cryptographicHash.ComputeHash(value), GamUtilsEO.Sha512(value), "random sha512 "); } } + + [Test] + public void TestSha256() + { + string[] arrayInputs = { one, two, three, four, five }; + string[] arrayRes = { "dpLDrTVAu4A8Ags67mbNiIcSMjTqDG5xQ8Ct1z/0Me0=", "P8TM/nRYcOLA2Z9x8w/wZWyN7dQcwdfT03aw2+aF4vM=", "i1udsME9skJWyCmqNkqpDG0uujGLkjKkq5MTuVTTVV8=", "BO+vCA9aPnThwp0cpqSFaTgsu80yTo1Z0rg+8hwDnwA=", "IisL1R/O9+ZcLmLbLtZUVwE7q1a+b6/rGe4R1FMVPIA=" }; + for (int i = 0; i < arrayInputs.Length; i++) + { + Assert.AreEqual(GamUtilsEO.Sha256(arrayInputs[i]), arrayRes[i], "TestSha256 error"); + } + } } } \ No newline at end of file From 38627063935ee6dc4c57aca74e7b07a2c7cce939 Mon Sep 17 00:00:00 2001 From: Claudia Beatriz Murialdo Garrone Date: Tue, 10 Sep 2024 12:26:09 -0300 Subject: [PATCH 12/16] Update BouncyCastle to version 2.4.0 for testing projects in the beta branch This update aligns with the changes introduced in PR #1047, which necessitates upgrading BouncyCastle to version 2.4.0. --- .../extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj | 2 +- .../extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj index 31b80e78a..e3ea84e97 100644 --- a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj +++ b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj @@ -27,7 +27,7 @@ - + diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj index 5ba330b65..758d8126c 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj @@ -10,7 +10,7 @@ - + From 126fc2ce33e56785cb384808995ac99d33ee465e Mon Sep 17 00:00:00 2001 From: Claudia Beatriz Murialdo Garrone Date: Tue, 10 Sep 2024 12:32:36 -0300 Subject: [PATCH 13/16] Update BouncyCastle to version 2.4.0 to align with the changes introduced in PR #1047. --- .../GeneXusCryptographyNetCore.csproj | 2 +- .../dotnetcore/GeneXusJWTNetCore/GeneXusJWTNetCore.csproj | 2 +- .../GeneXusXmlSignatureNetCore.csproj | 2 +- .../SecurityAPICommonsNetCore.csproj | 2 +- .../GeneXusCryptography/GeneXusCryptography.csproj | 4 ++-- .../dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj | 2 +- .../GeneXusXmlSignature/GeneXusXmlSignature.csproj | 2 +- .../SecurityAPICommons/SecurityAPICommons.csproj | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusCryptographyNetCore/GeneXusCryptographyNetCore.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusCryptographyNetCore/GeneXusCryptographyNetCore.csproj index 174ed6a9a..23ce5bf84 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusCryptographyNetCore/GeneXusCryptographyNetCore.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusCryptographyNetCore/GeneXusCryptographyNetCore.csproj @@ -68,7 +68,7 @@ - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusJWTNetCore/GeneXusJWTNetCore.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusJWTNetCore/GeneXusJWTNetCore.csproj index 96047c388..60adc91d7 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusJWTNetCore/GeneXusJWTNetCore.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusJWTNetCore/GeneXusJWTNetCore.csproj @@ -33,7 +33,7 @@ - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusXmlSignatureNetCore/GeneXusXmlSignatureNetCore.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusXmlSignatureNetCore/GeneXusXmlSignatureNetCore.csproj index 666954743..252a66f4d 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusXmlSignatureNetCore/GeneXusXmlSignatureNetCore.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusXmlSignatureNetCore/GeneXusXmlSignatureNetCore.csproj @@ -26,7 +26,7 @@ - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj index 7bdacca1e..2346a7ad4 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj @@ -34,7 +34,7 @@ - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/GeneXusCryptography.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/GeneXusCryptography.csproj index 1d9a763cc..17b58f372 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/GeneXusCryptography.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusCryptography/GeneXusCryptography.csproj @@ -1,4 +1,4 @@ - + net47 GeneXusCryptography @@ -7,7 +7,7 @@ GeneXus.SecurityApi.Cryptography - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj index 2cac667b1..18fa6ecca 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj @@ -16,7 +16,7 @@ - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/GeneXusXmlSignature.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/GeneXusXmlSignature.csproj index ea8ad6834..f4fcb3ff5 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/GeneXusXmlSignature.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusXmlSignature/GeneXusXmlSignature.csproj @@ -7,7 +7,7 @@ GeneXus.SecurityApi.XmlSignature - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/SecurityAPICommons.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/SecurityAPICommons.csproj index 4a9c504e2..85efd61da 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/SecurityAPICommons.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/SecurityAPICommons/SecurityAPICommons.csproj @@ -7,7 +7,7 @@ - + From 03e204ccb7a7d88c460d6aab11a4cccddf4e6fcb Mon Sep 17 00:00:00 2001 From: sgrampone Date: Mon, 14 Oct 2024 16:22:52 -0300 Subject: [PATCH 14/16] Strong naming GamUtils dll --- dotnet/src/extensions/gam/gamkey.snk | Bin 0 -> 596 bytes .../src/DotNetFramework/GamUtils/GamUtils.csproj | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 dotnet/src/extensions/gam/gamkey.snk diff --git a/dotnet/src/extensions/gam/gamkey.snk b/dotnet/src/extensions/gam/gamkey.snk new file mode 100644 index 0000000000000000000000000000000000000000..caa9e0fe99857ae09ac4223af4c7a0e167eaf2df GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096^SQTIu24O(y6V*x(0LM@Y2S0PFQp6!C zdQfSvx}E#7$nMCy$2v!VSLHeY$YWC~V}C&uk}!q);2G%|kE2`}`F#KKQU|8&-?~gG zFa1dn#G(VM=^JizCLJ@{h<`_Sg8}tk;(R!0z$K2_s}#`HU~SGek6kpu(PD7Hk=~xExj0IMkU|0}rw5mdA_#{j-+wg@>wvQLwNTL(d?Q_WaY6hqzq@?Po92{1F}bANG^l9E{e$;_9*uXrq_e$hnCZcQpH}c zN!$aqr9!5;6J_m!VI?G6KF9<$Lo8zt#XojG-FX|bTx@W)0C#R3u23g+o=?lDSt@@& z?yVD~`lwSOhv)kn2_lIVtlvIugnrXC2T$hpg;>H*wc}e)%a3CarDMj0OB2l-yWeSV zUYT`}B{V?3io+59E{ROf5YPE?i|n#fsbh1sIZR>h8baFC>)apg!-QrG96zDz=er$h ierU`p)izH=IIz5rJm#VItq%V;F9-)U=EuoFmyo@&LK_bN literal 0 HcmV?d00001 diff --git a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj index 758d8126c..a3776e3dd 100644 --- a/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj +++ b/dotnet/src/extensions/gam/src/DotNetFramework/GamUtils/GamUtils.csproj @@ -4,6 +4,8 @@ GamUtilsImpl CA1031, CA1801 Gam.Utils + True + ..\..\..\gamkey.snk True From 597a8afccdce393686c7872eac7e06c08f02e5b4 Mon Sep 17 00:00:00 2001 From: claudiamurialdo <33756655+claudiamurialdo@users.noreply.github.com> Date: Tue, 12 Nov 2024 10:28:18 -0300 Subject: [PATCH 15/16] Remove unused target framework net6.0 from GamUtilsNet.csproj --- .../extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj index e3ea84e97..dd3d7ecd5 100644 --- a/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj +++ b/dotnet/src/extensions/gam/src/DotNet/GamUtilsNet/GamUtilsNet.csproj @@ -1,7 +1,7 @@ - net6.0;net8.0 + net8.0 GamUtilsNetImpl 17.4.0 CA1031, CA1801, SYSLIB0027 From 2ea6bee275b92b278af1cb9d2fb2f92a36dbeda7 Mon Sep 17 00:00:00 2001 From: claudiamurialdo <33756655+claudiamurialdo@users.noreply.github.com> Date: Tue, 12 Nov 2024 10:28:42 -0300 Subject: [PATCH 16/16] Remove unused target framework net6.0 from GamTestNet.csproj --- .../src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj b/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj index f4e830680..1d3da5008 100644 --- a/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj +++ b/dotnet/src/extensions/gam/test/DotNet/GamTestNet/GamTestNet.csproj @@ -1,7 +1,7 @@ - net6.0;net8.0 + net8.0 false CS0618,CA1707 false