From c7cfdec6ed80838711c4c651c910e7986b3dd5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20Aas=20Sja=CC=8Afjell?= Date: Fri, 23 Sep 2016 12:10:38 +0200 Subject: [PATCH 01/10] Legger til enkel overload for CertificateChainValidator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nå kan man få tilbake en fin streng for den detaljerte feilinformasjonen. Vi kaller det også det nå, og ikke chainStatus, så vet man at det er noe kjipt --- .../CertificateChainValidator.cs | 22 ++++++++++++++++--- SharedAssemblyInfo.cs | 4 ++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Difi.Felles.Utility/CertificateChainValidator.cs b/Difi.Felles.Utility/CertificateChainValidator.cs index 960f1b8..a2ac1b8 100755 --- a/Difi.Felles.Utility/CertificateChainValidator.cs +++ b/Difi.Felles.Utility/CertificateChainValidator.cs @@ -30,13 +30,29 @@ public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat) /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// /// - /// Status på kjeden etter validering. + /// Status på kjeden etter validering hvis validering feilet. /// Kastes hvis det prøves å gjøre validering mot andre sertifikater enn de i . /// - public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat, out X509ChainStatus[] kjedestatus) + public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat, out string detaljertFeilinformasjon) + { + X509ChainStatus[] chainStatuses; + var erGyldigSertifikatkjede = ErGyldigSertifikatkjede(sertifikat, out chainStatuses); + detaljertFeilinformasjon = chainStatuses.Aggregate("", (result, curr) => $"{curr.Status}: {curr.StatusInformation}"); + + return erGyldigSertifikatkjede; + } + + /// + /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot + /// + /// + /// Status på kjeden etter validering hvis validering feilet. + /// Kastes hvis det prøves å gjøre validering mot andre sertifikater enn de i . + /// + public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat, out X509ChainStatus[] detaljertFeilinformasjon) { var chain = BuildCertificateChain(sertifikat); - kjedestatus = chain.ChainStatus; + detaljertFeilinformasjon = chain.ChainStatus; ValidateThatUsingOnlyValidatorCertificatesOrThrow(chain,sertifikat); diff --git a/SharedAssemblyInfo.cs b/SharedAssemblyInfo.cs index e2b15dd..5a73eff 100755 --- a/SharedAssemblyInfo.cs +++ b/SharedAssemblyInfo.cs @@ -5,8 +5,8 @@ [assembly: AssemblyTrademark("Direktoratet for forvaltning og IKT (Difi)")] [assembly: AssemblyProduct("Difi Felles Utility")] [assembly: AssemblyDescription("Bibliotek brukt av Difi i klientbiblioteker")] -[assembly: AssemblyVersion("0.7.0.*")] -[assembly: AssemblyFileVersion("0.7.0.*")] +[assembly: AssemblyVersion("0.8.0.*")] +[assembly: AssemblyFileVersion("0.8.0.*")] [assembly: AssemblyCopyright("© 2015-2016 Direktoratet for forvaltning og IKT (Difi)")] [assembly: AssemblyCulture("")] From c36fbb1dc9791218aa39f709f6a29da5bb830c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20Aas=20Sja=CC=8Afjell?= Date: Fri, 23 Sep 2016 16:24:11 +0200 Subject: [PATCH 02/10] Legger til ValidateCertificate og oppdaterer sertifikater MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Vi kan nå validere sertifikat og få en informativ feilmelding for alle scenarioer vi tidligere har validert. - Har lagt til nye testsertifikater som har SERIALNUMBER satt, slik at vi får testet som ønsket for alle scenarier. Tidligere ville de feile av at de manglet serienummer for utgåtte, så testene fungerte egentlig ikke som ønsket. --- .../CertificateValidatorTests.cs | 87 ++++++++++++++++-- .../Difi.Felles.Utility.Tester.csproj | 5 +- .../Enhetstester/ExpiredTestCertificate.cer | Bin 786 -> 1335 bytes .../NotActivatedTestCertificate.cer | Bin 788 -> 1123 bytes Difi.Felles.Utility/CertificateValidator.cs | 44 ++++++++- .../Difi.Felles.Utility.csproj | 2 + .../SertifikatValideringType.cs | 9 ++ .../SertifikatValideringsResultat.cs | 17 ++++ 8 files changed, 153 insertions(+), 11 deletions(-) create mode 100755 Difi.Felles.Utility/SertifikatValideringType.cs create mode 100755 Difi.Felles.Utility/SertifikatValideringsResultat.cs diff --git a/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs b/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs index 38a7d84..3158e29 100755 --- a/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs +++ b/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs @@ -7,11 +7,84 @@ namespace Difi.Felles.Utility.Tester public class CertificateValidatorTests { - - public class IsValidServerSertifikatMethod : CertificateValidatorTests + public class ValidateCertificate : CertificateValidatorTests { [Fact] - public void ReturnsFalseWithNullCertificate() + public void Returns_fail_with_null_certificate() + { + //Arrange + + //Act + var result = CertificateValidator.ValidateCertificate(null, "123456789"); + + //Assert + Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); + Assert.NotNull(result.Melding); + } + + [Fact] + public void Returns_fail_if_not_issued_to_organization_number() + { + //Arrange + var organizationNumber = "123456789"; + + //Act + var result = CertificateValidator.ValidateCertificate(SertifikatUtility.TestIntegrasjonssertifikat(), organizationNumber); + + //Assert + Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); + Assert.NotNull(result.Melding); + } + + [Fact] + public void Returns_fail_if_not_activated() + { + //Arrange + var sertifikatOrganisasjonsnummer = "988015814"; + + //Act + var result = CertificateValidator.ValidateCertificate(SertifikatUtility.NotActivatedTestCertificate(), sertifikatOrganisasjonsnummer); + + //Assert + Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); + Assert.NotNull(result.Melding); + } + + [Fact] + public void Returns_fail_if_expired() + { + //Arrange + var sertifikatOrganisasjonsnummer = "988015814"; + + //Act + var result = CertificateValidator.ValidateCertificate(SertifikatUtility.GetExpiredTestCertificate(), sertifikatOrganisasjonsnummer); + + //Assert + Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); + Assert.NotNull(result.Melding); + } + + [Fact] + public void Returns_ok_if_valid() + { + //Arrange + var sertifikatOrganisasjonsnummer = "984661185"; + + //Act + var result = CertificateValidator.ValidateCertificate(SertifikatUtility.GetPostenCertificate(), sertifikatOrganisasjonsnummer); + + //Assert + Assert.Equal(SertifikatValideringType.Gyldig, result.Type); + Assert.NotNull(result.Melding); + } + + + } + + public class IsValidCertificateMethod : CertificateValidatorTests + { + [Fact] + public void Returns_false_with_null_certificate() { //Arrange var certificateOrganizationNumber = "123456789"; @@ -24,7 +97,7 @@ public void ReturnsFalseWithNullCertificate() } [Fact] - public void ReturnsFalseIfNotIssuedToServerOrganizationNumber() + public void Returns_false_if_not_issued_to_organization_number() { //Arrange var sertifikatOrganisasjonsnummer = "123456789"; @@ -37,7 +110,7 @@ public void ReturnsFalseIfNotIssuedToServerOrganizationNumber() } [Fact] - public void ReturnsFalseIfNotActivated() + public void Returns_false_if_not_activated() { //Arrange var sertifikatOrganisasjonsnummer = "123456789"; @@ -50,7 +123,7 @@ public void ReturnsFalseIfNotActivated() } [Fact] - public void ReturnsFalseIfExpired() + public void Returns_false_if_expired() { //Arrange var sertifikatOrganisasjonsnummer = "123456789"; @@ -63,7 +136,7 @@ public void ReturnsFalseIfExpired() } [Fact] - public void ReturnsTrueForCorrectCertificate() + public void Returns_true_for_correct_certificate() { //Arrange var sertifikatOrganisasjonsnummer = "984661185"; diff --git a/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj b/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj index 179d073..836f92e 100755 --- a/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj +++ b/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj @@ -117,8 +117,6 @@ - - @@ -126,6 +124,8 @@ Designer + + @@ -136,7 +136,6 @@ - diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ExpiredTestCertificate.cer b/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ExpiredTestCertificate.cer index fd50658f6088e4cbe13fd8412db0be3c1521f54b..644f04d62b9863b5c37a4648aaec5436a32c02e8 100755 GIT binary patch literal 1335 zcmXqLVl_5sVv%3K%*4pVB(OI$Wd3?K`Pq)0YZVXWuK#Sn$;PV9$IK+l%3#oV!H^rs zXAWgy6K3-BHxxAB2XVNBIh=w#{oEBCgAE&J8Z=G=2{Owy_A$6HWHO`!aREa0KvT?C|II!l1EIY52@+=Nh|zI2ACKoVqL zFwl$~hBBZDAe-`lydtQOSUpjZ>@5qwPB{BO@a#19KB2KZ8LNBNtN>BO}A3V@2kE z=X%5+=wFzawpKJ%tYr3se}dfVmY`^&?2g%1s@|1W(hH7sUfJXK zb@Ha-g{A_gXW#z)VxRDB!^8X4@3gnR^*&XUef*~7nmL!0w4coXQ7GLNQy^j-7yqw? z&-M95jm;Iey?ka|K5$v&X!E;QcJn_Jt?n>f&v`gasQNr}kDq?f=Sww{V<$|yz~Ge< zUa;;(3Dd0qUoVGs9KG^yomz|HTF&I&e&$!Q-iqySHoQ1vo%HDj@5@_@>!qun&0^y? z&ANZ-M=wMBpBH);^Eg^-d(Vz)6X_}E&Fb>Egfq=>Rgm~ z=sa`BXH_OkO^m$25a9%3R$!u$Wn^jmYtZp9*p|4%>Mnku>2e2Y|_ik>TRZ*IXK`md|-Fr<^p<)n05;BvsAoonF4PSJwEJY{UO&*QLrL zIeiu{=TrVP-N8nFi_wAAp*HKMO6vxTu|0a##Bgx?*DvpixtISG&U&|7WUgr2mnL!N zT}r#FHks^v_x)Qz>T9NzURB(D*(-fIl`~iTvicj);PUOI_f`en<^M-5WfyiVJ(ew%b?>3R90q^b{lL!Z=r aWVhwrll*N%YCunEuc4;X;uTi)Ul;&FSE%p+ literal 786 zcmXqLV&*ewV*Is$nTe5!iN$Keo`VLQY^>UR%uKSZ3UIPO|BVz*~0)i-FjcH<3 z0@}u@)#lOmotKf3k(GhDiIJZH=sqr{CPqevm6w#vkb1qxe_FI$s8~Q<2>;!U zle#XS;ALX9KbO4ABHDFJh*jg?6poF#s%`ZV>vIZTX#0tNH;vR{FW)um)Q0ff)!UD= z-c|juT&7k;^1Ud_tKCJrPiX(^D%iHB`n*zJYq(dP1KYeh*+*ACNM3*brRL~K-hJW^ zK0flj6t*+vLgnfUYo_fln(((H&C$6GyWO0p!TGxa6??um*F#c;jyVo)|T4b^26y6n^xlX+h-7B-R;IdGu z_d}IPgU>%NnsvN>&THj7Tf&n?xViOF(%jNdY}~QBiraWCZZk16GB7UoGw?C+0!D!> zBa5?vV}k&vm}-QcTGKVP*U3U1eb;6 z-u$2a_g;URF?+J>%`IjMfqT5~?hg3;;X9Lj&ff#)K5O5Sh*`Brjk8GM26N`ef`yT9 zMSp0m+$}M)V}g?1TrJV4h>|;@&yFhjP4`=~*?!m2E0aGw@7?70ZLVGFfkbPgu&`3c zzwF;Tc1kTRoU4DMk3Fc^zJ9ILQ~TdL93RX%`0lIb>Wt*6xBoe62c7G=laRPh$u0U> zobmj7Hx%btEHJ+AF16{w;=jLdYB-3V4M}(-sQ2gBl#5FqZxvdst7f_U#P;)B0iwV) AD*ylh diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/NotActivatedTestCertificate.cer b/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/NotActivatedTestCertificate.cer index a362ce0d1ac0ea9d474b272d3a9de21ba40eeb67..e831f186cd5fc713dcee0b58a37588f7aec27bc5 100755 GIT binary patch literal 1123 zcmXqLVu?3sV)kCZ%*4pVB(TTv!u>`2UM}|3n$5%>^uf!3lZ{oIkC{o9mBFB~(~uj; zXAWgy6K3-BHxxAB2XVNBIh=w#{oEBCgAIcX0zpE|!d@6r!j#U%fv7wQX0T4t11&mMx29*0AF)}hdI#y)vcdkeLf&PVwX=_DO#Y$#B_$SD%Zu$9$<@@Y> zqea`dm~LPZ$?lkKrRrU2CB5KC=aoHvUng%WUT7*{diL$#FZK!FHaxsv{Z4!9Tklgv z*~f2Mu9#f-SX2Xj!)=8gk@V>mYxL&&I*(^4W)2#cKe)KZ5|9PQzF^{9Qw)gD#X6OEQCqm{e zIdSFgbhoa3JN;~v*Rt<6+tRW2qs~Q%ht4y1d{$**W@KPo+<3&G@t{HDK45gqGO{#o zGico0AP}@Vxb8{1^&Ib)|EHgwd&g^GW6xlU+9rH?1{leV3~M@~UWPy7me6WT%R1FA zBKOh2%%AJmCE>kq%4S5mOnIuIo~sd2r*=~du7QkFiU1n!i9=Tj_cp|XD$4_tHy14Q+3*^q!yyy=Qco*GmVa35hRWd%dkrKXt|B4e2jyI1T?! zyLQXtU*+|kk~&*Am(0JY#FS7ptKoo@1gH9=tN-rA6=kt{u9{I>`0g!(*o)Sz?Vnpd z-W3vA;`wtzVS&pUR%uKSZ3+%U+CRY1%$-69~UAKf-HU3TE*qE!@Rv)oGr{IOQpXhhfNG>6~om-Tbi@eee6l;IG>eSgC@nO={=}k_)?ndV{?#@5= zcunH2`1wrpf2~ax*I1}^J*fX)^jrz!zt*#REpwwq7Hdx7U9p+#)CHRG-qr#U4Ck3XNTxzlkL_Es&A($J}tSU_DD2e zVC9LMeu)zvTQ96#{6(JiUHsHN&R1_0D``E;;l35KXQ64&4!@jzr&rN21uU!1^ z_>qG-GGgtIkL>?=@bsf!mJ_R=DNR{3G4$+wsnx4rMy{+BQJs=`S=2J~OUl{cMc=18 zovPf*boe%d`;(;Wf@>A+V*bukO=WkjFwK6pdh)^dUqcF$lnUCGt=a97`0yA2eDF1q diff --git a/Difi.Felles.Utility/CertificateValidator.cs b/Difi.Felles.Utility/CertificateValidator.cs index 9490779..5cf3802 100755 --- a/Difi.Felles.Utility/CertificateValidator.cs +++ b/Difi.Felles.Utility/CertificateValidator.cs @@ -10,6 +10,38 @@ public static bool IsValidCertificate(X509Certificate2 certificate, string certi return certificate != null && IsIssuedToOrganizationNumber(certificate, certificateOrganizationNumber) && IsActiveCertificate(certificate); } + public static SertifikatValideringsResultat ValidateCertificate(X509Certificate2 certificate, string certificateOrganizationNumber) + { + if (certificate == null) + { + return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"Sertifikat var {null}!"); + } + + if (!IsIssuedToOrganizationNumber(certificate, certificateOrganizationNumber)) + { + return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, + $"Sertifikatet er ikke utstedt til organisasjonsnummer '{certificateOrganizationNumber}'. Dette vil skje om sertifikatet er utstedt til en annen virksomhet " + + $"eller hvis det ikke er et virksomhetssertifikat. Virksomhetssertifikat kan skaffes fra Buypass eller Commfides."); + } + + if (!IsActivatedCertificate(certificate)) + { + return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"Sertifikat '{GetCertificateInfo(certificate)}' aktiveres ikke før {certificate.GetEffectiveDateString()}."); + } + + if (IsExpiredCertificate(certificate)) + { + return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"Sertifikat '{GetCertificateInfo(certificate)}' gikk ut {certificate.GetExpirationDateString()}."); + } + + return new SertifikatValideringsResultat(SertifikatValideringType.Gyldig, $"Sertifikat '{GetCertificateInfo(certificate)}' er et gyldig sertifikat."); + } + + private static string GetCertificateInfo(X509Certificate2 certificate) + { + return $"Subject: {certificate.Subject}, Thumbprint: {certificate.Thumbprint}"; //TODO: Lag som extensionmetode + } + private static bool IsIssuedToOrganizationNumber(X509Certificate certificate, string certificateOrganizationNumber) { return certificate.Subject.Contains($"SERIALNUMBER={certificateOrganizationNumber}") || certificate.Subject.Contains($"CN={certificateOrganizationNumber}"); @@ -17,7 +49,17 @@ private static bool IsIssuedToOrganizationNumber(X509Certificate certificate, st private static bool IsActiveCertificate(X509Certificate certificate) { - return DateTime.Now > DateTime.Parse(certificate.GetEffectiveDateString()) && DateTime.Now < DateTime.Parse(certificate.GetExpirationDateString()); + return IsActivatedCertificate(certificate) && !IsExpiredCertificate(certificate); + } + + private static bool IsActivatedCertificate(X509Certificate certificate) + { + return DateTime.Now > DateTime.Parse(certificate.GetEffectiveDateString()); + } + + private static bool IsExpiredCertificate(X509Certificate certificate) + { + return DateTime.Now > DateTime.Parse(certificate.GetExpirationDateString()); } } } \ No newline at end of file diff --git a/Difi.Felles.Utility/Difi.Felles.Utility.csproj b/Difi.Felles.Utility/Difi.Felles.Utility.csproj index fe1f2c3..afab07a 100755 --- a/Difi.Felles.Utility/Difi.Felles.Utility.csproj +++ b/Difi.Felles.Utility/Difi.Felles.Utility.csproj @@ -47,6 +47,8 @@ Properties\SharedAssemblyInfo.cs + + diff --git a/Difi.Felles.Utility/SertifikatValideringType.cs b/Difi.Felles.Utility/SertifikatValideringType.cs new file mode 100755 index 0000000..7a02f87 --- /dev/null +++ b/Difi.Felles.Utility/SertifikatValideringType.cs @@ -0,0 +1,9 @@ +namespace Difi.Felles.Utility +{ + public enum SertifikatValideringType + { + Gyldig, + UgyldigSertifikat, + UgyldigKjede + } +} \ No newline at end of file diff --git a/Difi.Felles.Utility/SertifikatValideringsResultat.cs b/Difi.Felles.Utility/SertifikatValideringsResultat.cs new file mode 100755 index 0000000..3ecd932 --- /dev/null +++ b/Difi.Felles.Utility/SertifikatValideringsResultat.cs @@ -0,0 +1,17 @@ +using System; + +namespace Difi.Felles.Utility +{ + public class SertifikatValideringsResultat + { + public SertifikatValideringsResultat(SertifikatValideringType type, string melding) + { + Type = type; + Melding = melding; + } + + public SertifikatValideringType Type { get; set; } + + public string Melding { get; set; } + } +} From a377ea9a2ca3ef862e3b48c77ee68710db7c3922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20Aas=20Sja=CC=8Afjell?= Date: Fri, 23 Sep 2016 16:56:37 +0200 Subject: [PATCH 03/10] Lager extensionmetode for info om sertifikat --- Difi.Felles.Utility/CertificateChainValidator.cs | 3 ++- Difi.Felles.Utility/CertificateValidator.cs | 9 +++++---- Difi.Felles.Utility/Difi.Felles.Utility.csproj | 1 + .../Extensions/X509Certificate2Extensions.cs | 12 ++++++++++++ 4 files changed, 20 insertions(+), 5 deletions(-) create mode 100755 Difi.Felles.Utility/Extensions/X509Certificate2Extensions.cs diff --git a/Difi.Felles.Utility/CertificateChainValidator.cs b/Difi.Felles.Utility/CertificateChainValidator.cs index a2ac1b8..4203be3 100755 --- a/Difi.Felles.Utility/CertificateChainValidator.cs +++ b/Difi.Felles.Utility/CertificateChainValidator.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Security.Cryptography.X509Certificates; using Difi.Felles.Utility.Exceptions; +using Difi.Felles.Utility.Extensions; namespace Difi.Felles.Utility { @@ -82,7 +83,7 @@ private void ValidateThatUsingOnlyValidatorCertificatesOrThrow(X509Chain chain, var chainAsString = chain.ChainElements.Cast().Aggregate("",(result, curr) => GetCertificateInfo(result, curr.Certificate)); var validatorCertificatesAsString = SertifikatLager.Cast().Aggregate("", GetCertificateInfo); - throw new CertificateChainValidationException($"Validering av sertifikat '{sertifikat.Subject}' (thumbprint '{sertifikat.Thumbprint}') feilet. Dette skjer fordi kjeden ble bygd " + + throw new CertificateChainValidationException($"Validering av sertifikat '{sertifikat.Info()}' feilet. Dette skjer fordi kjeden ble bygd " + $"med følgende sertifikater {chainAsString}, men kun følgende er godkjent for å bygge kjeden: {validatorCertificatesAsString}. Dette skjer som oftest " + "om sertifikater blir hentet fra Certificate Store på Windows, og det tillates ikke under validering. Det er kun gyldig å bygge en " + "kjede med de sertifikatene sendt inn til validatoren."); diff --git a/Difi.Felles.Utility/CertificateValidator.cs b/Difi.Felles.Utility/CertificateValidator.cs index 5cf3802..dce622e 100755 --- a/Difi.Felles.Utility/CertificateValidator.cs +++ b/Difi.Felles.Utility/CertificateValidator.cs @@ -1,5 +1,6 @@ using System; using System.Security.Cryptography.X509Certificates; +using Difi.Felles.Utility.Extensions; namespace Difi.Felles.Utility { @@ -26,20 +27,20 @@ public static SertifikatValideringsResultat ValidateCertificate(X509Certificate2 if (!IsActivatedCertificate(certificate)) { - return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"Sertifikat '{GetCertificateInfo(certificate)}' aktiveres ikke før {certificate.GetEffectiveDateString()}."); + return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"{GetCertificateInfo(certificate)} aktiveres ikke før {certificate.GetEffectiveDateString()}."); } if (IsExpiredCertificate(certificate)) { - return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"Sertifikat '{GetCertificateInfo(certificate)}' gikk ut {certificate.GetExpirationDateString()}."); + return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"{ GetCertificateInfo(certificate) } gikk ut {certificate.GetExpirationDateString()}."); } - return new SertifikatValideringsResultat(SertifikatValideringType.Gyldig, $"Sertifikat '{GetCertificateInfo(certificate)}' er et gyldig sertifikat."); + return new SertifikatValideringsResultat(SertifikatValideringType.Gyldig, $"{GetCertificateInfo(certificate)} er et gyldig sertifikat."); } private static string GetCertificateInfo(X509Certificate2 certificate) { - return $"Subject: {certificate.Subject}, Thumbprint: {certificate.Thumbprint}"; //TODO: Lag som extensionmetode + return $"Sertifikat '{certificate.Info()}'"; } private static bool IsIssuedToOrganizationNumber(X509Certificate certificate, string certificateOrganizationNumber) diff --git a/Difi.Felles.Utility/Difi.Felles.Utility.csproj b/Difi.Felles.Utility/Difi.Felles.Utility.csproj index afab07a..1a04538 100755 --- a/Difi.Felles.Utility/Difi.Felles.Utility.csproj +++ b/Difi.Felles.Utility/Difi.Felles.Utility.csproj @@ -47,6 +47,7 @@ Properties\SharedAssemblyInfo.cs + diff --git a/Difi.Felles.Utility/Extensions/X509Certificate2Extensions.cs b/Difi.Felles.Utility/Extensions/X509Certificate2Extensions.cs new file mode 100755 index 0000000..c4e0e0a --- /dev/null +++ b/Difi.Felles.Utility/Extensions/X509Certificate2Extensions.cs @@ -0,0 +1,12 @@ +using System.Security.Cryptography.X509Certificates; + +namespace Difi.Felles.Utility.Extensions +{ + public static class X509Certificate2Extensions + { + public static string Info(this X509Certificate2 certificate) + { + return $"Subject: {certificate.Subject}, Thumbprint: {certificate.Thumbprint}"; + } + } +} From 866beecac9d2398278bbab783a042f4a3d766770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20Aas=20Sja=CC=8Afjell?= Date: Sun, 25 Sep 2016 14:29:46 +0200 Subject: [PATCH 04/10] Fjerner duplisering i CertificateValidator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Litt opprydding for å gjøre lesbarheten bedre. --- Difi.Felles.Utility/CertificateValidator.cs | 54 +++++++++++++++------ 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/Difi.Felles.Utility/CertificateValidator.cs b/Difi.Felles.Utility/CertificateValidator.cs index dce622e..3c76bd6 100755 --- a/Difi.Felles.Utility/CertificateValidator.cs +++ b/Difi.Felles.Utility/CertificateValidator.cs @@ -8,49 +8,75 @@ public class CertificateValidator { public static bool IsValidCertificate(X509Certificate2 certificate, string certificateOrganizationNumber) { - return certificate != null && IsIssuedToOrganizationNumber(certificate, certificateOrganizationNumber) && IsActiveCertificate(certificate); + return ValidateCertificate(certificate, certificateOrganizationNumber).Type == SertifikatValideringType.Gyldig; } public static SertifikatValideringsResultat ValidateCertificate(X509Certificate2 certificate, string certificateOrganizationNumber) { if (certificate == null) { - return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"Sertifikat var {null}!"); + return NoCertificateResult(); } if (!IsIssuedToOrganizationNumber(certificate, certificateOrganizationNumber)) { - return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, - $"Sertifikatet er ikke utstedt til organisasjonsnummer '{certificateOrganizationNumber}'. Dette vil skje om sertifikatet er utstedt til en annen virksomhet " + - $"eller hvis det ikke er et virksomhetssertifikat. Virksomhetssertifikat kan skaffes fra Buypass eller Commfides."); + return NotIssuedToOrganizationResult(certificateOrganizationNumber); } if (!IsActivatedCertificate(certificate)) { - return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"{GetCertificateInfo(certificate)} aktiveres ikke før {certificate.GetEffectiveDateString()}."); + return NotActivatedResult(certificate); } if (IsExpiredCertificate(certificate)) { - return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"{ GetCertificateInfo(certificate) } gikk ut {certificate.GetExpirationDateString()}."); + return ExpiredResult(certificate); } - return new SertifikatValideringsResultat(SertifikatValideringType.Gyldig, $"{GetCertificateInfo(certificate)} er et gyldig sertifikat."); + return ValidResult(certificate); } - private static string GetCertificateInfo(X509Certificate2 certificate) + private static SertifikatValideringsResultat NoCertificateResult() { - return $"Sertifikat '{certificate.Info()}'"; + return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"Sertifikat var {null}!"); } - private static bool IsIssuedToOrganizationNumber(X509Certificate certificate, string certificateOrganizationNumber) + private static SertifikatValideringsResultat NotIssuedToOrganizationResult(string certificateOrganizationNumber) { - return certificate.Subject.Contains($"SERIALNUMBER={certificateOrganizationNumber}") || certificate.Subject.Contains($"CN={certificateOrganizationNumber}"); + return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, + $"Sertifikatet er ikke utstedt til organisasjonsnummer '{certificateOrganizationNumber}'. Dette vil skje om sertifikatet er utstedt til en annen virksomhet " + + "eller hvis det ikke er et virksomhetssertifikat. Virksomhetssertifikat kan skaffes fra Buypass eller Commfides."); + } + + private static SertifikatValideringsResultat NotActivatedResult(X509Certificate2 certificate) + { + return CreateSertifikatValideringsResultat(certificate, + SertifikatValideringType.UgyldigSertifikat, + $"aktiveres ikke før {certificate.GetEffectiveDateString()}"); + } + + private static SertifikatValideringsResultat ExpiredResult(X509Certificate2 certificate) + { + return CreateSertifikatValideringsResultat(certificate, + SertifikatValideringType.UgyldigSertifikat, + $"gikk ut {certificate.GetExpirationDateString()}."); } - private static bool IsActiveCertificate(X509Certificate certificate) + private static SertifikatValideringsResultat ValidResult(X509Certificate2 certificate) { - return IsActivatedCertificate(certificate) && !IsExpiredCertificate(certificate); + return CreateSertifikatValideringsResultat(certificate, SertifikatValideringType.Gyldig, "er et gyldig sertifikat."); + } + + private static SertifikatValideringsResultat CreateSertifikatValideringsResultat(X509Certificate2 certificate, SertifikatValideringType sertifikatValideringType, string description) + { + return new SertifikatValideringsResultat( + sertifikatValideringType, + $"Sertifikat '{certificate.Info()}' {description}."); + } + + private static bool IsIssuedToOrganizationNumber(X509Certificate certificate, string certificateOrganizationNumber) + { + return certificate.Subject.Contains($"SERIALNUMBER={certificateOrganizationNumber}") || certificate.Subject.Contains($"CN={certificateOrganizationNumber}"); } private static bool IsActivatedCertificate(X509Certificate certificate) From 201bfd0ecfa57e117ab6c1a8a2dffb7f7184bda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20Aas=20Sja=CC=8Afjell?= Date: Sun, 25 Sep 2016 20:19:00 +0200 Subject: [PATCH 05/10] =?UTF-8?q?Metode=20for=20sjekk=20av=20kjede=20p?= =?UTF-8?q?=C3=A5=20CertificateValidator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Sjekk av selve sertifkatet kommer ofte sammen med sjekk av kjeden, derfor er metoden `ValidateCertificateAndChain` lagt til på `CertificateValidator`. - Dårlige navn på sertifikatene kunne føre til forvirring, så dette er nå fikset. I tillegg er det lagt til et gyldig selvsignert sertifikat som kan brukes for å sjekke at sertifikat er gyldig, men at kjeden ikke er det. --- .../CertificateValidatorTests.cs | 61 +++++++++++++++-- .../Difi.Felles.Utility.Tester.csproj | 5 +- .../SertifikatUtility.cs | 14 ++-- ...icate.cer => ExpiredSelfSignedBringAs.cer} | Bin ....cer => NotActivatedSelfSignedBringAs.cer} | Bin .../Enhetstester/ValidSelfSignedBringAs.cer | Bin 0 -> 1112 bytes .../CertificateChainValidator.cs | 63 ++++++++++++++---- Difi.Felles.Utility/CertificateValidator.cs | 17 ++++- 8 files changed, 135 insertions(+), 25 deletions(-) rename Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/{ExpiredTestCertificate.cer => ExpiredSelfSignedBringAs.cer} (100%) rename Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/{NotActivatedTestCertificate.cer => NotActivatedSelfSignedBringAs.cer} (100%) create mode 100755 Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ValidSelfSignedBringAs.cer diff --git a/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs b/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs index 3158e29..8e5e2a5 100755 --- a/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs +++ b/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs @@ -1,5 +1,7 @@  +using ApiClientShared; +using Difi.Felles.Utility.Utilities; using Xunit; namespace Difi.Felles.Utility.Tester @@ -7,7 +9,56 @@ namespace Difi.Felles.Utility.Tester public class CertificateValidatorTests { - public class ValidateCertificate : CertificateValidatorTests + public class ValidateCertificateAndChain : CertificateValidatorTests + { + [Fact] + public void Returns_fail_if_certificate_error() + { + //Arrange + var funksjoneltTestmiljøSertifikater = CertificateChainUtility.FunksjoneltTestmiljøSertifikater(); + + //Act + var result = CertificateValidator.ValidateCertificateAndChain( + SertifikatUtility.GetExpiredSelfSignedTestCertificate(), "988015814", funksjoneltTestmiljøSertifikater); + + //Assert + Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); + Assert.NotNull(result.Melding); + } + + [Fact] + public void Returns_fail_if_invalid_certificate_chain() + { + //Arrange + var funksjoneltTestmiljøSertifikater = CertificateChainUtility.FunksjoneltTestmiljøSertifikater(); + + //Act + var result = CertificateValidator.ValidateCertificateAndChain( + SertifikatUtility.GetValidSelfSignedTestCertificate(), "988015814", funksjoneltTestmiljøSertifikater); + + //Assert + Assert.Equal(SertifikatValideringType.UgyldigKjede, result.Type); + Assert.NotNull(result.Melding); + } + + [Fact] + public void Returns_ok_if_valid_certificate_and_chain() + { + //Arrange + var funksjoneltTestmiljøSertifikater = CertificateChainUtility.FunksjoneltTestmiljøSertifikater(); + + //Act + var result = CertificateValidator.ValidateCertificateAndChain( + SertifikatUtility.GetPostenCertificate(), "984661185", funksjoneltTestmiljøSertifikater); + + //Assert + Assert.Equal(SertifikatValideringType.Gyldig, result.Type); + Assert.NotNull(result.Melding); + } + + } + + public class ValidateCertificateMethod : CertificateValidatorTests { [Fact] public void Returns_fail_with_null_certificate() @@ -43,7 +94,7 @@ public void Returns_fail_if_not_activated() var sertifikatOrganisasjonsnummer = "988015814"; //Act - var result = CertificateValidator.ValidateCertificate(SertifikatUtility.NotActivatedTestCertificate(), sertifikatOrganisasjonsnummer); + var result = CertificateValidator.ValidateCertificate(SertifikatUtility.NotActivatedSelfSignedTestCertificate(), sertifikatOrganisasjonsnummer); //Assert Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); @@ -57,7 +108,7 @@ public void Returns_fail_if_expired() var sertifikatOrganisasjonsnummer = "988015814"; //Act - var result = CertificateValidator.ValidateCertificate(SertifikatUtility.GetExpiredTestCertificate(), sertifikatOrganisasjonsnummer); + var result = CertificateValidator.ValidateCertificate(SertifikatUtility.GetExpiredSelfSignedTestCertificate(), sertifikatOrganisasjonsnummer); //Assert Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); @@ -116,7 +167,7 @@ public void Returns_false_if_not_activated() var sertifikatOrganisasjonsnummer = "123456789"; //Act - var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.NotActivatedTestCertificate(), sertifikatOrganisasjonsnummer); + var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.NotActivatedSelfSignedTestCertificate(), sertifikatOrganisasjonsnummer); //Assert Assert.False(isValid); @@ -129,7 +180,7 @@ public void Returns_false_if_expired() var sertifikatOrganisasjonsnummer = "123456789"; //Act - var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.GetExpiredTestCertificate(), sertifikatOrganisasjonsnummer); + var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.GetExpiredSelfSignedTestCertificate(), sertifikatOrganisasjonsnummer); //Assert Assert.False(isValid); diff --git a/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj b/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj index 836f92e..04b60a1 100755 --- a/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj +++ b/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj @@ -124,8 +124,9 @@ Designer - - + + + diff --git a/Difi.Felles.Utility.Tester/SertifikatUtility.cs b/Difi.Felles.Utility.Tester/SertifikatUtility.cs index a1218a8..f05d0f6 100755 --- a/Difi.Felles.Utility.Tester/SertifikatUtility.cs +++ b/Difi.Felles.Utility.Tester/SertifikatUtility.cs @@ -17,16 +17,22 @@ public static X509Certificate2 GetFunksjoneltTestmiljøMottakerSertifikatOppslag return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Test", "testmottakersertifikatFraOppslagstjenesten.pem")); } - public static X509Certificate2 NotActivatedTestCertificate() + public static X509Certificate2 NotActivatedSelfSignedTestCertificate() { - return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Enhetstester", "NotActivatedTestCertificate.cer")); + return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Enhetstester", "NotActivatedSelfSignedBringAs.cer")); } - public static X509Certificate2 GetExpiredTestCertificate() + public static X509Certificate2 GetExpiredSelfSignedTestCertificate() { - return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Enhetstester", "ExpiredTestCertificate.cer")); + return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Enhetstester", "ExpiredSelfSignedBringAs.cer")); } + public static X509Certificate2 GetValidSelfSignedTestCertificate() + { + return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Enhetstester", "ValidSelfSignedBringAs.cer")); + } + + public static X509Certificate2 TestIntegrasjonssertifikat() { return GetPostenCertificate(); diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ExpiredTestCertificate.cer b/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ExpiredSelfSignedBringAs.cer similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ExpiredTestCertificate.cer rename to Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ExpiredSelfSignedBringAs.cer diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/NotActivatedTestCertificate.cer b/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/NotActivatedSelfSignedBringAs.cer similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/NotActivatedTestCertificate.cer rename to Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/NotActivatedSelfSignedBringAs.cer diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ValidSelfSignedBringAs.cer b/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ValidSelfSignedBringAs.cer new file mode 100755 index 0000000000000000000000000000000000000000..3462ae9ccf17651ff2b326218695e20fbc58f2b4 GIT binary patch literal 1112 zcmXqLVhJ&5Vs==-%*4pVB=GISNr&sqnbRF?KK6r!j#U%d#AN85K^ zMn*~t(7!M-ZLMgkSjp@M{{*?!Ek7Tze4m|f zv}pSl(+w;l*&Va3RJ|*$q!%3Nyt2pd>*P(v3rz(~&%XWp#XjNNhKKj7-)V1s>wT&y z`}j@EHFGX0X+N3&qfojlra;6vF8*H&pX>9B8k;L_d-=?`eBiRk(dKur?B;(cTHRr| zp7U^;Q1yA{9zXq{&zEW@$4;1Zfx#;!ykOmn5~f-Izg`aOIC|yZI<*$XwVcVl{midq zy%pQvY>M=l+JrBo0ArYuVg2vSe)UwW)~^Hk6Y z_U$u7Oe7TS*DDH!zWBFTwIb);Hhv>V%^g#^lcW?x)OkXsG8TM_TA6yI{!V&U?1sLk z1Vh8)*ZWnI>lUg^zt9r#>B!od3TIZmTky4RpYKnN6-U1sy(V-=T+?PxbA&v+nl!mxW2Ey literal 0 HcmV?d00001 diff --git a/Difi.Felles.Utility/CertificateChainValidator.cs b/Difi.Felles.Utility/CertificateChainValidator.cs index 4203be3..bcf0b7c 100755 --- a/Difi.Felles.Utility/CertificateChainValidator.cs +++ b/Difi.Felles.Utility/CertificateChainValidator.cs @@ -36,13 +36,21 @@ public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat) /// public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat, out string detaljertFeilinformasjon) { - X509ChainStatus[] chainStatuses; - var erGyldigSertifikatkjede = ErGyldigSertifikatkjede(sertifikat, out chainStatuses); - detaljertFeilinformasjon = chainStatuses.Aggregate("", (result, curr) => $"{curr.Status}: {curr.StatusInformation}"); + var result = ValidateCertificateChain(sertifikat); + detaljertFeilinformasjon = result.Melding; + + return result.Type == SertifikatValideringType.Gyldig; + } + + public SertifikatValideringsResultat ValidateCertificateChain(X509Certificate2 certificate) + { + var chain = BuildCertificateChain(certificate); + + ValidateThatUsingOnlyValidatorCertificatesOrThrow(chain, certificate); - return erGyldigSertifikatkjede; + return ValidateCertificateChain(certificate, chain); } - + /// /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// @@ -57,7 +65,7 @@ public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat, out X509ChainSt ValidateThatUsingOnlyValidatorCertificatesOrThrow(chain,sertifikat); - return IsValidCertificateChain(chain); + return ValidateCertificateChain(sertifikat, chain).Type == SertifikatValideringType.Gyldig; } private X509Chain BuildCertificateChain(X509Certificate2 sertifikat) @@ -112,23 +120,54 @@ public X509ChainPolicy ChainPolicy() return policy; } - private static bool IsValidCertificateChain(X509Chain chain) + private static SertifikatValideringsResultat ValidateCertificateChain(X509Certificate2 certificate, X509Chain chain) { - if (!HasExpectedLength(chain, 3)) return false; + const int requiredChainLength = 3; + if (!HasExpectedLength(chain, requiredChainLength)) + { + return IncorrectChainLengthResult(certificate, requiredChainLength, chain.ChainElements.Count); + } var detailedErrorInformation = chain.ChainStatus; switch (detailedErrorInformation.Length) { case 0: - return true; + return ValidResult(certificate); case 1: - var isUntrustedRootStatus = detailedErrorInformation.ElementAt(0).Status == X509ChainStatusFlags.UntrustedRoot; - return isUntrustedRootStatus; + var chainError = detailedErrorInformation.ElementAt(0).Status; + return chainError == X509ChainStatusFlags.UntrustedRoot + ? ValidResult(certificate) + : InvalidChainResult(certificate, detailedErrorInformation); default: - return false; + return InvalidChainResult(certificate, detailedErrorInformation); } } + private static SertifikatValideringsResultat InvalidChainResult(X509Certificate2 theCertificate, params X509ChainStatus[] x509ChainStatuses) + { + return CreateSertifikatValideringsResultat(theCertificate, SertifikatValideringType.UgyldigKjede, $"har følgende feil i sertifikatkjeden: {GetPrettyChainErrorStatuses(x509ChainStatuses)}"); + } + + private static SertifikatValideringsResultat ValidResult(X509Certificate2 theCertificate) + { + return CreateSertifikatValideringsResultat(theCertificate, SertifikatValideringType.Gyldig, "er et gyldig sertifikat."); + } + + private static SertifikatValideringsResultat IncorrectChainLengthResult(X509Certificate2 certificate2, int requiredChainLength, int actualChainLength) + { + return CreateSertifikatValideringsResultat(certificate2, SertifikatValideringType.UgyldigKjede, $"er ugyldig, fordi lengden på kjeden er {actualChainLength}, men skal være {requiredChainLength}. Dette skjer hvis sertifikatet er utstedt av en ukjent sertifikattilbyder eller er selvsignert."); + } + + private static SertifikatValideringsResultat CreateSertifikatValideringsResultat(X509Certificate2 certificate, SertifikatValideringType sertifikatValideringType, string description) + { + return new SertifikatValideringsResultat(sertifikatValideringType, $"Sertifikat '{certificate.Info()}' {description}."); + } + + private static string GetPrettyChainErrorStatuses(X509ChainStatus[] chainStatuses) + { + return chainStatuses.Aggregate("", (result, curr) => $"{curr.Status}: {curr.StatusInformation}"); + } + private static bool HasExpectedLength(X509Chain chain, int chainLength) { return chain.ChainElements.Count == chainLength; diff --git a/Difi.Felles.Utility/CertificateValidator.cs b/Difi.Felles.Utility/CertificateValidator.cs index 3c76bd6..ee474fb 100755 --- a/Difi.Felles.Utility/CertificateValidator.cs +++ b/Difi.Felles.Utility/CertificateValidator.cs @@ -6,9 +6,17 @@ namespace Difi.Felles.Utility { public class CertificateValidator { - public static bool IsValidCertificate(X509Certificate2 certificate, string certificateOrganizationNumber) + public static SertifikatValideringsResultat ValidateCertificateAndChain(X509Certificate2 certificate, string certificateOrganizationNumber, X509Certificate2Collection chainCertificates) { - return ValidateCertificate(certificate, certificateOrganizationNumber).Type == SertifikatValideringType.Gyldig; + var sertifikatValideringsResultat = ValidateCertificate(certificate, certificateOrganizationNumber); + + if (sertifikatValideringsResultat.Type != SertifikatValideringType.Gyldig) + { + return sertifikatValideringsResultat; + } + + var certificateChainValidator = new CertificateChainValidator(chainCertificates); + return certificateChainValidator.ValidateCertificateChain(certificate); } public static SertifikatValideringsResultat ValidateCertificate(X509Certificate2 certificate, string certificateOrganizationNumber) @@ -36,6 +44,11 @@ public static SertifikatValideringsResultat ValidateCertificate(X509Certificate2 return ValidResult(certificate); } + public static bool IsValidCertificate(X509Certificate2 certificate, string certificateOrganizationNumber) + { + return ValidateCertificate(certificate, certificateOrganizationNumber).Type == SertifikatValideringType.Gyldig; + } + private static SertifikatValideringsResultat NoCertificateResult() { return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"Sertifikat var {null}!"); From 964aa72f5e867544da5f76a3cced4208915444b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20Aas=20Sja=CC=8Afjell?= Date: Sun, 25 Sep 2016 21:03:32 +0200 Subject: [PATCH 06/10] Fjerner exceptionkasting for bruk av maskinsertifikater MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nå returnerer vi heller en fin feilmelding som en del av resultatet. --- .../CertificateChainValidatorTests.cs | 6 ++-- .../CertificateChainValidator.cs | 33 +++++++++++-------- Difi.Felles.Utility/CertificateValidator.cs | 10 +++--- .../Difi.Felles.Utility.csproj | 1 - .../CertificateChainValidationException.cs | 10 ------ 5 files changed, 29 insertions(+), 31 deletions(-) delete mode 100755 Difi.Felles.Utility/Exceptions/CertificateChainValidationException.cs diff --git a/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs b/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs index c4a7333..d2f32e3 100755 --- a/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs +++ b/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs @@ -146,8 +146,9 @@ public void Feiler_med_produksjonssertifikat_når_validerer_mot_testkjede() //Act var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.FunksjoneltTestmiljøSertifikater()); + var erGyldigSertifikatkjede = sertifikatValidator.ErGyldigSertifikatkjede(produksjonssertifikat); - Assert.Throws(() => sertifikatValidator.ErGyldigSertifikatkjede(produksjonssertifikat)); + Assert.False(erGyldigSertifikatkjede); } [Fact] @@ -158,8 +159,9 @@ public void Feiler_med_testsertifikat_når_validerer_mot_produksjonskjede() //Act var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); + var erGyldigSertifikatkjede = sertifikatValidator.ErGyldigSertifikatkjede(testsertifikat); - Assert.Throws(() => sertifikatValidator.ErGyldigSertifikatkjede(testsertifikat)); + Assert.False(erGyldigSertifikatkjede); } } } diff --git a/Difi.Felles.Utility/CertificateChainValidator.cs b/Difi.Felles.Utility/CertificateChainValidator.cs index bcf0b7c..dfba14f 100755 --- a/Difi.Felles.Utility/CertificateChainValidator.cs +++ b/Difi.Felles.Utility/CertificateChainValidator.cs @@ -19,7 +19,6 @@ public CertificateChainValidator(X509Certificate2Collection sertifikatLager) /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// /// - /// Kastes hvis det prøves å gjøre validering mot andre sertifikater enn de i . /// public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat) { @@ -32,7 +31,6 @@ public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat) /// /// /// Status på kjeden etter validering hvis validering feilet. - /// Kastes hvis det prøves å gjøre validering mot andre sertifikater enn de i . /// public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat, out string detaljertFeilinformasjon) { @@ -46,9 +44,11 @@ public SertifikatValideringsResultat ValidateCertificateChain(X509Certificate2 c { var chain = BuildCertificateChain(certificate); - ValidateThatUsingOnlyValidatorCertificatesOrThrow(chain, certificate); + var onlyUsingValidatorCertificatesResult = ValidateThatUsingOnlyValidatorCertificates(chain, certificate); - return ValidateCertificateChain(certificate, chain); + return onlyUsingValidatorCertificatesResult.Type != SertifikatValideringType.Gyldig + ? onlyUsingValidatorCertificatesResult + : ValidateCertificateChain(certificate, chain); } /// @@ -56,14 +56,17 @@ public SertifikatValideringsResultat ValidateCertificateChain(X509Certificate2 c /// /// /// Status på kjeden etter validering hvis validering feilet. - /// Kastes hvis det prøves å gjøre validering mot andre sertifikater enn de i . /// public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat, out X509ChainStatus[] detaljertFeilinformasjon) { var chain = BuildCertificateChain(sertifikat); detaljertFeilinformasjon = chain.ChainStatus; - ValidateThatUsingOnlyValidatorCertificatesOrThrow(chain,sertifikat); + var onlyUsingValidatorCertificatesResult = ValidateThatUsingOnlyValidatorCertificates(chain,sertifikat); + if (onlyUsingValidatorCertificatesResult.Type != SertifikatValideringType.Gyldig) + { + return false; + } return ValidateCertificateChain(sertifikat, chain).Type == SertifikatValideringType.Gyldig; } @@ -78,7 +81,7 @@ private X509Chain BuildCertificateChain(X509Certificate2 sertifikat) return chain; } - private void ValidateThatUsingOnlyValidatorCertificatesOrThrow(X509Chain chain, X509Certificate2 sertifikat) + private SertifikatValideringsResultat ValidateThatUsingOnlyValidatorCertificates(X509Chain chain, X509Certificate2 sertifikat) { foreach (var chainElement in chain.ChainElements) { @@ -91,11 +94,15 @@ private void ValidateThatUsingOnlyValidatorCertificatesOrThrow(X509Chain chain, var chainAsString = chain.ChainElements.Cast().Aggregate("",(result, curr) => GetCertificateInfo(result, curr.Certificate)); var validatorCertificatesAsString = SertifikatLager.Cast().Aggregate("", GetCertificateInfo); - throw new CertificateChainValidationException($"Validering av sertifikat '{sertifikat.Info()}' feilet. Dette skjer fordi kjeden ble bygd " + - $"med følgende sertifikater {chainAsString}, men kun følgende er godkjent for å bygge kjeden: {validatorCertificatesAsString}. Dette skjer som oftest " + - "om sertifikater blir hentet fra Certificate Store på Windows, og det tillates ikke under validering. Det er kun gyldig å bygge en " + - "kjede med de sertifikatene sendt inn til validatoren."); + return UsedExternalCertificatesResult(sertifikat, chainAsString, validatorCertificatesAsString); } + + return new SertifikatValideringsResultat(SertifikatValideringType.Gyldig, ""); + } + + private static SertifikatValideringsResultat UsedExternalCertificatesResult(X509Certificate2 sertifikat, string chainAsString, string validatorCertificatesAsString) + { + return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigKjede, $"Validering av sertifikat '{sertifikat.Info()}' feilet. Dette skjer fordi kjeden ble bygd med følgende sertifikater {chainAsString}, men kun følgende er godkjent for å bygge kjeden: {validatorCertificatesAsString}. Dette skjer som oftest om sertifikater blir hentet fra Certificate Store på Windows, og det tillates ikke under validering. Det er kun gyldig å bygge en kjede med de sertifikatene sendt inn til validatoren."); } private static bool IsSameCertificate(X509Certificate2 certificate1, X509Certificate2 certificate2) @@ -143,9 +150,9 @@ private static SertifikatValideringsResultat ValidateCertificateChain(X509Certif } } - private static SertifikatValideringsResultat InvalidChainResult(X509Certificate2 theCertificate, params X509ChainStatus[] x509ChainStatuses) + private static SertifikatValideringsResultat InvalidChainResult(X509Certificate2 certificate, params X509ChainStatus[] x509ChainStatuses) { - return CreateSertifikatValideringsResultat(theCertificate, SertifikatValideringType.UgyldigKjede, $"har følgende feil i sertifikatkjeden: {GetPrettyChainErrorStatuses(x509ChainStatuses)}"); + return CreateSertifikatValideringsResultat(certificate, SertifikatValideringType.UgyldigKjede, $"har følgende feil i sertifikatkjeden: {GetPrettyChainErrorStatuses(x509ChainStatuses)}"); } private static SertifikatValideringsResultat ValidResult(X509Certificate2 theCertificate) diff --git a/Difi.Felles.Utility/CertificateValidator.cs b/Difi.Felles.Utility/CertificateValidator.cs index ee474fb..7d97d9c 100755 --- a/Difi.Felles.Utility/CertificateValidator.cs +++ b/Difi.Felles.Utility/CertificateValidator.cs @@ -6,6 +6,11 @@ namespace Difi.Felles.Utility { public class CertificateValidator { + public static bool IsValidCertificate(X509Certificate2 certificate, string certificateOrganizationNumber) + { + return ValidateCertificate(certificate, certificateOrganizationNumber).Type == SertifikatValideringType.Gyldig; + } + public static SertifikatValideringsResultat ValidateCertificateAndChain(X509Certificate2 certificate, string certificateOrganizationNumber, X509Certificate2Collection chainCertificates) { var sertifikatValideringsResultat = ValidateCertificate(certificate, certificateOrganizationNumber); @@ -44,11 +49,6 @@ public static SertifikatValideringsResultat ValidateCertificate(X509Certificate2 return ValidResult(certificate); } - public static bool IsValidCertificate(X509Certificate2 certificate, string certificateOrganizationNumber) - { - return ValidateCertificate(certificate, certificateOrganizationNumber).Type == SertifikatValideringType.Gyldig; - } - private static SertifikatValideringsResultat NoCertificateResult() { return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"Sertifikat var {null}!"); diff --git a/Difi.Felles.Utility/Difi.Felles.Utility.csproj b/Difi.Felles.Utility/Difi.Felles.Utility.csproj index 1a04538..290648e 100755 --- a/Difi.Felles.Utility/Difi.Felles.Utility.csproj +++ b/Difi.Felles.Utility/Difi.Felles.Utility.csproj @@ -50,7 +50,6 @@ - diff --git a/Difi.Felles.Utility/Exceptions/CertificateChainValidationException.cs b/Difi.Felles.Utility/Exceptions/CertificateChainValidationException.cs deleted file mode 100755 index 4d3dc08..0000000 --- a/Difi.Felles.Utility/Exceptions/CertificateChainValidationException.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Difi.Felles.Utility.Exceptions -{ - public class CertificateChainValidationException : SecurityException - { - public CertificateChainValidationException(string message) - : base(message) - { - } - } -} From 640fa31f8b5a40839993b0126b7750ca0cd009c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20Aas=20Sja=CC=8Afjell?= Date: Mon, 26 Sep 2016 08:54:46 +0200 Subject: [PATCH 07/10] =?UTF-8?q?Fjerner=20sertifikat=20fra=20liste=20over?= =?UTF-8?q?=20de=20som=20brukes=20for=20=C3=A5=20bygge=20kjede?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Og prettyprinter listen. Nå ser den pittelittegranne finere ut! --- Difi.Felles.Utility/CertificateChainValidator.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Difi.Felles.Utility/CertificateChainValidator.cs b/Difi.Felles.Utility/CertificateChainValidator.cs index dfba14f..cedac20 100755 --- a/Difi.Felles.Utility/CertificateChainValidator.cs +++ b/Difi.Felles.Utility/CertificateChainValidator.cs @@ -91,8 +91,14 @@ private SertifikatValideringsResultat ValidateThatUsingOnlyValidatorCertificates var isValidatorCertificate = SertifikatLager.Cast().Any(lagerSertifikat => IsSameCertificate(chainElement.Certificate, lagerSertifikat)); if (isValidatorCertificate) { continue; } - var chainAsString = chain.ChainElements.Cast().Aggregate("",(result, curr) => GetCertificateInfo(result, curr.Certificate)); - var validatorCertificatesAsString = SertifikatLager.Cast().Aggregate("", GetCertificateInfo); + var chainAsString = chain.ChainElements + .Cast() + .Where(c => c.Certificate.Thumbprint != sertifikat.Thumbprint) + .Aggregate("",(result, curr) => GetCertificateInfo(result, curr.Certificate)); + + var validatorCertificatesAsString = SertifikatLager + .Cast() + .Aggregate("", GetCertificateInfo); return UsedExternalCertificatesResult(sertifikat, chainAsString, validatorCertificatesAsString); } @@ -102,7 +108,11 @@ private SertifikatValideringsResultat ValidateThatUsingOnlyValidatorCertificates private static SertifikatValideringsResultat UsedExternalCertificatesResult(X509Certificate2 sertifikat, string chainAsString, string validatorCertificatesAsString) { - return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigKjede, $"Validering av sertifikat '{sertifikat.Info()}' feilet. Dette skjer fordi kjeden ble bygd med følgende sertifikater {chainAsString}, men kun følgende er godkjent for å bygge kjeden: {validatorCertificatesAsString}. Dette skjer som oftest om sertifikater blir hentet fra Certificate Store på Windows, og det tillates ikke under validering. Det er kun gyldig å bygge en kjede med de sertifikatene sendt inn til validatoren."); + return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigKjede, + $"Validering av sertifikat '{sertifikat.Info()}' feilet. {Environment.NewLine}" + + $"Dette skjer fordi kjeden ble bygd med følgende sertifikater: {Environment.NewLine}{chainAsString}, " + + $"men kun følgende er godkjent for å bygge kjeden: {Environment.NewLine}{validatorCertificatesAsString}. Dette skjer som oftest om sertifikater blir hentet fra Certificate Store på Windows, " + + "og det tillates ikke under validering. Det er kun gyldig å bygge en kjede med de sertifikatene sendt inn til validatoren."); } private static bool IsSameCertificate(X509Certificate2 certificate1, X509Certificate2 certificate2) From 23289b5bd1ccfdf8908881da32b8a09af823fe98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20Aas=20Sja=CC=8Afjell?= Date: Mon, 26 Sep 2016 15:40:43 +0200 Subject: [PATCH 08/10] =?UTF-8?q?Fikser=20etter=20draforesp=C3=B8rsel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Output av info for sertifikater, deprecating av metoder, info til utvikler og bedre navn på klasser, metoder og variabler - Fjerner tester for metoder som er deprecated. Disse blir ikke endret. Fjerner også tester i CertificateChainValidator som er like mtp logikk. Vi er nå helt uavhengige av Windows Certificate Store, så tester fra prod til test og andre veien er unødvendig. --- .../CertificateChainValidatorTests.cs | 149 +++--------------- .../CertificateValidatorTests.cs | 88 +++++------ .../Utilities/CertificateChainUtilityTests.cs | 6 +- .../CertificateChainValidator.cs | 127 ++++++++------- .../CertificateValidationResult.cs | 15 ++ .../CertificateValidationType.cs | 9 ++ Difi.Felles.Utility/CertificateValidator.cs | 49 +++--- .../Difi.Felles.Utility.csproj | 4 +- .../Extensions/X509Certificate2Extensions.cs | 4 +- .../SertifikatValideringType.cs | 9 -- .../SertifikatValideringsResultat.cs | 17 -- .../Utilities/CertificateChainUtility.cs | 4 +- difi-felles-utility.sln | 2 +- 13 files changed, 191 insertions(+), 292 deletions(-) create mode 100755 Difi.Felles.Utility/CertificateValidationResult.cs create mode 100755 Difi.Felles.Utility/CertificateValidationType.cs delete mode 100755 Difi.Felles.Utility/SertifikatValideringType.cs delete mode 100755 Difi.Felles.Utility/SertifikatValideringsResultat.cs diff --git a/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs b/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs index d2f32e3..242eb5f 100755 --- a/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs +++ b/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs @@ -1,167 +1,60 @@ -using System.Linq; -using System.Security.Cryptography.X509Certificates; -using Difi.Felles.Utility.Exceptions; -using Difi.Felles.Utility.Utilities; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Difi.Felles.Utility.Utilities; using Xunit; using Assert = Xunit.Assert; namespace Difi.Felles.Utility.Tester { - + public class CertificateChainValidatorTests { - public class ErGyldigSertifikatkjedeMethod : CertificateChainValidatorTests + public class ValidateCertificateChain : CertificateChainValidatorTests { [Fact] - public void Gyldig_produksjonssertifikat_når_validerer_mot_produksjonskjede() - { - //Arrange - var produksjonssertifikat = SertifikatUtility.GetProduksjonsMottakerSertifikatOppslagstjenesten(); - - //Act - var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); - var erGyldigResponssertifikat = sertifikatValidator.ErGyldigSertifikatkjede(produksjonssertifikat); - - //Assert - Assert.True(erGyldigResponssertifikat); - } - - [Fact] - public void Gyldig_testsertifikat_når_validerer_mot_testkjede() - { - //Arrange - var testSertifikat = SertifikatUtility.GetFunksjoneltTestmiljøMottakerSertifikatOppslagstjenesten(); - - //Act - var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.FunksjoneltTestmiljøSertifikater()); - var erGyldigResponssertifikat = sertifikatValidator.ErGyldigSertifikatkjede(testSertifikat); - - //Assert - Assert.True(erGyldigResponssertifikat); - } - - [Fact] - public void Gyldig_produksjonssertifikat_og_kjedestatus_når_validerer_mot_produksjonskjede() + public void Valid_with_correct_root_and_intermediate() { //Arrange - var produksjonssertifikat = SertifikatUtility.GetProduksjonsMottakerSertifikatOppslagstjenesten(); - X509ChainStatus[] kjedestatus; + var productionCertificate = SertifikatUtility.GetProduksjonsMottakerSertifikatOppslagstjenesten(); + var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); //Act - var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); - var erGyldigResponssertifikat = sertifikatValidator.ErGyldigSertifikatkjede(produksjonssertifikat, out kjedestatus); + var result = certificateChainValidator.Validate(productionCertificate); //Assert - const int forventetAntallStatusElementer = 0; - Assert.True(erGyldigResponssertifikat); - Assert.Equal(forventetAntallStatusElementer, kjedestatus.Length); + Assert.Equal(CertificateValidationType.Valid, result.Type); + Assert.Contains("et gyldig sertifikat", result.Message); } [Fact] - public void Gyldig_testsertifikat_og_kjedestatus_når_validerer_mot_testkjede() + public void Fails_with_wrong_root_and_intermediate() { //Arrange - var testSertifikat = SertifikatUtility.GetFunksjoneltTestmiljøMottakerSertifikatOppslagstjenesten(); - X509ChainStatus[] kjedestatus; + var productionCertificate = SertifikatUtility.GetProduksjonsMottakerSertifikatOppslagstjenesten(); //Act - var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.FunksjoneltTestmiljøSertifikater()); - var erGyldigResponssertifikat = sertifikatValidator.ErGyldigSertifikatkjede(testSertifikat, out kjedestatus); + var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.FunksjoneltTestmiljøSertifikater()); + var result = certificateChainValidator.Validate(productionCertificate); //Assert - Assert.True(erGyldigResponssertifikat); - Assert.True((kjedestatus.Length == 0) || (kjedestatus.ElementAt(0).Status == X509ChainStatusFlags.UntrustedRoot)); - } - - [Fact] - public void Feiler_med_selvsignert_sertifikat_når_validerer_mot_produksjonskjede() - { - //Arrange - var selvsignertSertifikat = SertifikatUtility.GetEnhetstesterSelvsignertSertifikat(); + Assert.Equal(CertificateValidationType.InvalidChain, result.Type); + Assert.Contains("blir hentet fra Certificate Store på Windows", result.Message); - //Act - var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); - - var erGyldigResponssertifikat = sertifikatValidator.ErGyldigSertifikatkjede(selvsignertSertifikat); - - //Assert - Assert.False(erGyldigResponssertifikat); } [Fact] - public void Feiler_med_selvsignert_sertifikat_når_validerer_mot_testkjede() + public void Fails_with_self_signed_certificate() { //Arrange - var selvsignertSertifikat = SertifikatUtility.GetEnhetstesterSelvsignertSertifikat(); + var selfSignedCertificate = SertifikatUtility.GetEnhetstesterSelvsignertSertifikat(); + var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); //Act - var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.FunksjoneltTestmiljøSertifikater()); - - var erGyldigResponssertifikat = sertifikatValidator.ErGyldigSertifikatkjede(selvsignertSertifikat); + var result = certificateChainValidator.Validate(selfSignedCertificate); //Assert - Assert.False(erGyldigResponssertifikat); - } - - [Fact] - public void Feiler_med_selvsignert_sertifikat_og_kjedestatus_når_validerer_mot_produksjonskjede() - { - //Arrange - var selvsignertSertifikat = SertifikatUtility.GetEnhetstesterSelvsignertSertifikat(); - - //Act - var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); - - X509ChainStatus[] kjedestatus; - var erGyldigResponssertifikat = sertifikatValidator.ErGyldigSertifikatkjede(selvsignertSertifikat, out kjedestatus); - - //Assert - Assert.False(erGyldigResponssertifikat); - Assert.True(kjedestatus.ElementAt(0).Status == X509ChainStatusFlags.UntrustedRoot); - } - - [Fact] - public void Feiler_med_selvsignert_sertifikat_og_kjedestatus_når_validerer_mot_testkjede() - { - var selvsignertSertifikat = SertifikatUtility.GetEnhetstesterSelvsignertSertifikat(); - - //Act - var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.FunksjoneltTestmiljøSertifikater()); - - X509ChainStatus[] kjedestatus; - var erGyldigResponssertifikat = sertifikatValidator.ErGyldigSertifikatkjede(selvsignertSertifikat, out kjedestatus); - - //Assert - Assert.False(erGyldigResponssertifikat); - Assert.True(kjedestatus.ElementAt(0).Status == X509ChainStatusFlags.UntrustedRoot); - } - - [Fact] - public void Feiler_med_produksjonssertifikat_når_validerer_mot_testkjede() - { - //Arrange - var produksjonssertifikat = SertifikatUtility.GetProduksjonsMottakerSertifikatOppslagstjenesten(); - - //Act - var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.FunksjoneltTestmiljøSertifikater()); - var erGyldigSertifikatkjede = sertifikatValidator.ErGyldigSertifikatkjede(produksjonssertifikat); - - Assert.False(erGyldigSertifikatkjede); - } - - [Fact] - public void Feiler_med_testsertifikat_når_validerer_mot_produksjonskjede() - { - //Arrange - var testsertifikat = SertifikatUtility.GetFunksjoneltTestmiljøMottakerSertifikatOppslagstjenesten(); - - //Act - var sertifikatValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); - var erGyldigSertifikatkjede = sertifikatValidator.ErGyldigSertifikatkjede(testsertifikat); + Assert.Equal(CertificateValidationType.InvalidChain, result.Type); + Assert.Contains("sertifikatet er selvsignert", result.Message); - Assert.False(erGyldigSertifikatkjede); } } } diff --git a/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs b/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs index 8e5e2a5..8b28c4d 100755 --- a/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs +++ b/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs @@ -1,7 +1,4 @@ - - -using ApiClientShared; -using Difi.Felles.Utility.Utilities; +using Difi.Felles.Utility.Utilities; using Xunit; namespace Difi.Felles.Utility.Tester @@ -15,47 +12,41 @@ public class ValidateCertificateAndChain : CertificateValidatorTests public void Returns_fail_if_certificate_error() { //Arrange - var funksjoneltTestmiljøSertifikater = CertificateChainUtility.FunksjoneltTestmiljøSertifikater(); + var funksjoneltTestmiljøSertifikater = CertificateChainUtility.TestCertificates(); //Act - var result = CertificateValidator.ValidateCertificateAndChain( - SertifikatUtility.GetExpiredSelfSignedTestCertificate(), "988015814", funksjoneltTestmiljøSertifikater); + var result = CertificateValidator.ValidateCertificateAndChain(SertifikatUtility.GetExpiredSelfSignedTestCertificate(), "988015814", funksjoneltTestmiljøSertifikater); //Assert - Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); - Assert.NotNull(result.Melding); + Assert.Equal(CertificateValidationType.InvalidCertificate, result.Type); + Assert.NotNull(result.Message); } [Fact] public void Returns_fail_if_invalid_certificate_chain() { //Arrange - var funksjoneltTestmiljøSertifikater = CertificateChainUtility.FunksjoneltTestmiljøSertifikater(); + var funksjoneltTestmiljøSertifikater = CertificateChainUtility.TestCertificates(); //Act - var result = CertificateValidator.ValidateCertificateAndChain( - SertifikatUtility.GetValidSelfSignedTestCertificate(), "988015814", funksjoneltTestmiljøSertifikater); + var result = CertificateValidator.ValidateCertificateAndChain(SertifikatUtility.GetValidSelfSignedTestCertificate(), "988015814", funksjoneltTestmiljøSertifikater); //Assert - Assert.Equal(SertifikatValideringType.UgyldigKjede, result.Type); - Assert.NotNull(result.Melding); + Assert.Equal(CertificateValidationType.InvalidChain, result.Type); } [Fact] public void Returns_ok_if_valid_certificate_and_chain() { //Arrange - var funksjoneltTestmiljøSertifikater = CertificateChainUtility.FunksjoneltTestmiljøSertifikater(); + var funksjoneltTestmiljøSertifikater = CertificateChainUtility.TestCertificates(); //Act - var result = CertificateValidator.ValidateCertificateAndChain( - SertifikatUtility.GetPostenCertificate(), "984661185", funksjoneltTestmiljøSertifikater); + var result = CertificateValidator.ValidateCertificateAndChain(SertifikatUtility.GetPostenCertificate(), "984661185", funksjoneltTestmiljøSertifikater); //Assert - Assert.Equal(SertifikatValideringType.Gyldig, result.Type); - Assert.NotNull(result.Melding); + Assert.Equal(CertificateValidationType.Valid, result.Type); } - } public class ValidateCertificateMethod : CertificateValidatorTests @@ -64,69 +55,70 @@ public class ValidateCertificateMethod : CertificateValidatorTests public void Returns_fail_with_null_certificate() { //Arrange + const string organizationNumber = "123456789"; //Act - var result = CertificateValidator.ValidateCertificate(null, "123456789"); + var result = CertificateValidator.ValidateCertificate(null, organizationNumber); //Assert - Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); - Assert.NotNull(result.Melding); + Assert.Equal(CertificateValidationType.InvalidCertificate, result.Type); + Assert.Contains("var null", result.Message); } [Fact] public void Returns_fail_if_not_issued_to_organization_number() { //Arrange - var organizationNumber = "123456789"; + const string certificateOrganizationNumber = "123456789"; //Act - var result = CertificateValidator.ValidateCertificate(SertifikatUtility.TestIntegrasjonssertifikat(), organizationNumber); + var result = CertificateValidator.ValidateCertificate(SertifikatUtility.TestIntegrasjonssertifikat(), certificateOrganizationNumber); //Assert - Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); - Assert.NotNull(result.Melding); + Assert.Equal(CertificateValidationType.InvalidCertificate, result.Type); + Assert.Contains("ikke utstedt til organisasjonsnummer", result.Message); } [Fact] public void Returns_fail_if_not_activated() { //Arrange - var sertifikatOrganisasjonsnummer = "988015814"; + const string certificateOrganizationNumber = "988015814"; //Act - var result = CertificateValidator.ValidateCertificate(SertifikatUtility.NotActivatedSelfSignedTestCertificate(), sertifikatOrganisasjonsnummer); + var result = CertificateValidator.ValidateCertificate(SertifikatUtility.NotActivatedSelfSignedTestCertificate(), certificateOrganizationNumber); //Assert - Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); - Assert.NotNull(result.Melding); + Assert.Equal(CertificateValidationType.InvalidCertificate, result.Type); + Assert.Contains("aktiveres ikke før", result.Message); } [Fact] public void Returns_fail_if_expired() { //Arrange - var sertifikatOrganisasjonsnummer = "988015814"; + const string certificateOrganizationNumber = "988015814"; //Act - var result = CertificateValidator.ValidateCertificate(SertifikatUtility.GetExpiredSelfSignedTestCertificate(), sertifikatOrganisasjonsnummer); + var result = CertificateValidator.ValidateCertificate(SertifikatUtility.GetExpiredSelfSignedTestCertificate(), certificateOrganizationNumber); //Assert - Assert.Equal(SertifikatValideringType.UgyldigSertifikat, result.Type); - Assert.NotNull(result.Melding); + Assert.Equal(CertificateValidationType.InvalidCertificate, result.Type); + Assert.Contains("gikk ut",result.Message); } [Fact] public void Returns_ok_if_valid() { //Arrange - var sertifikatOrganisasjonsnummer = "984661185"; + const string certificateOrganizationNumber = "984661185"; //Act - var result = CertificateValidator.ValidateCertificate(SertifikatUtility.GetPostenCertificate(), sertifikatOrganisasjonsnummer); + var result = CertificateValidator.ValidateCertificate(SertifikatUtility.GetPostenCertificate(), certificateOrganizationNumber); //Assert - Assert.Equal(SertifikatValideringType.Gyldig, result.Type); - Assert.NotNull(result.Melding); + Assert.Equal(CertificateValidationType.Valid, result.Type); + Assert.Contains("er et gyldig sertifikat", result.Message); } @@ -138,7 +130,7 @@ public class IsValidCertificateMethod : CertificateValidatorTests public void Returns_false_with_null_certificate() { //Arrange - var certificateOrganizationNumber = "123456789"; + const string certificateOrganizationNumber = "123456789"; //Act var isValid = CertificateValidator.IsValidCertificate(null, certificateOrganizationNumber); @@ -151,10 +143,10 @@ public void Returns_false_with_null_certificate() public void Returns_false_if_not_issued_to_organization_number() { //Arrange - var sertifikatOrganisasjonsnummer = "123456789"; + var certificateOrganizationNumber = "123456789"; //Act - var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.TestIntegrasjonssertifikat(), sertifikatOrganisasjonsnummer); + var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.TestIntegrasjonssertifikat(), certificateOrganizationNumber); //Assert Assert.False(isValid); @@ -164,10 +156,10 @@ public void Returns_false_if_not_issued_to_organization_number() public void Returns_false_if_not_activated() { //Arrange - var sertifikatOrganisasjonsnummer = "123456789"; + var certificateOrganizationNumber = "123456789"; //Act - var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.NotActivatedSelfSignedTestCertificate(), sertifikatOrganisasjonsnummer); + var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.NotActivatedSelfSignedTestCertificate(), certificateOrganizationNumber); //Assert Assert.False(isValid); @@ -177,10 +169,10 @@ public void Returns_false_if_not_activated() public void Returns_false_if_expired() { //Arrange - var sertifikatOrganisasjonsnummer = "123456789"; + var certificateOrganizationNumber = "123456789"; //Act - var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.GetExpiredSelfSignedTestCertificate(), sertifikatOrganisasjonsnummer); + var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.GetExpiredSelfSignedTestCertificate(), certificateOrganizationNumber); //Assert Assert.False(isValid); @@ -190,10 +182,10 @@ public void Returns_false_if_expired() public void Returns_true_for_correct_certificate() { //Arrange - var sertifikatOrganisasjonsnummer = "984661185"; + var certificateOrganizationNumber = "984661185"; //Act - var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.GetPostenCertificate(), sertifikatOrganisasjonsnummer); + var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.GetPostenCertificate(), certificateOrganizationNumber); //Assert Assert.True(isValid); diff --git a/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs b/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs index 6dba02a..0950a38 100755 --- a/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs +++ b/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs @@ -14,7 +14,7 @@ public class TestsertifikaterMethod : CertificateChainUtilityTests public void ReturnererFireSertifikaterMedThumbprint() { //Arrange - var sertifikater = CertificateChainUtility.FunksjoneltTestmiljøSertifikater(); + var sertifikater = CertificateChainUtility.TestCertificates(); //Act @@ -33,7 +33,7 @@ public class ProduksjonssertifikaterMethod : CertificateChainUtilityTests public void ReturnererFireSertifikaterMedThumbprint() { //Arrange - var sertifikater = CertificateChainUtility.ProduksjonsSertifikater(); + var sertifikater = CertificateChainUtility.ProductionCertificates(); //Act @@ -52,7 +52,7 @@ public class CertificateChainInfoTests : CertificateChainUtilityTests public void DebugMesages() { int i = 0; - foreach (var certificate in CertificateChainUtility.FunksjoneltTestmiljøSertifikater()) + foreach (var certificate in CertificateChainUtility.TestCertificates()) { Trace.WriteLine($"{i++}: Issuer `{certificate.Issuer}`, thumbprint `{certificate.Thumbprint}`"); } diff --git a/Difi.Felles.Utility/CertificateChainValidator.cs b/Difi.Felles.Utility/CertificateChainValidator.cs index cedac20..e6e5449 100755 --- a/Difi.Felles.Utility/CertificateChainValidator.cs +++ b/Difi.Felles.Utility/CertificateChainValidator.cs @@ -1,74 +1,100 @@ using System; using System.Linq; using System.Security.Cryptography.X509Certificates; -using Difi.Felles.Utility.Exceptions; using Difi.Felles.Utility.Extensions; namespace Difi.Felles.Utility { public class CertificateChainValidator { - public CertificateChainValidator(X509Certificate2Collection sertifikatLager) + public CertificateChainValidator(X509Certificate2Collection certificateStore) { - SertifikatLager = sertifikatLager; + CertificateStore = certificateStore; } - public X509Certificate2Collection SertifikatLager { get; set; } + public X509Certificate2Collection CertificateStore { get; set; } + + [Obsolete("Use CertificateStore instead.")] + public X509Certificate2Collection SertifikatLager => CertificateStore; + + /// + /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot + /// + /// + /// + [Obsolete("Use IsValidChain instead.")] + public bool ErGyldigSertifikatkjede(X509Certificate2 certificate) + { + return IsValidChain(certificate); + } + + /// + /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot + /// + /// + /// + public bool IsValidChain(X509Certificate2 certificate) + { + return Validate(certificate).Type == CertificateValidationType.Valid; + } /// /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// - /// + /// + /// Status på kjeden etter validering hvis validering feilet. /// - public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat) + [Obsolete("Use IsValidChain instead.")] + public bool ErGyldigSertifikatkjede(X509Certificate2 certificate, out string detaljertFeilinformasjon) { - X509ChainStatus[] chainStatuses; - return ErGyldigSertifikatkjede(sertifikat, out chainStatuses); + return IsValidChain(certificate, out detaljertFeilinformasjon); } /// /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// - /// + /// /// Status på kjeden etter validering hvis validering feilet. /// - public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat, out string detaljertFeilinformasjon) + public bool IsValidChain(X509Certificate2 certificate, out string detaljertFeilinformasjon) { - var result = ValidateCertificateChain(sertifikat); - detaljertFeilinformasjon = result.Melding; + var result = Validate(certificate); + detaljertFeilinformasjon = result.Message; - return result.Type == SertifikatValideringType.Gyldig; + return result.Type == CertificateValidationType.Valid; } - public SertifikatValideringsResultat ValidateCertificateChain(X509Certificate2 certificate) + + public CertificateValidationResult Validate(X509Certificate2 certificate) { var chain = BuildCertificateChain(certificate); var onlyUsingValidatorCertificatesResult = ValidateThatUsingOnlyValidatorCertificates(chain, certificate); - return onlyUsingValidatorCertificatesResult.Type != SertifikatValideringType.Gyldig + return onlyUsingValidatorCertificatesResult.Type != CertificateValidationType.Valid ? onlyUsingValidatorCertificatesResult - : ValidateCertificateChain(certificate, chain); + : Validate(certificate, chain); } /// /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// - /// - /// Status på kjeden etter validering hvis validering feilet. + /// + /// Status på kjeden etter validering hvis validering feilet. /// - public bool ErGyldigSertifikatkjede(X509Certificate2 sertifikat, out X509ChainStatus[] detaljertFeilinformasjon) + [Obsolete("Use other overloads for validation, as this overload exposes the error of untrusted root certificate. We tolerate this error because it occurs when loading a root certificate from file, which is always done here. We trust the certificates as they are preloaded in library.")] + public bool ErGyldigSertifikatkjede(X509Certificate2 certificate, out X509ChainStatus[] detailedErrorInformation) { - var chain = BuildCertificateChain(sertifikat); - detaljertFeilinformasjon = chain.ChainStatus; + var chain = BuildCertificateChain(certificate); + detailedErrorInformation = chain.ChainStatus; - var onlyUsingValidatorCertificatesResult = ValidateThatUsingOnlyValidatorCertificates(chain,sertifikat); - if (onlyUsingValidatorCertificatesResult.Type != SertifikatValideringType.Gyldig) + var onlyUsingValidatorCertificatesResult = ValidateThatUsingOnlyValidatorCertificates(chain,certificate); + if (onlyUsingValidatorCertificatesResult.Type != CertificateValidationType.Valid) { return false; } - return ValidateCertificateChain(sertifikat, chain).Type == SertifikatValideringType.Gyldig; + return Validate(certificate, chain).Type == CertificateValidationType.Valid; } private X509Chain BuildCertificateChain(X509Certificate2 sertifikat) @@ -81,35 +107,35 @@ private X509Chain BuildCertificateChain(X509Certificate2 sertifikat) return chain; } - private SertifikatValideringsResultat ValidateThatUsingOnlyValidatorCertificates(X509Chain chain, X509Certificate2 sertifikat) + private CertificateValidationResult ValidateThatUsingOnlyValidatorCertificates(X509Chain chain, X509Certificate2 certificate) { foreach (var chainElement in chain.ChainElements) { - var isCertificateToValidate = IsSameCertificate(chainElement.Certificate, sertifikat); + var isCertificateToValidate = IsSameCertificate(chainElement.Certificate, certificate); if (isCertificateToValidate) { continue; } - var isValidatorCertificate = SertifikatLager.Cast().Any(lagerSertifikat => IsSameCertificate(chainElement.Certificate, lagerSertifikat)); + var isValidatorCertificate = CertificateStore.Cast().Any(lagerSertifikat => IsSameCertificate(chainElement.Certificate, lagerSertifikat)); if (isValidatorCertificate) { continue; } var chainAsString = chain.ChainElements .Cast() - .Where(c => c.Certificate.Thumbprint != sertifikat.Thumbprint) + .Where(c => c.Certificate.Thumbprint != certificate.Thumbprint) .Aggregate("",(result, curr) => GetCertificateInfo(result, curr.Certificate)); - var validatorCertificatesAsString = SertifikatLager + var validatorCertificatesAsString = CertificateStore .Cast() .Aggregate("", GetCertificateInfo); - return UsedExternalCertificatesResult(sertifikat, chainAsString, validatorCertificatesAsString); + return UsedExternalCertificatesResult(certificate, chainAsString, validatorCertificatesAsString); } - return new SertifikatValideringsResultat(SertifikatValideringType.Gyldig, ""); + return ValidResult(certificate); } - private static SertifikatValideringsResultat UsedExternalCertificatesResult(X509Certificate2 sertifikat, string chainAsString, string validatorCertificatesAsString) + private static CertificateValidationResult UsedExternalCertificatesResult(X509Certificate2 sertifikat, string chainAsString, string validatorCertificatesAsString) { - return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigKjede, - $"Validering av sertifikat '{sertifikat.Info()}' feilet. {Environment.NewLine}" + + return new CertificateValidationResult(CertificateValidationType.InvalidChain, + $"Validering av '{sertifikat.ToShortString()}' feilet. {Environment.NewLine}" + $"Dette skjer fordi kjeden ble bygd med følgende sertifikater: {Environment.NewLine}{chainAsString}, " + $"men kun følgende er godkjent for å bygge kjeden: {Environment.NewLine}{validatorCertificatesAsString}. Dette skjer som oftest om sertifikater blir hentet fra Certificate Store på Windows, " + "og det tillates ikke under validering. Det er kun gyldig å bygge en kjede med de sertifikatene sendt inn til validatoren."); @@ -132,17 +158,16 @@ public X509ChainPolicy ChainPolicy() RevocationMode = X509RevocationMode.NoCheck }; - policy.ExtraStore.AddRange(SertifikatLager); + policy.ExtraStore.AddRange(CertificateStore); return policy; } - private static SertifikatValideringsResultat ValidateCertificateChain(X509Certificate2 certificate, X509Chain chain) + private static CertificateValidationResult Validate(X509Certificate2 certificate, X509Chain chain) { - const int requiredChainLength = 3; - if (!HasExpectedLength(chain, requiredChainLength)) + if (IsSelfSignedCertificate(chain)) { - return IncorrectChainLengthResult(certificate, requiredChainLength, chain.ChainElements.Count); + return SelfSignedErrorResult(certificate); } var detailedErrorInformation = chain.ChainStatus; @@ -154,30 +179,25 @@ private static SertifikatValideringsResultat ValidateCertificateChain(X509Certif var chainError = detailedErrorInformation.ElementAt(0).Status; return chainError == X509ChainStatusFlags.UntrustedRoot ? ValidResult(certificate) - : InvalidChainResult(certificate, detailedErrorInformation); + : InvalidChainResult(certificate, detailedErrorInformation); //We tolerate this 'UntrustedRoot' because it occurs when loading a root certificate from file, which is always done here. We trust the certificates as they are preloaded in library. default: return InvalidChainResult(certificate, detailedErrorInformation); } } - private static SertifikatValideringsResultat InvalidChainResult(X509Certificate2 certificate, params X509ChainStatus[] x509ChainStatuses) - { - return CreateSertifikatValideringsResultat(certificate, SertifikatValideringType.UgyldigKjede, $"har følgende feil i sertifikatkjeden: {GetPrettyChainErrorStatuses(x509ChainStatuses)}"); - } - - private static SertifikatValideringsResultat ValidResult(X509Certificate2 theCertificate) + private static CertificateValidationResult InvalidChainResult(X509Certificate2 certificate, params X509ChainStatus[] x509ChainStatuses) { - return CreateSertifikatValideringsResultat(theCertificate, SertifikatValideringType.Gyldig, "er et gyldig sertifikat."); + return new CertificateValidationResult(CertificateValidationType.InvalidChain, certificate.ToShortString($"har følgende feil i sertifikatkjeden: {GetPrettyChainErrorStatuses(x509ChainStatuses)}")); } - private static SertifikatValideringsResultat IncorrectChainLengthResult(X509Certificate2 certificate2, int requiredChainLength, int actualChainLength) + private static CertificateValidationResult ValidResult(X509Certificate2 certificate) { - return CreateSertifikatValideringsResultat(certificate2, SertifikatValideringType.UgyldigKjede, $"er ugyldig, fordi lengden på kjeden er {actualChainLength}, men skal være {requiredChainLength}. Dette skjer hvis sertifikatet er utstedt av en ukjent sertifikattilbyder eller er selvsignert."); + return new CertificateValidationResult(CertificateValidationType.Valid, certificate.ToShortString("er et gyldig sertifikat.")); } - private static SertifikatValideringsResultat CreateSertifikatValideringsResultat(X509Certificate2 certificate, SertifikatValideringType sertifikatValideringType, string description) + private static CertificateValidationResult SelfSignedErrorResult(X509Certificate2 certificate) { - return new SertifikatValideringsResultat(sertifikatValideringType, $"Sertifikat '{certificate.Info()}' {description}."); + return new CertificateValidationResult(CertificateValidationType.InvalidChain, certificate.ToShortString("er ugyldig, fordi lengden på kjeden er 1, noe som betyr at sertifikatet er selvsignert. Det må brukes et sertifikat utstedt av en gyldig sertifikatutsteder.")); } private static string GetPrettyChainErrorStatuses(X509ChainStatus[] chainStatuses) @@ -185,9 +205,10 @@ private static string GetPrettyChainErrorStatuses(X509ChainStatus[] chainStatuse return chainStatuses.Aggregate("", (result, curr) => $"{curr.Status}: {curr.StatusInformation}"); } - private static bool HasExpectedLength(X509Chain chain, int chainLength) + private static bool IsSelfSignedCertificate(X509Chain chain) { - return chain.ChainElements.Count == chainLength; + const int selfSignedChainLength = 1; + return chain.ChainElements.Count == selfSignedChainLength; } } } \ No newline at end of file diff --git a/Difi.Felles.Utility/CertificateValidationResult.cs b/Difi.Felles.Utility/CertificateValidationResult.cs new file mode 100755 index 0000000..14b4fdc --- /dev/null +++ b/Difi.Felles.Utility/CertificateValidationResult.cs @@ -0,0 +1,15 @@ +namespace Difi.Felles.Utility +{ + public class CertificateValidationResult + { + public CertificateValidationResult(CertificateValidationType type, string message) + { + Type = type; + Message = message; + } + + public CertificateValidationType Type { get; set; } + + public string Message { get; set; } + } +} \ No newline at end of file diff --git a/Difi.Felles.Utility/CertificateValidationType.cs b/Difi.Felles.Utility/CertificateValidationType.cs new file mode 100755 index 0000000..f9a5ce2 --- /dev/null +++ b/Difi.Felles.Utility/CertificateValidationType.cs @@ -0,0 +1,9 @@ +namespace Difi.Felles.Utility +{ + public enum CertificateValidationType + { + Valid, + InvalidCertificate, + InvalidChain + } +} \ No newline at end of file diff --git a/Difi.Felles.Utility/CertificateValidator.cs b/Difi.Felles.Utility/CertificateValidator.cs index 7d97d9c..26d566b 100755 --- a/Difi.Felles.Utility/CertificateValidator.cs +++ b/Difi.Felles.Utility/CertificateValidator.cs @@ -8,23 +8,23 @@ public class CertificateValidator { public static bool IsValidCertificate(X509Certificate2 certificate, string certificateOrganizationNumber) { - return ValidateCertificate(certificate, certificateOrganizationNumber).Type == SertifikatValideringType.Gyldig; + return ValidateCertificate(certificate, certificateOrganizationNumber).Type == CertificateValidationType.Valid; } - public static SertifikatValideringsResultat ValidateCertificateAndChain(X509Certificate2 certificate, string certificateOrganizationNumber, X509Certificate2Collection chainCertificates) + public static CertificateValidationResult ValidateCertificateAndChain(X509Certificate2 certificate, string certificateOrganizationNumber, X509Certificate2Collection allowedChainCertificates) { var sertifikatValideringsResultat = ValidateCertificate(certificate, certificateOrganizationNumber); - if (sertifikatValideringsResultat.Type != SertifikatValideringType.Gyldig) + if (sertifikatValideringsResultat.Type != CertificateValidationType.Valid) { return sertifikatValideringsResultat; } - var certificateChainValidator = new CertificateChainValidator(chainCertificates); - return certificateChainValidator.ValidateCertificateChain(certificate); + var certificateChainValidator = new CertificateChainValidator(allowedChainCertificates); + return certificateChainValidator.Validate(certificate); } - public static SertifikatValideringsResultat ValidateCertificate(X509Certificate2 certificate, string certificateOrganizationNumber) + public static CertificateValidationResult ValidateCertificate(X509Certificate2 certificate, string certificateOrganizationNumber) { if (certificate == null) { @@ -49,42 +49,37 @@ public static SertifikatValideringsResultat ValidateCertificate(X509Certificate2 return ValidResult(certificate); } - private static SertifikatValideringsResultat NoCertificateResult() + private static CertificateValidationResult NoCertificateResult() { - return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, $"Sertifikat var {null}!"); + return new CertificateValidationResult(CertificateValidationType.InvalidCertificate, "Sertifikat var null! Sjekk at sertifikatet blir lastet korrekt."); } - private static SertifikatValideringsResultat NotIssuedToOrganizationResult(string certificateOrganizationNumber) + private static CertificateValidationResult NotIssuedToOrganizationResult(string certificateOrganizationNumber) { - return new SertifikatValideringsResultat(SertifikatValideringType.UgyldigSertifikat, + return new CertificateValidationResult(CertificateValidationType.InvalidCertificate, $"Sertifikatet er ikke utstedt til organisasjonsnummer '{certificateOrganizationNumber}'. Dette vil skje om sertifikatet er utstedt til en annen virksomhet " + "eller hvis det ikke er et virksomhetssertifikat. Virksomhetssertifikat kan skaffes fra Buypass eller Commfides."); } - private static SertifikatValideringsResultat NotActivatedResult(X509Certificate2 certificate) + private static CertificateValidationResult NotActivatedResult(X509Certificate2 certificate) { - return CreateSertifikatValideringsResultat(certificate, - SertifikatValideringType.UgyldigSertifikat, - $"aktiveres ikke før {certificate.GetEffectiveDateString()}"); + return new CertificateValidationResult( + CertificateValidationType.InvalidCertificate, + certificate.ToShortString($"aktiveres ikke før {certificate.GetEffectiveDateString()}")); } - private static SertifikatValideringsResultat ExpiredResult(X509Certificate2 certificate) + private static CertificateValidationResult ExpiredResult(X509Certificate2 certificate) { - return CreateSertifikatValideringsResultat(certificate, - SertifikatValideringType.UgyldigSertifikat, - $"gikk ut {certificate.GetExpirationDateString()}."); + return new CertificateValidationResult( + CertificateValidationType.InvalidCertificate, + certificate.ToShortString($"gikk ut {certificate.GetExpirationDateString()}.")); } - private static SertifikatValideringsResultat ValidResult(X509Certificate2 certificate) + private static CertificateValidationResult ValidResult(X509Certificate2 certificate) { - return CreateSertifikatValideringsResultat(certificate, SertifikatValideringType.Gyldig, "er et gyldig sertifikat."); - } - - private static SertifikatValideringsResultat CreateSertifikatValideringsResultat(X509Certificate2 certificate, SertifikatValideringType sertifikatValideringType, string description) - { - return new SertifikatValideringsResultat( - sertifikatValideringType, - $"Sertifikat '{certificate.Info()}' {description}."); + return new CertificateValidationResult( + CertificateValidationType.Valid, + certificate.ToShortString("er et gyldig sertifikat.")); } private static bool IsIssuedToOrganizationNumber(X509Certificate certificate, string certificateOrganizationNumber) diff --git a/Difi.Felles.Utility/Difi.Felles.Utility.csproj b/Difi.Felles.Utility/Difi.Felles.Utility.csproj index 290648e..0477c36 100755 --- a/Difi.Felles.Utility/Difi.Felles.Utility.csproj +++ b/Difi.Felles.Utility/Difi.Felles.Utility.csproj @@ -48,8 +48,8 @@ Properties\SharedAssemblyInfo.cs - - + + diff --git a/Difi.Felles.Utility/Extensions/X509Certificate2Extensions.cs b/Difi.Felles.Utility/Extensions/X509Certificate2Extensions.cs index c4e0e0a..2b42d87 100755 --- a/Difi.Felles.Utility/Extensions/X509Certificate2Extensions.cs +++ b/Difi.Felles.Utility/Extensions/X509Certificate2Extensions.cs @@ -4,9 +4,9 @@ namespace Difi.Felles.Utility.Extensions { public static class X509Certificate2Extensions { - public static string Info(this X509Certificate2 certificate) + public static string ToShortString(this X509Certificate2 certificate, string extraInfo = "") { - return $"Subject: {certificate.Subject}, Thumbprint: {certificate.Thumbprint}"; + return $"Sertifikat med Subject '{certificate.Subject}' og Thumbprint '{certificate.Thumbprint}' {extraInfo}"; } } } diff --git a/Difi.Felles.Utility/SertifikatValideringType.cs b/Difi.Felles.Utility/SertifikatValideringType.cs deleted file mode 100755 index 7a02f87..0000000 --- a/Difi.Felles.Utility/SertifikatValideringType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Difi.Felles.Utility -{ - public enum SertifikatValideringType - { - Gyldig, - UgyldigSertifikat, - UgyldigKjede - } -} \ No newline at end of file diff --git a/Difi.Felles.Utility/SertifikatValideringsResultat.cs b/Difi.Felles.Utility/SertifikatValideringsResultat.cs deleted file mode 100755 index 3ecd932..0000000 --- a/Difi.Felles.Utility/SertifikatValideringsResultat.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Difi.Felles.Utility -{ - public class SertifikatValideringsResultat - { - public SertifikatValideringsResultat(SertifikatValideringType type, string melding) - { - Type = type; - Melding = melding; - } - - public SertifikatValideringType Type { get; set; } - - public string Melding { get; set; } - } -} diff --git a/Difi.Felles.Utility/Utilities/CertificateChainUtility.cs b/Difi.Felles.Utility/Utilities/CertificateChainUtility.cs index 9731227..788f005 100755 --- a/Difi.Felles.Utility/Utilities/CertificateChainUtility.cs +++ b/Difi.Felles.Utility/Utilities/CertificateChainUtility.cs @@ -8,7 +8,7 @@ public static class CertificateChainUtility { private static readonly ResourceUtility ResourceUtility = new ResourceUtility("Difi.Felles.Utility.Resources.Certificates"); - public static X509Certificate2Collection FunksjoneltTestmiljøSertifikater() + public static X509Certificate2Collection TestCertificates() { var difiTestkjedesertifikater = new List { @@ -20,7 +20,7 @@ public static X509Certificate2Collection FunksjoneltTestmiljøSertifikater() return new X509Certificate2Collection(difiTestkjedesertifikater.ToArray()); } - public static X509Certificate2Collection ProduksjonsSertifikater() + public static X509Certificate2Collection ProductionCertificates() { var difiProduksjonssertifikater = new List { diff --git a/difi-felles-utility.sln b/difi-felles-utility.sln index c6c8f9e..d0d3522 100755 --- a/difi-felles-utility.sln +++ b/difi-felles-utility.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 +VisualStudioVersion = 14.0.24720.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Difi.Felles.Utility", "Difi.Felles.Utility\Difi.Felles.Utility.csproj", "{7AB8D858-878F-4184-9557-995BE75DC635}" EndProject From 9781f1b1a7d3ef551eab27a415ed79993087e955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20Aas=20Sja=CC=8Afjell?= Date: Mon, 26 Sep 2016 16:07:12 +0200 Subject: [PATCH 09/10] R# cleanup og bedre datosjekk for sertifikater --- .../CertificateChainValidatorTests.cs | 8 +- .../CertificateValidatorTests.cs | 2 +- .../Security/SignedXmlWithAgnosticIdTests.cs | 79 +++++++++---------- .../SertifikatUtility.cs | 1 - .../Testdata/Transportkvittering.cs | 2 +- .../Utilities/CertificateChainUtilityTests.cs | 7 +- .../Validation/TestGenerator.cs | 36 ++++----- .../Validation/ValidationMessagesTests.cs | 8 +- .../Validation/XmlValidationRunnerTests.cs | 3 - .../Validation/XmlValidatorTests.cs | 64 ++++++++------- .../CertificateChainValidator.cs | 16 ++-- Difi.Felles.Utility/CertificateValidator.cs | 8 +- .../Properties/AssemblyInfo.cs | 1 - .../Security/SignedXmlWithAgnosticId.cs | 10 +-- .../Validation/ValidationMessages.cs | 4 +- .../Validation/XmlValidationRunner.cs | 4 +- SharedAssemblyInfo.cs | 1 - 17 files changed, 115 insertions(+), 139 deletions(-) diff --git a/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs b/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs index 242eb5f..73b5418 100755 --- a/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs +++ b/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs @@ -8,14 +8,14 @@ namespace Difi.Felles.Utility.Tester public class CertificateChainValidatorTests { - public class ValidateCertificateChain : CertificateChainValidatorTests + public class ValidateCertificateChainMethod : CertificateChainValidatorTests { [Fact] public void Valid_with_correct_root_and_intermediate() { //Arrange var productionCertificate = SertifikatUtility.GetProduksjonsMottakerSertifikatOppslagstjenesten(); - var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); + var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.ProductionCertificates()); //Act var result = certificateChainValidator.Validate(productionCertificate); @@ -32,7 +32,7 @@ public void Fails_with_wrong_root_and_intermediate() var productionCertificate = SertifikatUtility.GetProduksjonsMottakerSertifikatOppslagstjenesten(); //Act - var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.FunksjoneltTestmiljøSertifikater()); + var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.TestCertificates()); var result = certificateChainValidator.Validate(productionCertificate); //Assert @@ -46,7 +46,7 @@ public void Fails_with_self_signed_certificate() { //Arrange var selfSignedCertificate = SertifikatUtility.GetEnhetstesterSelvsignertSertifikat(); - var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); + var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.ProductionCertificates()); //Act var result = certificateChainValidator.Validate(selfSignedCertificate); diff --git a/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs b/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs index 8b28c4d..4bc8f79 100755 --- a/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs +++ b/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs @@ -6,7 +6,7 @@ namespace Difi.Felles.Utility.Tester public class CertificateValidatorTests { - public class ValidateCertificateAndChain : CertificateValidatorTests + public class ValidateCertificateAndChainMethod : CertificateValidatorTests { [Fact] public void Returns_fail_if_certificate_error() diff --git a/Difi.Felles.Utility.Tester/Security/SignedXmlWithAgnosticIdTests.cs b/Difi.Felles.Utility.Tester/Security/SignedXmlWithAgnosticIdTests.cs index ef7ae59..34a4d68 100755 --- a/Difi.Felles.Utility.Tester/Security/SignedXmlWithAgnosticIdTests.cs +++ b/Difi.Felles.Utility.Tester/Security/SignedXmlWithAgnosticIdTests.cs @@ -11,28 +11,33 @@ using Difi.Felles.Utility.Utilities; using Xunit; - namespace Difi.Felles.Utility.Tester.Security { - public class SignedXmlWithAgnosticIdTests { - public class KonstruktørMethod : SignedXmlWithAgnosticIdTests { [Fact] - public void KonstruktørMedXmlDokumentOgSertifikat() + public void FeilerMedPrivatnøkkelSomIkkeErRsaIKKEIMPLEMENTERT() { - //Arrange - var xmlDokument = XmlUtility.ToXmlDocument(TransportKvittering.TransportOkKvittertingFunksjoneltTestmiljø); - var sertifikat = CertificateUtility.GetAvsenderEnhetstesterSertifikat(); - var signedXmlWithAgnosticId = new SignedXmlWithAgnosticId(xmlDokument, sertifikat); + //Denne testen er ikke skrevet fordi vi ikke har klart å lage et sertifikat som bruker + //DSACryptoProvider. Script `GenererSertifikatScripts.txt` inneholder info om hvordan. + //Feilmelding `bad data` kommer, så noe er galt. Jeg mener det likevel er viktig å påpeke + //at vi bør ha testdekning på dette. Kanskje kan fremtiden løse dette problemet? + // Aleksander 02.11.2015 - //Act - var signingKey = signedXmlWithAgnosticId.SigningKey; + ////////////////////////////////////////////// + //P12 container med privatekey og sertifikat som holder i 10 år, DSA kryptering + ////////////////////////////////////////////// - //Assert - Assert.True(signingKey is RSACryptoServiceProvider); + //Lag dsa-parametere + // openssl dsaparam -out dsap.pem 2048 + + //Lag privatnøkkel og sertifikat + //openssl req -x509 - newkey dsa: dsap.pem - keyout key.pem -out certificate.pem - days 3650 - nodes - subj "/C=NO/ST=Oslo/L=Posthuset/O=Digipost testsertifikat Name/OU=Org/CN=www.digiphoest.no" + + //Pakk inn i container + //openssl pkcs12 -export -out certificate.pfx - inkey key.pem -in certificate.pem } [Fact] @@ -55,30 +60,21 @@ public void FeilerMedSertifikatUtenPrivatnøkkel() } [Fact] - public void FeilerMedPrivatnøkkelSomIkkeErRsaIKKEIMPLEMENTERT() + public void KonstruktørMedXmlDokumentOgSertifikat() { - //Denne testen er ikke skrevet fordi vi ikke har klart å lage et sertifikat som bruker - //DSACryptoProvider. Script `GenererSertifikatScripts.txt` inneholder info om hvordan. - //Feilmelding `bad data` kommer, så noe er galt. Jeg mener det likevel er viktig å påpeke - //at vi bør ha testdekning på dette. Kanskje kan fremtiden løse dette problemet? - // Aleksander 02.11.2015 - - ////////////////////////////////////////////// - //P12 container med privatekey og sertifikat som holder i 10 år, DSA kryptering - ////////////////////////////////////////////// - - //Lag dsa-parametere - // openssl dsaparam -out dsap.pem 2048 + //Arrange + var xmlDokument = XmlUtility.ToXmlDocument(TransportKvittering.TransportOkKvittertingFunksjoneltTestmiljø); + var sertifikat = CertificateUtility.GetAvsenderEnhetstesterSertifikat(); + var signedXmlWithAgnosticId = new SignedXmlWithAgnosticId(xmlDokument, sertifikat); - //Lag privatnøkkel og sertifikat - //openssl req -x509 - newkey dsa: dsap.pem - keyout key.pem -out certificate.pem - days 3650 - nodes - subj "/C=NO/ST=Oslo/L=Posthuset/O=Digipost testsertifikat Name/OU=Org/CN=www.digiphoest.no" + //Act + var signingKey = signedXmlWithAgnosticId.SigningKey; - //Pakk inn i container - //openssl pkcs12 -export -out certificate.pfx - inkey key.pem -in certificate.pem + //Assert + Assert.True(signingKey is RSACryptoServiceProvider); } } - public class FindIdElementMethod : SignedXmlWithAgnosticIdTests { [Fact] @@ -112,13 +108,12 @@ public void FinnerIdElementUansettSkrivemåte() Assert.NotNull(response); Assert.True( - response.Attributes.OfType().Any(a => a.LocalName == id && a.Value == "value")); + response.Attributes.OfType().Any(a => (a.LocalName == id) && (a.Value == "value"))); } } } } - public class GetPublicKeyMethod : SignedXmlWithAgnosticIdTests { private XmlNamespaceManager GetNamespaceManager(XmlDocument forDocument) @@ -151,18 +146,18 @@ private void AddBodySignatureNodeToSignedXmlWithAgnosticId(XmlDocument kildeXmlD private object GetPublicKey(SignedXmlWithAgnosticId signedXmlWithAgnosticId) { - return typeof (SignedXmlWithAgnosticId).GetMethod("GetPublicKey", BindingFlags.Instance | BindingFlags.NonPublic) + return typeof(SignedXmlWithAgnosticId).GetMethod("GetPublicKey", BindingFlags.Instance | BindingFlags.NonPublic) .Invoke(signedXmlWithAgnosticId, null); } [Fact] - public void GetsKeyFromTransportReceipt() + public void GetsKeyFromMessageReceiptBody() { //Arrange - var xmlDokument = XmlUtility.ToXmlDocument(TransportKvittering.TransportOkKvittertingFunksjoneltTestmiljø); - var signedXmlWithAgnosticId = new SignedXmlWithAgnosticId(xmlDokument); + var document = XmlUtility.ToXmlDocument(ReceiptResponse.FunctionalTestEnvironment); + var signedXmlWithAgnosticId = new SignedXmlWithAgnosticId(document); - AddHeaderSignatureNodeToSignedXmlWithAgnosticId(xmlDokument, signedXmlWithAgnosticId); + AddBodySignatureNodeToSignedXmlWithAgnosticId(document, signedXmlWithAgnosticId); //Act var signingKey = GetPublicKey(signedXmlWithAgnosticId); @@ -192,13 +187,13 @@ public void GetsKeyFromMessageReceiptHeader() } [Fact] - public void GetsKeyFromMessageReceiptBody() + public void GetsKeyFromTransportReceipt() { //Arrange - var document = XmlUtility.ToXmlDocument(ReceiptResponse.FunctionalTestEnvironment); - var signedXmlWithAgnosticId = new SignedXmlWithAgnosticId(document); + var xmlDokument = XmlUtility.ToXmlDocument(TransportKvittering.TransportOkKvittertingFunksjoneltTestmiljø); + var signedXmlWithAgnosticId = new SignedXmlWithAgnosticId(xmlDokument); - AddBodySignatureNodeToSignedXmlWithAgnosticId(document, signedXmlWithAgnosticId); + AddHeaderSignatureNodeToSignedXmlWithAgnosticId(xmlDokument, signedXmlWithAgnosticId); //Act var signingKey = GetPublicKey(signedXmlWithAgnosticId); @@ -229,7 +224,7 @@ public void SignatureNodeAndBinarySecurityTokenAreAlike() var binarySecurityToken = doc.SelectSingleNode("//wsse:BinarySecurityToken", mgr); var key = new X509Certificate2(Convert.FromBase64String(binarySecurityToken.InnerText)); - var publicKey = typeof (SignedXmlWithAgnosticId).GetMethod("GetPublicKey", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(signedXmlWithAgnosticId, null) as AsymmetricAlgorithm; + var publicKey = typeof(SignedXmlWithAgnosticId).GetMethod("GetPublicKey", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(signedXmlWithAgnosticId, null) as AsymmetricAlgorithm; //Assert Assert.Equal(publicKey.ToXmlString(false), key.PublicKey.Key.ToXmlString(false)); diff --git a/Difi.Felles.Utility.Tester/SertifikatUtility.cs b/Difi.Felles.Utility.Tester/SertifikatUtility.cs index f05d0f6..2ab35ba 100755 --- a/Difi.Felles.Utility.Tester/SertifikatUtility.cs +++ b/Difi.Felles.Utility.Tester/SertifikatUtility.cs @@ -32,7 +32,6 @@ public static X509Certificate2 GetValidSelfSignedTestCertificate() return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Enhetstester", "ValidSelfSignedBringAs.cer")); } - public static X509Certificate2 TestIntegrasjonssertifikat() { return GetPostenCertificate(); diff --git a/Difi.Felles.Utility.Tester/Testdata/Transportkvittering.cs b/Difi.Felles.Utility.Tester/Testdata/Transportkvittering.cs index 1218d19..ebbe128 100755 --- a/Difi.Felles.Utility.Tester/Testdata/Transportkvittering.cs +++ b/Difi.Felles.Utility.Tester/Testdata/Transportkvittering.cs @@ -14,7 +14,7 @@ internal class TransportKvittering public static string TransportOkKvittertingFunksjoneltTestmiljøMedInput( string dokumentPakkeId = "4fa27c07-8a0f-45a9-954e-c658f6c480af@meldingsformidler.sdp.difi.no", string securityBinary = "MIIE7jCCA9agAwIBAgIKGBj1bv99Jpi+EzANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJOTzEdMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIzAhBgNVBAMMGkJ1eXBhc3MgQ2xhc3MgMyBUZXN0NCBDQSAzMB4XDTE0MDQyNDEyMzExMVoXDTE3MDQyNDIxNTkwMFowVTELMAkGA1UEBhMCTk8xGDAWBgNVBAoMD1BPU1RFTiBOT1JHRSBBUzEYMBYGA1UEAwwPUE9TVEVOIE5PUkdFIEFTMRIwEAYDVQQFEwk5ODQ2NjExODUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLTnQryf2bmiyQ9q3ylQ6xMl7EhGIbjuziXkRTfL+M94m3ceAiko+r2piefKCiquLMK4j+UDcOapUtLC4dT4c6GhRH4FIOEn5aNS2I/njTenBypWka/VEhQUj7zvIh5G4UXIDIXYvLd7gideeMtkX24KUh2XVlh+PcqLGHirqBwVfFiTn5SKhr/ojhYYEb2xxTk3AY9nLd1MMffKQwUWmfoTos4scREYGI2R2vWxKWPcDqk+jig2DISWSJSuerz3HMYAAmp+Gjt0oFJNiyOFaFyGwT3DvqwOMQWwWXdmLh1NxMgTpghXAaXae76ucm9GDQ9E7ytf+JA096RWoi+5GtAgMBAAGjggHCMIIBvjAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFD+u9XgLkqNwIDVfWvr3JKBSAfBBMB0GA1UdDgQWBBTVyVLqcjWf1Qd0gsmCTrhXiWeqVDAOBgNVHQ8BAf8EBAMCBLAwFgYDVR0gBA8wDTALBglghEIBGgEAAwIwgbsGA1UdHwSBszCBsDA3oDWgM4YxaHR0cDovL2NybC50ZXN0NC5idXlwYXNzLm5vL2NybC9CUENsYXNzM1Q0Q0EzLmNybDB1oHOgcYZvbGRhcDovL2xkYXAudGVzdDQuYnV5cGFzcy5uby9kYz1CdXlwYXNzLGRjPU5PLENOPUJ1eXBhc3MlMjBDbGFzcyUyMDMlMjBUZXN0NCUyMENBJTIwMz9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0MIGKBggrBgEFBQcBAQR+MHwwOwYIKwYBBQUHMAGGL2h0dHA6Ly9vY3NwLnRlc3Q0LmJ1eXBhc3Mubm8vb2NzcC9CUENsYXNzM1Q0Q0EzMD0GCCsGAQUFBzAChjFodHRwOi8vY3J0LnRlc3Q0LmJ1eXBhc3Mubm8vY3J0L0JQQ2xhc3MzVDRDQTMuY2VyMA0GCSqGSIb3DQEBCwUAA4IBAQCmMpAGaNplOgx3b4Qq6FLEcpnMOnPlSWBC7pQEDWx6OtNUHDm56fBoyVQYKR6LuGfalnnOKuB/sGSmO3eYlh7uDK9WA7bsNU/W8ZiwYwF6PBRui2rrqYk3kj4NLTNlyh/AOO1a2FDFHu369W0zcjj5ns7qs0K3peXtLX8pVxA8RmjwdGe69P/2r6s2A5CBj7oXZJD0Yo2dJFdsZzonT900sUi+MWzlhj3LxU5/684NWc2NI6ZPof/dyYpy3K/AFzpDLWGSmaDO66hPl7EfoJxEiX0DNBaQzNIyRFPh0ir0jM+32ZQ4goR8bAtyhKeTyA/4+Qx1WQXS3wURCC0lsbMh" - ) + ) { return $"{securityBinary}2015-10-22T14:27:47.188Z2015-10-22T14:32:47.188ZXryysQP3I8XTSL9icB3WCy17JxqqZIvNchNVzr9/rbc=PuFI7dA66+N5d4Cov7GAdXYQq3wKBe8FwGknZtH/s4E=XI9g0I9fGSf/NVJVxe43kKCgF0OFdTc3F9SXSkE5PxA=iHhXDHohEm9cFfqz6sLc5JTUULKmhqXqCNKqDA+LoJETaR7mLF6buwlSBX4cDms6BbfY//z1RRxM8g6bEfjZtaPGBoRUUH5ar4+jJX74NDoFa37CPN/YjLNYfx98Ld5Gidx/DljDlXQg3NTwYks8LXj1NyjTWC1bQGVFA4Gw7WC81GrUpRTP8fN/WhiN3hliZB3Q04K6KLFq1DH7aYxEvlYkziXBE7pYjdeFLmFGm+cVkVWG4j2t0GCJ8c75XIXHh1ZXhAUwKUHislP3gJ0z0Jmmvbcn6oLcSdCHJ1WYwGe5sxfPiGIbfKwYR3DsyqTTyOnXsqGP/S9vUndQ/bpQDQ==2015-10-22T16:27:47.187+02:00604d8104-d957-435c-a7ec-d5611f97f249388214db-29cc-43c7-9543-877e017e5bb45jQFrdmBGPCSWj5Sq4bVoYyfrF8vAYqKl1h3m/l1j5o=clCREk3SJj5Y+FZ9oD8cnlMg1SDR74d8rXNcZQQIl8A="; } diff --git a/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs b/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs index 0950a38..3b98fe3 100755 --- a/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs +++ b/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs @@ -4,10 +4,8 @@ namespace Difi.Felles.Utility.Tester.Utilities { - public class CertificateChainUtilityTests { - public class TestsertifikaterMethod : CertificateChainUtilityTests { [Fact] @@ -26,7 +24,6 @@ public void ReturnererFireSertifikaterMedThumbprint() } } - public class ProduksjonssertifikaterMethod : CertificateChainUtilityTests { [Fact] @@ -45,19 +42,17 @@ public void ReturnererFireSertifikaterMedThumbprint() } } - public class CertificateChainInfoTests : CertificateChainUtilityTests { [Fact] public void DebugMesages() { - int i = 0; + var i = 0; foreach (var certificate in CertificateChainUtility.TestCertificates()) { Trace.WriteLine($"{i++}: Issuer `{certificate.Issuer}`, thumbprint `{certificate.Thumbprint}`"); } } - } } } \ No newline at end of file diff --git a/Difi.Felles.Utility.Tester/Validation/TestGenerator.cs b/Difi.Felles.Utility.Tester/Validation/TestGenerator.cs index 6598b73..2b5fb7a 100755 --- a/Difi.Felles.Utility.Tester/Validation/TestGenerator.cs +++ b/Difi.Felles.Utility.Tester/Validation/TestGenerator.cs @@ -11,6 +11,13 @@ internal static class TestGenerator { private static readonly ResourceUtility ResourceUtility = new ResourceUtility("Difi.Felles.Utility.Tester.Testdata"); + public static XmlSchemaSet XmlSchemaSet() + { + var xmlSchemaSet = new XmlSchemaSet(); + xmlSchemaSet.Add("http://tempuri.org/po.xsd", XmlReader.Create(new MemoryStream(ResourceUtility.ReadAllBytes(true, "Xsd.Sample.xsd")))); + return xmlSchemaSet; + } + public interface ITestCouple { List ExpectedValidationMessages { get; } @@ -20,21 +27,16 @@ public interface ITestCouple public class ValidTestCouple : ITestCouple { + public List ExpectedValidationMessages => new List(); + public string Input() { return Encoding.UTF8.GetString(ResourceUtility.ReadAllBytes(true, "Xml.Valid.xml")); } - - public List ExpectedValidationMessages => new List(); } public class InvalidContentTestCouple : ITestCouple { - public string Input() - { - return Encoding.UTF8.GetString(ResourceUtility.ReadAllBytes(true, "Xml.InvalidIdentifikatorContent.xml")); - } - public List ExpectedValidationMessages { get @@ -44,15 +46,15 @@ public List ExpectedValidationMessages return new List {validationMessageEn, validationMessageNb}; } } - } - public class InvalidSyntaxTestCouple : ITestCouple - { public string Input() { - return Encoding.UTF8.GetString(ResourceUtility.ReadAllBytes(true, "Xml.UnknownElement.xml")); + return Encoding.UTF8.GetString(ResourceUtility.ReadAllBytes(true, "Xml.InvalidIdentifikatorContent.xml")); } + } + public class InvalidSyntaxTestCouple : ITestCouple + { public List ExpectedValidationMessages { get @@ -62,13 +64,11 @@ public List ExpectedValidationMessages return new List {validationMessageEn, validationMessageNb}; } } - } - public static XmlSchemaSet XmlSchemaSet() - { - var xmlSchemaSet = new XmlSchemaSet(); - xmlSchemaSet.Add("http://tempuri.org/po.xsd", XmlReader.Create(new MemoryStream(ResourceUtility.ReadAllBytes(true,"Xsd.Sample.xsd")))); - return xmlSchemaSet; - } + public string Input() + { + return Encoding.UTF8.GetString(ResourceUtility.ReadAllBytes(true, "Xml.UnknownElement.xml")); + } + } } } \ No newline at end of file diff --git a/Difi.Felles.Utility.Tester/Validation/ValidationMessagesTests.cs b/Difi.Felles.Utility.Tester/Validation/ValidationMessagesTests.cs index e6b076d..3dd35a3 100755 --- a/Difi.Felles.Utility.Tester/Validation/ValidationMessagesTests.cs +++ b/Difi.Felles.Utility.Tester/Validation/ValidationMessagesTests.cs @@ -1,14 +1,11 @@ -using System.Collections.Generic; -using System.Xml.Schema; +using System.Xml.Schema; using Difi.Felles.Utility.Validation; using Xunit; namespace Difi.Felles.Utility.Tester.Validation { - public class ValidationMessagesTests { - public class AddErrorMethod : ValidationMessagesTests { [Fact] @@ -26,7 +23,6 @@ public void ErrorMessageIsAdded() } } - public class AddWarningMethod : ValidationMessagesTests { [Fact] @@ -44,7 +40,6 @@ public void WarningMessageIsAdded() } } - public class ToStringMethod : ValidationMessagesTests { [Fact] @@ -58,6 +53,5 @@ public void OutputsCorrectly() Assert.Same(expectedError, messages.ToString()); } } - } } \ No newline at end of file diff --git a/Difi.Felles.Utility.Tester/Validation/XmlValidationRunnerTests.cs b/Difi.Felles.Utility.Tester/Validation/XmlValidationRunnerTests.cs index 45f20d2..f72ba91 100755 --- a/Difi.Felles.Utility.Tester/Validation/XmlValidationRunnerTests.cs +++ b/Difi.Felles.Utility.Tester/Validation/XmlValidationRunnerTests.cs @@ -3,10 +3,8 @@ namespace Difi.Felles.Utility.Tester.Validation { - public class XmlValidationRunnerTests { - public class ConstructorMethod : XmlValidationRunnerTests { [Fact] @@ -23,7 +21,6 @@ public void SimpleInitialization() } } - public class ValidateMethod : ValidationMessagesTests { [Fact] diff --git a/Difi.Felles.Utility.Tester/Validation/XmlValidatorTests.cs b/Difi.Felles.Utility.Tester/Validation/XmlValidatorTests.cs index bfb82a6..771f07e 100755 --- a/Difi.Felles.Utility.Tester/Validation/XmlValidatorTests.cs +++ b/Difi.Felles.Utility.Tester/Validation/XmlValidatorTests.cs @@ -3,22 +3,40 @@ namespace Difi.Felles.Utility.Tester.Validation { - public class XmlValidatorTests { - public class ValidateMethod : XmlValidatorTests { [Fact] - public void ValidateReturnsBoolAndOutsString() + public void MultipleValidateShouldNotHoldValidationState() + { + XmlValidator validator = new XmlValidatorTestImplementation(); + + var invalidContentTestCouple = new TestGenerator.InvalidContentTestCouple(); + List messagesList; + var validateResult = validator.Validate(invalidContentTestCouple.Input(), out messagesList); + Assert.False(validateResult); + Assert.True(invalidContentTestCouple.ExpectedValidationMessages.Contains(messagesList.ToString())); + + var validTestCouple = new TestGenerator.ValidTestCouple(); + validateResult = validator.Validate(validTestCouple.Input(), out messagesList); + Assert.True(validateResult); + Assert.Equal(0, messagesList.Count); + + var invalidSyntaxTestCouple = new TestGenerator.InvalidSyntaxTestCouple(); + validateResult = validator.Validate(invalidSyntaxTestCouple.Input(), out messagesList); + Assert.False(validateResult); + Assert.True(invalidSyntaxTestCouple.ExpectedValidationMessages.Contains(messagesList.ToString())); + } + + [Fact] + public void ValidateReturnsBool() { var invalidContentTestCouple = new TestGenerator.InvalidContentTestCouple(); XmlValidator validator = new XmlValidatorTestImplementation(); - string validationMessage; - - var status = validator.Validate(invalidContentTestCouple.Input(), out validationMessage); - Assert.True(invalidContentTestCouple.ExpectedValidationMessages.Contains(validationMessage)); + var status = validator.Validate(invalidContentTestCouple.Input()); + Assert.False(status); } @@ -28,7 +46,7 @@ public void ValidateReturnsBoolAndOutsListOfStrings() var invalidContentTestCouple = new TestGenerator.InvalidContentTestCouple(); XmlValidator validator = new XmlValidatorTestImplementation(); List validationMessages; - + var status = validator.Validate(invalidContentTestCouple.Input(), out validationMessages); Assert.True(invalidContentTestCouple.ExpectedValidationMessages.Contains(validationMessages.ToString())); @@ -36,13 +54,15 @@ public void ValidateReturnsBoolAndOutsListOfStrings() } [Fact] - public void ValidateReturnsBool() + public void ValidateReturnsBoolAndOutsString() { var invalidContentTestCouple = new TestGenerator.InvalidContentTestCouple(); XmlValidator validator = new XmlValidatorTestImplementation(); - - var status = validator.Validate(invalidContentTestCouple.Input()); + string validationMessage; + var status = validator.Validate(invalidContentTestCouple.Input(), out validationMessage); + + Assert.True(invalidContentTestCouple.ExpectedValidationMessages.Contains(validationMessage)); Assert.False(status); } @@ -83,28 +103,6 @@ public void ValidateWithInvalidSyntaxShouldReturnFalseAndGiveValidationError() Assert.True(invalidSyntaxTestRequest.ExpectedValidationMessages.Contains(messagesList.ToString())); Assert.False(validateResult); } - - [Fact] - public void MultipleValidateShouldNotHoldValidationState() - { - XmlValidator validator = new XmlValidatorTestImplementation(); - - var invalidContentTestCouple = new TestGenerator.InvalidContentTestCouple(); - List messagesList; - var validateResult = validator.Validate(invalidContentTestCouple.Input(), out messagesList); - Assert.False(validateResult); - Assert.True(invalidContentTestCouple.ExpectedValidationMessages.Contains(messagesList.ToString())); - - var validTestCouple = new TestGenerator.ValidTestCouple(); - validateResult = validator.Validate(validTestCouple.Input(), out messagesList); - Assert.True(validateResult); - Assert.Equal(0, messagesList.Count); - - var invalidSyntaxTestCouple = new TestGenerator.InvalidSyntaxTestCouple(); - validateResult = validator.Validate(invalidSyntaxTestCouple.Input(), out messagesList); - Assert.False(validateResult); - Assert.True(invalidSyntaxTestCouple.ExpectedValidationMessages.Contains(messagesList.ToString())); - } } } } \ No newline at end of file diff --git a/Difi.Felles.Utility/CertificateChainValidator.cs b/Difi.Felles.Utility/CertificateChainValidator.cs index e6e5449..7e17038 100755 --- a/Difi.Felles.Utility/CertificateChainValidator.cs +++ b/Difi.Felles.Utility/CertificateChainValidator.cs @@ -42,24 +42,24 @@ public bool IsValidChain(X509Certificate2 certificate) /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// /// - /// Status på kjeden etter validering hvis validering feilet. + /// Status på kjeden etter validering hvis validering feilet. /// [Obsolete("Use IsValidChain instead.")] - public bool ErGyldigSertifikatkjede(X509Certificate2 certificate, out string detaljertFeilinformasjon) + public bool ErGyldigSertifikatkjede(X509Certificate2 certificate, out string detailedErrorInformation) { - return IsValidChain(certificate, out detaljertFeilinformasjon); + return IsValidChain(certificate, out detailedErrorInformation); } /// /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// /// - /// Status på kjeden etter validering hvis validering feilet. + /// Status på kjeden etter validering hvis validering feilet. /// - public bool IsValidChain(X509Certificate2 certificate, out string detaljertFeilinformasjon) + public bool IsValidChain(X509Certificate2 certificate, out string detailedErrorInformation) { var result = Validate(certificate); - detaljertFeilinformasjon = result.Message; + detailedErrorInformation = result.Message; return result.Type == CertificateValidationType.Valid; } @@ -132,10 +132,10 @@ private CertificateValidationResult ValidateThatUsingOnlyValidatorCertificates(X return ValidResult(certificate); } - private static CertificateValidationResult UsedExternalCertificatesResult(X509Certificate2 sertifikat, string chainAsString, string validatorCertificatesAsString) + private static CertificateValidationResult UsedExternalCertificatesResult(X509Certificate2 certificate, string chainAsString, string validatorCertificatesAsString) { return new CertificateValidationResult(CertificateValidationType.InvalidChain, - $"Validering av '{sertifikat.ToShortString()}' feilet. {Environment.NewLine}" + + $"Validering av '{certificate.ToShortString()}' feilet. {Environment.NewLine}" + $"Dette skjer fordi kjeden ble bygd med følgende sertifikater: {Environment.NewLine}{chainAsString}, " + $"men kun følgende er godkjent for å bygge kjeden: {Environment.NewLine}{validatorCertificatesAsString}. Dette skjer som oftest om sertifikater blir hentet fra Certificate Store på Windows, " + "og det tillates ikke under validering. Det er kun gyldig å bygge en kjede med de sertifikatene sendt inn til validatoren."); diff --git a/Difi.Felles.Utility/CertificateValidator.cs b/Difi.Felles.Utility/CertificateValidator.cs index 26d566b..ca9df28 100755 --- a/Difi.Felles.Utility/CertificateValidator.cs +++ b/Difi.Felles.Utility/CertificateValidator.cs @@ -87,14 +87,14 @@ private static bool IsIssuedToOrganizationNumber(X509Certificate certificate, st return certificate.Subject.Contains($"SERIALNUMBER={certificateOrganizationNumber}") || certificate.Subject.Contains($"CN={certificateOrganizationNumber}"); } - private static bool IsActivatedCertificate(X509Certificate certificate) + private static bool IsActivatedCertificate(X509Certificate2 certificate) { - return DateTime.Now > DateTime.Parse(certificate.GetEffectiveDateString()); + return DateTime.Now > certificate.NotBefore; } - private static bool IsExpiredCertificate(X509Certificate certificate) + private static bool IsExpiredCertificate(X509Certificate2 certificate) { - return DateTime.Now > DateTime.Parse(certificate.GetExpirationDateString()); + return DateTime.Now > certificate.NotAfter; } } } \ No newline at end of file diff --git a/Difi.Felles.Utility/Properties/AssemblyInfo.cs b/Difi.Felles.Utility/Properties/AssemblyInfo.cs index c4d9483..36de275 100755 --- a/Difi.Felles.Utility/Properties/AssemblyInfo.cs +++ b/Difi.Felles.Utility/Properties/AssemblyInfo.cs @@ -4,5 +4,4 @@ [assembly: AssemblyTitle("Difi.Felles.Utility")] [assembly: ComVisible(false)] - [assembly: InternalsVisibleTo("Difi.Oppslagstjeneste.Klient.Tester,PublicKey=00240000048000009400000006020000002400005253413100040000010001008b3388f9c416425f0145bbcf26e66b9a87c4e08b4cd41563e4bc8846df38ba4d997c5408cc77da26d79b03c39874a6af9df0aff3e7bdb3c0e53a91f6d19c50e160f5bf67986a04f0f985eca0252f557ed9ae520dd51e3107d6168d073d4ec5ada28d34e492ad9fb7af29c82309c5c0124211e679caea38d5463d2af9042dafda")] \ No newline at end of file diff --git a/Difi.Felles.Utility/Security/SignedXmlWithAgnosticId.cs b/Difi.Felles.Utility/Security/SignedXmlWithAgnosticId.cs index 561c1aa..78cda51 100755 --- a/Difi.Felles.Utility/Security/SignedXmlWithAgnosticId.cs +++ b/Difi.Felles.Utility/Security/SignedXmlWithAgnosticId.cs @@ -47,7 +47,7 @@ public SignedXmlWithAgnosticId(XmlDocument xmlDocument, X509Certificate2 certifi // Adds signature method to crypto api if (CryptoConfig.CreateFromName(signatureMethod) == null) - CryptoConfig.AddAlgorithm(typeof (RsaPkCs1Sha256SignatureDescription), signatureMethod); + CryptoConfig.AddAlgorithm(typeof(RsaPkCs1Sha256SignatureDescription), signatureMethod); // Makes sure the signingkey is using Microsoft Enhanced RSA and AES Cryptographic Provider which enables SHA256 if (!certificate.HasPrivateKey) @@ -90,11 +90,11 @@ public override XmlElement GetIdElement(XmlDocument doc, string id) // Check to se if id element is within the signatures object node. This is used by ESIs Xml Advanced Electronic Signatures (Xades) if (idElem == null) { - if (Signature != null && Signature.ObjectList != null) + if ((Signature != null) && (Signature.ObjectList != null)) { foreach (DataObject dataObject in Signature.ObjectList) { - if (dataObject.Data != null && dataObject.Data.Count > 0) + if ((dataObject.Data != null) && (dataObject.Data.Count > 0)) { foreach (XmlNode dataNode in dataObject.Data) { @@ -145,7 +145,7 @@ private AsymmetricAlgorithm GetNextKey() GetPublicKeysAndSetEnumerator(); } - while (_publicKeyListEnumerator != null && _publicKeyListEnumerator.MoveNext()) + while ((_publicKeyListEnumerator != null) && _publicKeyListEnumerator.MoveNext()) { publicKey = _publicKeyListEnumerator.Current; } @@ -191,7 +191,7 @@ private X509Certificate2 GetBinarySecurityToken(XmlNode securityTokenReference) X509Certificate2 publicCertificate = null; var keyElement = FindIdElement(_xmlDokument, securityTokenReferenceUri); - if (keyElement != null && !string.IsNullOrEmpty(keyElement.InnerText)) + if ((keyElement != null) && !string.IsNullOrEmpty(keyElement.InnerText)) { publicCertificate = new X509Certificate2(Convert.FromBase64String(keyElement.InnerText)); } diff --git a/Difi.Felles.Utility/Validation/ValidationMessages.cs b/Difi.Felles.Utility/Validation/ValidationMessages.cs index db152da..7f18a02 100755 --- a/Difi.Felles.Utility/Validation/ValidationMessages.cs +++ b/Difi.Felles.Utility/Validation/ValidationMessages.cs @@ -7,9 +7,9 @@ namespace Difi.Felles.Utility.Validation { public class ValidationMessages : List { - public bool HasErrors { get; private set; } = false; + public bool HasErrors { get; private set; } - public bool HasWarnings { get; private set; } = false; + public bool HasWarnings { get; private set; } internal void Add(XmlSeverityType severity, string message) { diff --git a/Difi.Felles.Utility/Validation/XmlValidationRunner.cs b/Difi.Felles.Utility/Validation/XmlValidationRunner.cs index 04ce616..31a6314 100755 --- a/Difi.Felles.Utility/Validation/XmlValidationRunner.cs +++ b/Difi.Felles.Utility/Validation/XmlValidationRunner.cs @@ -15,13 +15,13 @@ internal class XmlValidationRunner internal static readonly List ToleratedErrors = new List {ToleratedXsdIdErrorEnUs, ToleratedXsdIdErrorNbNo, ToleratedPrefixListErrorEnUs, ToleratedPrefixListErrorNbNo}; - internal XmlSchemaSet XmlSchemaSet { get; } - internal XmlValidationRunner(XmlSchemaSet xmlSchemaSet) { XmlSchemaSet = xmlSchemaSet; } + internal XmlSchemaSet XmlSchemaSet { get; } + internal ValidationMessages ValidationMessages { get; } = new ValidationMessages(); internal bool Validate(string document) diff --git a/SharedAssemblyInfo.cs b/SharedAssemblyInfo.cs index 5a73eff..309bffb 100755 --- a/SharedAssemblyInfo.cs +++ b/SharedAssemblyInfo.cs @@ -9,5 +9,4 @@ [assembly: AssemblyFileVersion("0.8.0.*")] [assembly: AssemblyCopyright("© 2015-2016 Direktoratet for forvaltning og IKT (Difi)")] [assembly: AssemblyCulture("")] - [assembly: InternalsVisibleTo("Difi.Felles.Utility.Tester,PublicKey=00240000048000009400000006020000002400005253413100040000010001008b3388f9c416425f0145bbcf26e66b9a87c4e08b4cd41563e4bc8846df38ba4d997c5408cc77da26d79b03c39874a6af9df0aff3e7bdb3c0e53a91f6d19c50e160f5bf67986a04f0f985eca0252f557ed9ae520dd51e3107d6168d073d4ec5ada28d34e492ad9fb7af29c82309c5c0124211e679caea38d5463d2af9042dafda")] \ No newline at end of file From 34b0e5dd25c4cdfaa62a064735ee6325f5983221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20Aas=20Sja=CC=8Afjell?= Date: Tue, 27 Sep 2016 13:57:57 +0200 Subject: [PATCH 10/10] Flytter ressurser til eget prosjekt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Det blir veldig verbose greier av å flytte så mange sertifikater, men skal i utgangspunktet være en veldig snill greie, så det er ikke så skummelt som det ser ut til --- .../Certificate/CertificateResource.cs | 104 ++++++++++++++++ .../Data/ProdChain}/BPClass3CA3.cer | Bin .../Data/ProdChain}/BPClass3RootCA.cer | Bin .../cpn enterprise sha256 class 3.crt | Bin .../ProdChain}/cpn rootca sha256 class 3.crt | Bin .../TestChain}/Buypass_Class_3_Test4_CA_3.cer | Bin .../Buypass_Class_3_Test4_Root_CA.cer | Bin ...enterprise-norwegian sha256 ca - test2.crt | 0 .../root - cpn root sha256 ca - test.crt | 0 .../UnitTests}/ExpiredSelfSignedBringAs.cer | Bin .../NotActivatedSelfSignedBringAs.cer | Bin .../Data/UnitTests}/PostenNorgeAs.cer | 0 .../UnitTests}/ValidSelfSignedBringAs.cer | Bin .../Data/UnitTests}/difi-enhetstester.cer | Bin .../Data/UnitTests}/difi-enhetstester.p12 | Bin ...mottakersertifikatFraOppslagstjenesten.pem | 0 ...mottakersertifikatFraOppslagstjenesten.pem | 0 .../Difi.Felles.Utility.Resources.csproj | 116 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 7 ++ .../Xml/Data}/InvalidIdentifikatorContent.xml | 26 ++-- .../Xml/Data}/Transportkvittering.cs | 0 .../Xml/Data/UnknownElement.xml | 13 ++ .../Xml/Data}/Valid.xml | 32 ++--- .../Xml/XmlResource.cs | 34 +++++ .../Xml/XmlUtility.cs | 15 +++ .../Xsd/Data/Sample.xsd | 44 +++++++ .../Xsd/XsdResource.cs | 21 ++++ Difi.Felles.Utility.Resources/packages.config | 4 + .../CertificateChainValidatorTests.cs | 38 +++--- .../CertificateUtility.cs | 30 ----- .../CertificateValidatorTests.cs | 74 ++++++----- .../Difi.Felles.Utility.Tester.csproj | 43 ++----- .../Security/SignedXmlWithAgnosticIdTests.cs | 5 +- .../SertifikatUtility.cs | 50 -------- .../Testdata/Xml/UnknownElement.xml | 13 -- .../Testdata/Xsd/Sample.xsd | 54 -------- .../Utilities/CertificateChainUtilityTests.cs | 6 +- .../Validation/TestGenerator.cs | 15 +-- .../XmlValidatorTestImplementation.cs | 15 +-- .../CertificateChainValidator.cs | 37 +++--- Difi.Felles.Utility/CertificateValidator.cs | 2 +- .../Difi.Felles.Utility.csproj | 18 ++- .../Extensions/X509Certificate2Extensions.cs | 4 +- .../Certificates/Production/BPClass3CA3.cer | Bin 1231 -> 0 bytes .../Production/BPClass3RootCA.cer | Bin 1373 -> 0 bytes .../cpn enterprise sha256 class 3.crt | Bin 1283 -> 0 bytes .../Production/cpn rootca sha256 class 3.crt | Bin 1087 -> 0 bytes .../Test/Buypass_Class_3_Test4_CA_3.cer | Bin 1251 -> 0 bytes .../Test/Buypass_Class_3_Test4_Root_CA.cer | Bin 1385 -> 0 bytes ...enterprise-norwegian sha256 ca - test2.crt | 36 ------ .../Test/root - cpn root sha256 ca - test.crt | 33 ----- .../Utilities/CertificateChainUtility.cs | 30 +---- difi-felles-utility.nuspec | 1 + difi-felles-utility.sln | 6 + 54 files changed, 507 insertions(+), 419 deletions(-) create mode 100755 Difi.Felles.Utility.Resources/Certificate/CertificateResource.cs rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod => Difi.Felles.Utility.Resources/Certificate/Data/ProdChain}/BPClass3CA3.cer (100%) mode change 100644 => 100755 rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod => Difi.Felles.Utility.Resources/Certificate/Data/ProdChain}/BPClass3RootCA.cer (100%) mode change 100644 => 100755 rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod => Difi.Felles.Utility.Resources/Certificate/Data/ProdChain}/cpn enterprise sha256 class 3.crt (100%) mode change 100644 => 100755 rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod => Difi.Felles.Utility.Resources/Certificate/Data/ProdChain}/cpn rootca sha256 class 3.crt (100%) mode change 100644 => 100755 rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test => Difi.Felles.Utility.Resources/Certificate/Data/TestChain}/Buypass_Class_3_Test4_CA_3.cer (100%) mode change 100644 => 100755 rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test => Difi.Felles.Utility.Resources/Certificate/Data/TestChain}/Buypass_Class_3_Test4_Root_CA.cer (100%) mode change 100644 => 100755 rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test => Difi.Felles.Utility.Resources/Certificate/Data/TestChain}/intermediate - commfides cpn enterprise-norwegian sha256 ca - test2.crt (100%) mode change 100644 => 100755 rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test => Difi.Felles.Utility.Resources/Certificate/Data/TestChain}/root - cpn root sha256 ca - test.crt (100%) mode change 100644 => 100755 rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester => Difi.Felles.Utility.Resources/Certificate/Data/UnitTests}/ExpiredSelfSignedBringAs.cer (100%) rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester => Difi.Felles.Utility.Resources/Certificate/Data/UnitTests}/NotActivatedSelfSignedBringAs.cer (100%) rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester => Difi.Felles.Utility.Resources/Certificate/Data/UnitTests}/PostenNorgeAs.cer (100%) rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester => Difi.Felles.Utility.Resources/Certificate/Data/UnitTests}/ValidSelfSignedBringAs.cer (100%) rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester => Difi.Felles.Utility.Resources/Certificate/Data/UnitTests}/difi-enhetstester.cer (100%) rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester => Difi.Felles.Utility.Resources/Certificate/Data/UnitTests}/difi-enhetstester.p12 (100%) rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod => Difi.Felles.Utility.Resources/Certificate/Data/UnitTests}/produksjonsmottakersertifikatFraOppslagstjenesten.pem (100%) rename {Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test => Difi.Felles.Utility.Resources/Certificate/Data/UnitTests}/testmottakersertifikatFraOppslagstjenesten.pem (100%) create mode 100755 Difi.Felles.Utility.Resources/Difi.Felles.Utility.Resources.csproj create mode 100755 Difi.Felles.Utility.Resources/Properties/AssemblyInfo.cs rename {Difi.Felles.Utility.Tester/Testdata/Xml => Difi.Felles.Utility.Resources/Xml/Data}/InvalidIdentifikatorContent.xml (83%) rename {Difi.Felles.Utility.Tester/Testdata => Difi.Felles.Utility.Resources/Xml/Data}/Transportkvittering.cs (100%) create mode 100755 Difi.Felles.Utility.Resources/Xml/Data/UnknownElement.xml rename {Difi.Felles.Utility.Tester/Testdata/Xml => Difi.Felles.Utility.Resources/Xml/Data}/Valid.xml (61%) create mode 100755 Difi.Felles.Utility.Resources/Xml/XmlResource.cs create mode 100755 Difi.Felles.Utility.Resources/Xml/XmlUtility.cs create mode 100755 Difi.Felles.Utility.Resources/Xsd/Data/Sample.xsd create mode 100755 Difi.Felles.Utility.Resources/Xsd/XsdResource.cs create mode 100755 Difi.Felles.Utility.Resources/packages.config delete mode 100755 Difi.Felles.Utility.Tester/CertificateUtility.cs delete mode 100755 Difi.Felles.Utility.Tester/SertifikatUtility.cs delete mode 100755 Difi.Felles.Utility.Tester/Testdata/Xml/UnknownElement.xml delete mode 100755 Difi.Felles.Utility.Tester/Testdata/Xsd/Sample.xsd delete mode 100755 Difi.Felles.Utility/Resources/Certificates/Production/BPClass3CA3.cer delete mode 100755 Difi.Felles.Utility/Resources/Certificates/Production/BPClass3RootCA.cer delete mode 100755 Difi.Felles.Utility/Resources/Certificates/Production/cpn enterprise sha256 class 3.crt delete mode 100755 Difi.Felles.Utility/Resources/Certificates/Production/cpn rootca sha256 class 3.crt delete mode 100755 Difi.Felles.Utility/Resources/Certificates/Test/Buypass_Class_3_Test4_CA_3.cer delete mode 100755 Difi.Felles.Utility/Resources/Certificates/Test/Buypass_Class_3_Test4_Root_CA.cer delete mode 100755 Difi.Felles.Utility/Resources/Certificates/Test/intermediate - commfides cpn enterprise-norwegian sha256 ca - test2.crt delete mode 100755 Difi.Felles.Utility/Resources/Certificates/Test/root - cpn root sha256 ca - test.crt diff --git a/Difi.Felles.Utility.Resources/Certificate/CertificateResource.cs b/Difi.Felles.Utility.Resources/Certificate/CertificateResource.cs new file mode 100755 index 0000000..ee62cce --- /dev/null +++ b/Difi.Felles.Utility.Resources/Certificate/CertificateResource.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; +using ApiClientShared; + +namespace Difi.Felles.Utility.Resources.Certificate +{ + internal class CertificateResource + { + private static readonly ResourceUtility ResourceUtility = new ResourceUtility("Difi.Felles.Utility.Resources.Certificate.Data"); + + internal static X509Certificate2 GetCertificate(params string[] path) + { + return new X509Certificate2(ResourceUtility.ReadAllBytes(true, path), "", X509KeyStorageFlags.Exportable); + } + + public static class UnitTests + { + public static X509Certificate2 GetProduksjonsMottakerSertifikatOppslagstjenesten() + { + return GetCertificate("UnitTests", "produksjonsmottakersertifikatFraOppslagstjenesten.pem"); + } + + public static X509Certificate2 GetFunksjoneltTestmiljøMottakerSertifikatOppslagstjenesten() + { + return GetCertificate("UnitTests", "testmottakersertifikatFraOppslagstjenesten.pem"); + } + + public static X509Certificate2 NotActivatedSelfSignedTestCertificate() + { + return GetCertificate("UnitTests", "NotActivatedSelfSignedBringAs.cer"); + } + + public static X509Certificate2 GetExpiredSelfSignedTestCertificate() + { + return GetCertificate("UnitTests", "ExpiredSelfSignedBringAs.cer"); + } + + public static X509Certificate2 GetValidSelfSignedTestCertificate() + { + return GetCertificate("UnitTests", "ValidSelfSignedBringAs.cer"); + } + + public static X509Certificate2 TestIntegrasjonssertifikat() + { + return GetPostenCertificate(); + } + + public static X509Certificate2 GetEnhetstesterSelvsignertSertifikat() + { + return GetCertificate("UnitTests", "difi-enhetstester.cer"); + } + + public static X509Certificate2 GetPostenCertificate() + { + return GetCertificate("UnitTests", "PostenNorgeAs.cer"); + } + + internal static X509Certificate2 GetAvsenderEnhetstesterSertifikat() + { + return EvigTestSertifikatMedPrivatnøkkel(); + } + + internal static X509Certificate2 GetMottakerEnhetstesterSertifikat() + { + return EvigTestSertifikatUtenPrivatnøkkel(); + } + + private static X509Certificate2 EvigTestSertifikatUtenPrivatnøkkel() + { + return GetCertificate("UnitTests", "difi-enhetstester.cer"); + } + + private static X509Certificate2 EvigTestSertifikatMedPrivatnøkkel() + { + return GetCertificate("UnitTests", "difi-enhetstester.p12"); + } + } + + public static class Chain + { + public static List GetDifiTestChain() + { + return new List + { + new X509Certificate2(GetCertificate("TestChain", "Buypass_Class_3_Test4_CA_3.cer")), + new X509Certificate2(GetCertificate("TestChain", "Buypass_Class_3_Test4_Root_CA.cer")), + new X509Certificate2(GetCertificate("TestChain", "intermediate - commfides cpn enterprise-norwegian sha256 ca - test2.crt")), + new X509Certificate2(GetCertificate("TestChain", "root - cpn root sha256 ca - test.crt")) + }; + } + + public static List GetDifiProductionChain() + { + return new List + { + new X509Certificate2(GetCertificate("ProdChain", "BPClass3CA3.cer")), + new X509Certificate2(GetCertificate("ProdChain", "BPClass3RootCA.cer")), + new X509Certificate2(GetCertificate("ProdChain", "cpn enterprise sha256 class 3.crt")), + new X509Certificate2(GetCertificate("ProdChain", "cpn rootca sha256 class 3.crt")) + }; + } + } + } +} \ No newline at end of file diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod/BPClass3CA3.cer b/Difi.Felles.Utility.Resources/Certificate/Data/ProdChain/BPClass3CA3.cer old mode 100644 new mode 100755 similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod/BPClass3CA3.cer rename to Difi.Felles.Utility.Resources/Certificate/Data/ProdChain/BPClass3CA3.cer diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod/BPClass3RootCA.cer b/Difi.Felles.Utility.Resources/Certificate/Data/ProdChain/BPClass3RootCA.cer old mode 100644 new mode 100755 similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod/BPClass3RootCA.cer rename to Difi.Felles.Utility.Resources/Certificate/Data/ProdChain/BPClass3RootCA.cer diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod/cpn enterprise sha256 class 3.crt b/Difi.Felles.Utility.Resources/Certificate/Data/ProdChain/cpn enterprise sha256 class 3.crt old mode 100644 new mode 100755 similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod/cpn enterprise sha256 class 3.crt rename to Difi.Felles.Utility.Resources/Certificate/Data/ProdChain/cpn enterprise sha256 class 3.crt diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod/cpn rootca sha256 class 3.crt b/Difi.Felles.Utility.Resources/Certificate/Data/ProdChain/cpn rootca sha256 class 3.crt old mode 100644 new mode 100755 similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod/cpn rootca sha256 class 3.crt rename to Difi.Felles.Utility.Resources/Certificate/Data/ProdChain/cpn rootca sha256 class 3.crt diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test/Buypass_Class_3_Test4_CA_3.cer b/Difi.Felles.Utility.Resources/Certificate/Data/TestChain/Buypass_Class_3_Test4_CA_3.cer old mode 100644 new mode 100755 similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test/Buypass_Class_3_Test4_CA_3.cer rename to Difi.Felles.Utility.Resources/Certificate/Data/TestChain/Buypass_Class_3_Test4_CA_3.cer diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test/Buypass_Class_3_Test4_Root_CA.cer b/Difi.Felles.Utility.Resources/Certificate/Data/TestChain/Buypass_Class_3_Test4_Root_CA.cer old mode 100644 new mode 100755 similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test/Buypass_Class_3_Test4_Root_CA.cer rename to Difi.Felles.Utility.Resources/Certificate/Data/TestChain/Buypass_Class_3_Test4_Root_CA.cer diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test/intermediate - commfides cpn enterprise-norwegian sha256 ca - test2.crt b/Difi.Felles.Utility.Resources/Certificate/Data/TestChain/intermediate - commfides cpn enterprise-norwegian sha256 ca - test2.crt old mode 100644 new mode 100755 similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test/intermediate - commfides cpn enterprise-norwegian sha256 ca - test2.crt rename to Difi.Felles.Utility.Resources/Certificate/Data/TestChain/intermediate - commfides cpn enterprise-norwegian sha256 ca - test2.crt diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test/root - cpn root sha256 ca - test.crt b/Difi.Felles.Utility.Resources/Certificate/Data/TestChain/root - cpn root sha256 ca - test.crt old mode 100644 new mode 100755 similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test/root - cpn root sha256 ca - test.crt rename to Difi.Felles.Utility.Resources/Certificate/Data/TestChain/root - cpn root sha256 ca - test.crt diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ExpiredSelfSignedBringAs.cer b/Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/ExpiredSelfSignedBringAs.cer similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ExpiredSelfSignedBringAs.cer rename to Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/ExpiredSelfSignedBringAs.cer diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/NotActivatedSelfSignedBringAs.cer b/Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/NotActivatedSelfSignedBringAs.cer similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/NotActivatedSelfSignedBringAs.cer rename to Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/NotActivatedSelfSignedBringAs.cer diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/PostenNorgeAs.cer b/Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/PostenNorgeAs.cer similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/PostenNorgeAs.cer rename to Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/PostenNorgeAs.cer diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ValidSelfSignedBringAs.cer b/Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/ValidSelfSignedBringAs.cer similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/ValidSelfSignedBringAs.cer rename to Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/ValidSelfSignedBringAs.cer diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/difi-enhetstester.cer b/Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/difi-enhetstester.cer similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/difi-enhetstester.cer rename to Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/difi-enhetstester.cer diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/difi-enhetstester.p12 b/Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/difi-enhetstester.p12 similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Enhetstester/difi-enhetstester.p12 rename to Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/difi-enhetstester.p12 diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod/produksjonsmottakersertifikatFraOppslagstjenesten.pem b/Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/produksjonsmottakersertifikatFraOppslagstjenesten.pem similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Prod/produksjonsmottakersertifikatFraOppslagstjenesten.pem rename to Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/produksjonsmottakersertifikatFraOppslagstjenesten.pem diff --git a/Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test/testmottakersertifikatFraOppslagstjenesten.pem b/Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/testmottakersertifikatFraOppslagstjenesten.pem similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Sertifikater/Test/testmottakersertifikatFraOppslagstjenesten.pem rename to Difi.Felles.Utility.Resources/Certificate/Data/UnitTests/testmottakersertifikatFraOppslagstjenesten.pem diff --git a/Difi.Felles.Utility.Resources/Difi.Felles.Utility.Resources.csproj b/Difi.Felles.Utility.Resources/Difi.Felles.Utility.Resources.csproj new file mode 100755 index 0000000..507374c --- /dev/null +++ b/Difi.Felles.Utility.Resources/Difi.Felles.Utility.Resources.csproj @@ -0,0 +1,116 @@ + + + + + Debug + AnyCPU + {C737EA02-E687-45C4-95DB-72B5083246F2} + Library + Properties + Difi.Felles.Utility.Resources + Difi.Felles.Utility.Resources + v4.5 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + + + C:\Keys\digipost.pfx + + + + ..\packages\api-client-shared.1.0.5968.19413\lib\net45\ApiClientShared.dll + True + + + + + + + + + + + + + Properties\SharedAssemblyInfo.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Designer + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Difi.Felles.Utility.Resources/Properties/AssemblyInfo.cs b/Difi.Felles.Utility.Resources/Properties/AssemblyInfo.cs new file mode 100755 index 0000000..cd01984 --- /dev/null +++ b/Difi.Felles.Utility.Resources/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Difi.Felles.Utility.Resources")] +[assembly: ComVisible(false)] +[assembly: InternalsVisibleTo("Difi.Felles.Utility,PublicKey=00240000048000009400000006020000002400005253413100040000010001008b3388f9c416425f0145bbcf26e66b9a87c4e08b4cd41563e4bc8846df38ba4d997c5408cc77da26d79b03c39874a6af9df0aff3e7bdb3c0e53a91f6d19c50e160f5bf67986a04f0f985eca0252f557ed9ae520dd51e3107d6168d073d4ec5ada28d34e492ad9fb7af29c82309c5c0124211e679caea38d5463d2af9042dafda")] \ No newline at end of file diff --git a/Difi.Felles.Utility.Tester/Testdata/Xml/InvalidIdentifikatorContent.xml b/Difi.Felles.Utility.Resources/Xml/Data/InvalidIdentifikatorContent.xml similarity index 83% rename from Difi.Felles.Utility.Tester/Testdata/Xml/InvalidIdentifikatorContent.xml rename to Difi.Felles.Utility.Resources/Xml/Data/InvalidIdentifikatorContent.xml index 2981bde..98fc8ac 100755 --- a/Difi.Felles.Utility.Tester/Testdata/Xml/InvalidIdentifikatorContent.xml +++ b/Difi.Felles.Utility.Resources/Xml/Data/InvalidIdentifikatorContent.xml @@ -1,13 +1,13 @@ - - -
- - - -
- - - invalidContent - - -
+ + +
+ + + +
+ + + invalidContent + + +
\ No newline at end of file diff --git a/Difi.Felles.Utility.Tester/Testdata/Transportkvittering.cs b/Difi.Felles.Utility.Resources/Xml/Data/Transportkvittering.cs similarity index 100% rename from Difi.Felles.Utility.Tester/Testdata/Transportkvittering.cs rename to Difi.Felles.Utility.Resources/Xml/Data/Transportkvittering.cs diff --git a/Difi.Felles.Utility.Resources/Xml/Data/UnknownElement.xml b/Difi.Felles.Utility.Resources/Xml/Data/UnknownElement.xml new file mode 100755 index 0000000..dfa4d10 --- /dev/null +++ b/Difi.Felles.Utility.Resources/Xml/Data/UnknownElement.xml @@ -0,0 +1,13 @@ + + +
+ + + +
+ + + + + +
\ No newline at end of file diff --git a/Difi.Felles.Utility.Tester/Testdata/Xml/Valid.xml b/Difi.Felles.Utility.Resources/Xml/Data/Valid.xml similarity index 61% rename from Difi.Felles.Utility.Tester/Testdata/Xml/Valid.xml rename to Difi.Felles.Utility.Resources/Xml/Data/Valid.xml index cd09245..e05d223 100755 --- a/Difi.Felles.Utility.Tester/Testdata/Xml/Valid.xml +++ b/Difi.Felles.Utility.Resources/Xml/Data/Valid.xml @@ -1,16 +1,16 @@ - - -
- - - -
- - - abc - - - bbb - - -
+ + +
+ + + +
+ + + abc + + + bbb + + +
\ No newline at end of file diff --git a/Difi.Felles.Utility.Resources/Xml/XmlResource.cs b/Difi.Felles.Utility.Resources/Xml/XmlResource.cs new file mode 100755 index 0000000..e2b0798 --- /dev/null +++ b/Difi.Felles.Utility.Resources/Xml/XmlResource.cs @@ -0,0 +1,34 @@ +using System.Text; +using ApiClientShared; + +namespace Difi.Felles.Utility.Resources.Xml +{ + public class XmlResource + { + private static readonly ResourceUtility ResourceUtility = new ResourceUtility("Difi.Felles.Utility.Resources.Xml.Data"); + + private static string GetResource(params string[] path) + { + var bytes = ResourceUtility.ReadAllBytes(true, path); + return XmlUtility.ToXmlDocument(Encoding.UTF8.GetString(bytes)).OuterXml; + } + + internal class GetContent + { + public static string GetInvalid() + { + return GetResource("InvalidIdentifikatorContent.xml"); + } + + public static string GetContentWithUnknownElement() + { + return GetResource("UnknownElement.xml"); + } + + public static string GetValid() + { + return GetResource("Valid.xml"); + } + } + } +} \ No newline at end of file diff --git a/Difi.Felles.Utility.Resources/Xml/XmlUtility.cs b/Difi.Felles.Utility.Resources/Xml/XmlUtility.cs new file mode 100755 index 0000000..a59ba84 --- /dev/null +++ b/Difi.Felles.Utility.Resources/Xml/XmlUtility.cs @@ -0,0 +1,15 @@ +using System.Xml; + +namespace Difi.Felles.Utility.Resources.Xml +{ + public class XmlUtility + { + public static XmlDocument ToXmlDocument(string xml) + { + var xmlDocument = new XmlDocument(); + xmlDocument.LoadXml(xml); + + return xmlDocument; + } + } +} \ No newline at end of file diff --git a/Difi.Felles.Utility.Resources/Xsd/Data/Sample.xsd b/Difi.Felles.Utility.Resources/Xsd/Data/Sample.xsd new file mode 100755 index 0000000..7f73efd --- /dev/null +++ b/Difi.Felles.Utility.Resources/Xsd/Data/Sample.xsd @@ -0,0 +1,44 @@ + + + Purchase order schema for Example.com. + Copyright 2000 Example.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Difi.Felles.Utility.Resources/Xsd/XsdResource.cs b/Difi.Felles.Utility.Resources/Xsd/XsdResource.cs new file mode 100755 index 0000000..ff3f097 --- /dev/null +++ b/Difi.Felles.Utility.Resources/Xsd/XsdResource.cs @@ -0,0 +1,21 @@ +using System.IO; +using ApiClientShared; + +namespace Difi.Felles.Utility.Resources.Xsd +{ + internal class XsdResource + { + private static readonly ResourceUtility ResourceUtility = new ResourceUtility("Difi.Felles.Utility.Resources.Xsd.Data"); + + private static Stream GetResource(params string[] path) + { + var bytes = ResourceUtility.ReadAllBytes(true, path); + return new MemoryStream(bytes); + } + + public static Stream Sample() + { + return GetResource("Sample.xsd"); + } + } +} \ No newline at end of file diff --git a/Difi.Felles.Utility.Resources/packages.config b/Difi.Felles.Utility.Resources/packages.config new file mode 100755 index 0000000..1464b53 --- /dev/null +++ b/Difi.Felles.Utility.Resources/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs b/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs index 73b5418..f15b0d7 100755 --- a/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs +++ b/Difi.Felles.Utility.Tester/CertificateChainValidatorTests.cs @@ -1,60 +1,56 @@ -using Difi.Felles.Utility.Utilities; +using Difi.Felles.Utility.Resources.Certificate; +using Difi.Felles.Utility.Utilities; using Xunit; -using Assert = Xunit.Assert; namespace Difi.Felles.Utility.Tester { - public class CertificateChainValidatorTests { - - public class ValidateCertificateChainMethod : CertificateChainValidatorTests + public class ValidateCertificateChain : CertificateChainValidatorTests { [Fact] - public void Valid_with_correct_root_and_intermediate() + public void Fails_with_self_signed_certificate() { //Arrange - var productionCertificate = SertifikatUtility.GetProduksjonsMottakerSertifikatOppslagstjenesten(); - var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.ProductionCertificates()); + var selfSignedCertificate = CertificateResource.UnitTests.GetEnhetstesterSelvsignertSertifikat(); + var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); //Act - var result = certificateChainValidator.Validate(productionCertificate); + var result = certificateChainValidator.Validate(selfSignedCertificate); //Assert - Assert.Equal(CertificateValidationType.Valid, result.Type); - Assert.Contains("et gyldig sertifikat", result.Message); + Assert.Equal(CertificateValidationType.InvalidChain, result.Type); + Assert.Contains("sertifikatet er selvsignert", result.Message); } [Fact] public void Fails_with_wrong_root_and_intermediate() { //Arrange - var productionCertificate = SertifikatUtility.GetProduksjonsMottakerSertifikatOppslagstjenesten(); + var productionCertificate = CertificateResource.UnitTests.GetProduksjonsMottakerSertifikatOppslagstjenesten(); //Act - var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.TestCertificates()); + var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.FunksjoneltTestmiljøSertifikater()); var result = certificateChainValidator.Validate(productionCertificate); //Assert Assert.Equal(CertificateValidationType.InvalidChain, result.Type); Assert.Contains("blir hentet fra Certificate Store på Windows", result.Message); - } [Fact] - public void Fails_with_self_signed_certificate() + public void Valid_with_correct_root_and_intermediate() { //Arrange - var selfSignedCertificate = SertifikatUtility.GetEnhetstesterSelvsignertSertifikat(); - var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.ProductionCertificates()); + var productionCertificate = CertificateResource.UnitTests.GetProduksjonsMottakerSertifikatOppslagstjenesten(); + var certificateChainValidator = new CertificateChainValidator(CertificateChainUtility.ProduksjonsSertifikater()); //Act - var result = certificateChainValidator.Validate(selfSignedCertificate); + var result = certificateChainValidator.Validate(productionCertificate); //Assert - Assert.Equal(CertificateValidationType.InvalidChain, result.Type); - Assert.Contains("sertifikatet er selvsignert", result.Message); - + Assert.Equal(CertificateValidationType.Valid, result.Type); + Assert.Contains("et gyldig sertifikat", result.Message); } } } diff --git a/Difi.Felles.Utility.Tester/CertificateUtility.cs b/Difi.Felles.Utility.Tester/CertificateUtility.cs deleted file mode 100755 index 713278c..0000000 --- a/Difi.Felles.Utility.Tester/CertificateUtility.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Security.Cryptography.X509Certificates; -using ApiClientShared; - -namespace Difi.Felles.Utility.Tester -{ - internal class CertificateUtility - { - internal static readonly ResourceUtility ResourceUtility = new ResourceUtility("Difi.Felles.Utility.Tester.Testdata.Sertifikater.Enhetstester"); - - internal static X509Certificate2 GetAvsenderEnhetstesterSertifikat() - { - return EvigTestSertifikatMedPrivatnøkkel(); - } - - internal static X509Certificate2 GetMottakerEnhetstesterSertifikat() - { - return EvigTestSertifikatUtenPrivatnøkkel(); - } - - private static X509Certificate2 EvigTestSertifikatUtenPrivatnøkkel() - { - return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "difi-enhetstester.cer"), "", X509KeyStorageFlags.Exportable); - } - - private static X509Certificate2 EvigTestSertifikatMedPrivatnøkkel() - { - return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "difi-enhetstester.p12"), "", X509KeyStorageFlags.Exportable); - } - } -} \ No newline at end of file diff --git a/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs b/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs index 4bc8f79..b0f81c3 100755 --- a/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs +++ b/Difi.Felles.Utility.Tester/CertificateValidatorTests.cs @@ -1,9 +1,9 @@ -using Difi.Felles.Utility.Utilities; +using Difi.Felles.Utility.Resources.Certificate; +using Difi.Felles.Utility.Utilities; using Xunit; namespace Difi.Felles.Utility.Tester { - public class CertificateValidatorTests { public class ValidateCertificateAndChainMethod : CertificateValidatorTests @@ -12,10 +12,10 @@ public class ValidateCertificateAndChainMethod : CertificateValidatorTests public void Returns_fail_if_certificate_error() { //Arrange - var funksjoneltTestmiljøSertifikater = CertificateChainUtility.TestCertificates(); + var funksjoneltTestmiljøSertifikater = CertificateChainUtility.FunksjoneltTestmiljøSertifikater(); //Act - var result = CertificateValidator.ValidateCertificateAndChain(SertifikatUtility.GetExpiredSelfSignedTestCertificate(), "988015814", funksjoneltTestmiljøSertifikater); + var result = CertificateValidator.ValidateCertificateAndChain(CertificateResource.UnitTests.GetExpiredSelfSignedTestCertificate(), "988015814", funksjoneltTestmiljøSertifikater); //Assert Assert.Equal(CertificateValidationType.InvalidCertificate, result.Type); @@ -26,10 +26,10 @@ public void Returns_fail_if_certificate_error() public void Returns_fail_if_invalid_certificate_chain() { //Arrange - var funksjoneltTestmiljøSertifikater = CertificateChainUtility.TestCertificates(); + var funksjoneltTestmiljøSertifikater = CertificateChainUtility.FunksjoneltTestmiljøSertifikater(); //Act - var result = CertificateValidator.ValidateCertificateAndChain(SertifikatUtility.GetValidSelfSignedTestCertificate(), "988015814", funksjoneltTestmiljøSertifikater); + var result = CertificateValidator.ValidateCertificateAndChain(CertificateResource.UnitTests.GetValidSelfSignedTestCertificate(), "988015814", funksjoneltTestmiljøSertifikater); //Assert Assert.Equal(CertificateValidationType.InvalidChain, result.Type); @@ -39,10 +39,10 @@ public void Returns_fail_if_invalid_certificate_chain() public void Returns_ok_if_valid_certificate_and_chain() { //Arrange - var funksjoneltTestmiljøSertifikater = CertificateChainUtility.TestCertificates(); + var funksjoneltTestmiljøSertifikater = CertificateChainUtility.FunksjoneltTestmiljøSertifikater(); //Act - var result = CertificateValidator.ValidateCertificateAndChain(SertifikatUtility.GetPostenCertificate(), "984661185", funksjoneltTestmiljøSertifikater); + var result = CertificateValidator.ValidateCertificateAndChain(CertificateResource.UnitTests.GetPostenCertificate(), "984661185", funksjoneltTestmiljøSertifikater); //Assert Assert.Equal(CertificateValidationType.Valid, result.Type); @@ -52,59 +52,59 @@ public void Returns_ok_if_valid_certificate_and_chain() public class ValidateCertificateMethod : CertificateValidatorTests { [Fact] - public void Returns_fail_with_null_certificate() + public void Returns_fail_if_expired() { //Arrange - const string organizationNumber = "123456789"; + const string certificateOrganizationNumber = "988015814"; //Act - var result = CertificateValidator.ValidateCertificate(null, organizationNumber); + var result = CertificateValidator.ValidateCertificate(CertificateResource.UnitTests.GetExpiredSelfSignedTestCertificate(), certificateOrganizationNumber); //Assert Assert.Equal(CertificateValidationType.InvalidCertificate, result.Type); - Assert.Contains("var null", result.Message); + Assert.Contains("gikk ut", result.Message); } [Fact] - public void Returns_fail_if_not_issued_to_organization_number() + public void Returns_fail_if_not_activated() { //Arrange - const string certificateOrganizationNumber = "123456789"; + const string certificateOrganizationNumber = "988015814"; //Act - var result = CertificateValidator.ValidateCertificate(SertifikatUtility.TestIntegrasjonssertifikat(), certificateOrganizationNumber); + var result = CertificateValidator.ValidateCertificate(CertificateResource.UnitTests.NotActivatedSelfSignedTestCertificate(), certificateOrganizationNumber); //Assert Assert.Equal(CertificateValidationType.InvalidCertificate, result.Type); - Assert.Contains("ikke utstedt til organisasjonsnummer", result.Message); + Assert.Contains("aktiveres ikke før", result.Message); } [Fact] - public void Returns_fail_if_not_activated() + public void Returns_fail_if_not_issued_to_organization_number() { //Arrange - const string certificateOrganizationNumber = "988015814"; + const string certificateOrganizationNumber = "123456789"; //Act - var result = CertificateValidator.ValidateCertificate(SertifikatUtility.NotActivatedSelfSignedTestCertificate(), certificateOrganizationNumber); + var result = CertificateValidator.ValidateCertificate(CertificateResource.UnitTests.TestIntegrasjonssertifikat(), certificateOrganizationNumber); //Assert Assert.Equal(CertificateValidationType.InvalidCertificate, result.Type); - Assert.Contains("aktiveres ikke før", result.Message); + Assert.Contains("ikke utstedt til organisasjonsnummer", result.Message); } [Fact] - public void Returns_fail_if_expired() + public void Returns_fail_with_null_certificate() { //Arrange - const string certificateOrganizationNumber = "988015814"; + const string organizationNumber = "123456789"; //Act - var result = CertificateValidator.ValidateCertificate(SertifikatUtility.GetExpiredSelfSignedTestCertificate(), certificateOrganizationNumber); + var result = CertificateValidator.ValidateCertificate(null, organizationNumber); //Assert Assert.Equal(CertificateValidationType.InvalidCertificate, result.Type); - Assert.Contains("gikk ut",result.Message); + Assert.Contains("var null", result.Message); } [Fact] @@ -114,65 +114,63 @@ public void Returns_ok_if_valid() const string certificateOrganizationNumber = "984661185"; //Act - var result = CertificateValidator.ValidateCertificate(SertifikatUtility.GetPostenCertificate(), certificateOrganizationNumber); + var result = CertificateValidator.ValidateCertificate(CertificateResource.UnitTests.GetPostenCertificate(), certificateOrganizationNumber); //Assert Assert.Equal(CertificateValidationType.Valid, result.Type); Assert.Contains("er et gyldig sertifikat", result.Message); } - - } public class IsValidCertificateMethod : CertificateValidatorTests { [Fact] - public void Returns_false_with_null_certificate() + public void Returns_false_if_expired() { //Arrange - const string certificateOrganizationNumber = "123456789"; + var certificateOrganizationNumber = "123456789"; //Act - var isValid = CertificateValidator.IsValidCertificate(null, certificateOrganizationNumber); + var isValid = CertificateValidator.IsValidCertificate(CertificateResource.UnitTests.GetExpiredSelfSignedTestCertificate(), certificateOrganizationNumber); //Assert Assert.False(isValid); } [Fact] - public void Returns_false_if_not_issued_to_organization_number() + public void Returns_false_if_not_activated() { //Arrange var certificateOrganizationNumber = "123456789"; //Act - var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.TestIntegrasjonssertifikat(), certificateOrganizationNumber); + var isValid = CertificateValidator.IsValidCertificate(CertificateResource.UnitTests.NotActivatedSelfSignedTestCertificate(), certificateOrganizationNumber); //Assert Assert.False(isValid); } [Fact] - public void Returns_false_if_not_activated() + public void Returns_false_if_not_issued_to_organization_number() { //Arrange var certificateOrganizationNumber = "123456789"; //Act - var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.NotActivatedSelfSignedTestCertificate(), certificateOrganizationNumber); + var isValid = CertificateValidator.IsValidCertificate(CertificateResource.UnitTests.TestIntegrasjonssertifikat(), certificateOrganizationNumber); //Assert Assert.False(isValid); } [Fact] - public void Returns_false_if_expired() + public void Returns_false_with_null_certificate() { //Arrange - var certificateOrganizationNumber = "123456789"; + const string certificateOrganizationNumber = "123456789"; //Act - var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.GetExpiredSelfSignedTestCertificate(), certificateOrganizationNumber); + var isValid = CertificateValidator.IsValidCertificate(null, certificateOrganizationNumber); //Assert Assert.False(isValid); @@ -185,7 +183,7 @@ public void Returns_true_for_correct_certificate() var certificateOrganizationNumber = "984661185"; //Act - var isValid = CertificateValidator.IsValidCertificate(SertifikatUtility.GetPostenCertificate(), certificateOrganizationNumber); + var isValid = CertificateValidator.IsValidCertificate(CertificateResource.UnitTests.GetPostenCertificate(), certificateOrganizationNumber); //Assert Assert.True(isValid); diff --git a/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj b/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj index 04b60a1..93d6ed2 100755 --- a/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj +++ b/Difi.Felles.Utility.Tester/Difi.Felles.Utility.Tester.csproj @@ -49,6 +49,7 @@ True + @@ -80,15 +81,12 @@ Properties\SharedAssemblyInfo.cs - - - @@ -97,46 +95,21 @@
+ + {c737ea02-e687-45c4-95db-72b5083246f2} + Difi.Felles.Utility.Resources + {7ab8d858-878f-4184-9557-995be75dc635} Difi.Felles.Utility - - - - - - - - - - - - - - - - - - - + Designer - - - - - - - - - - - - - + + diff --git a/Difi.Felles.Utility.Tester/Security/SignedXmlWithAgnosticIdTests.cs b/Difi.Felles.Utility.Tester/Security/SignedXmlWithAgnosticIdTests.cs index 34a4d68..6b078ab 100755 --- a/Difi.Felles.Utility.Tester/Security/SignedXmlWithAgnosticIdTests.cs +++ b/Difi.Felles.Utility.Tester/Security/SignedXmlWithAgnosticIdTests.cs @@ -5,6 +5,7 @@ using System.Security.Cryptography.X509Certificates; using System.Xml; using Difi.Felles.Utility.Exceptions; +using Difi.Felles.Utility.Resources.Certificate; using Difi.Felles.Utility.Security; using Difi.Felles.Utility.Tester.Testdata; using Difi.Felles.Utility.Tester.Utilities; @@ -45,7 +46,7 @@ public void FeilerMedSertifikatUtenPrivatnøkkel() { //Arrange var xmlDokument = XmlUtility.ToXmlDocument(TransportKvittering.TransportOkKvittertingFunksjoneltTestmiljø); - var sertifikat = CertificateUtility.GetMottakerEnhetstesterSertifikat(); + var sertifikat = CertificateResource.UnitTests.GetMottakerEnhetstesterSertifikat(); //Act try @@ -64,7 +65,7 @@ public void KonstruktørMedXmlDokumentOgSertifikat() { //Arrange var xmlDokument = XmlUtility.ToXmlDocument(TransportKvittering.TransportOkKvittertingFunksjoneltTestmiljø); - var sertifikat = CertificateUtility.GetAvsenderEnhetstesterSertifikat(); + var sertifikat = CertificateResource.UnitTests.GetAvsenderEnhetstesterSertifikat(); var signedXmlWithAgnosticId = new SignedXmlWithAgnosticId(xmlDokument, sertifikat); //Act diff --git a/Difi.Felles.Utility.Tester/SertifikatUtility.cs b/Difi.Felles.Utility.Tester/SertifikatUtility.cs deleted file mode 100755 index 2ab35ba..0000000 --- a/Difi.Felles.Utility.Tester/SertifikatUtility.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.Security.Cryptography.X509Certificates; -using ApiClientShared; - -namespace Difi.Felles.Utility.Tester -{ - internal class SertifikatUtility - { - private static readonly ResourceUtility ResourceUtility = new ResourceUtility("Difi.Felles.Utility.Tester.Testdata.Sertifikater"); - - public static X509Certificate2 GetProduksjonsMottakerSertifikatOppslagstjenesten() - { - return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Prod", "produksjonsmottakersertifikatFraOppslagstjenesten.pem")); - } - - public static X509Certificate2 GetFunksjoneltTestmiljøMottakerSertifikatOppslagstjenesten() - { - return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Test", "testmottakersertifikatFraOppslagstjenesten.pem")); - } - - public static X509Certificate2 NotActivatedSelfSignedTestCertificate() - { - return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Enhetstester", "NotActivatedSelfSignedBringAs.cer")); - } - - public static X509Certificate2 GetExpiredSelfSignedTestCertificate() - { - return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Enhetstester", "ExpiredSelfSignedBringAs.cer")); - } - - public static X509Certificate2 GetValidSelfSignedTestCertificate() - { - return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Enhetstester", "ValidSelfSignedBringAs.cer")); - } - - public static X509Certificate2 TestIntegrasjonssertifikat() - { - return GetPostenCertificate(); - } - - public static X509Certificate2 GetEnhetstesterSelvsignertSertifikat() - { - return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Enhetstester", "difi-enhetstester.cer")); - } - - public static X509Certificate2 GetPostenCertificate() - { - return new X509Certificate2(ResourceUtility.ReadAllBytes(true, "Enhetstester", "PostenNorgeAs.cer")); - } - } -} \ No newline at end of file diff --git a/Difi.Felles.Utility.Tester/Testdata/Xml/UnknownElement.xml b/Difi.Felles.Utility.Tester/Testdata/Xml/UnknownElement.xml deleted file mode 100755 index 78b6089..0000000 --- a/Difi.Felles.Utility.Tester/Testdata/Xml/UnknownElement.xml +++ /dev/null @@ -1,13 +0,0 @@ - - -
- - - -
- - - - - -
diff --git a/Difi.Felles.Utility.Tester/Testdata/Xsd/Sample.xsd b/Difi.Felles.Utility.Tester/Testdata/Xsd/Sample.xsd deleted file mode 100755 index 882e2f4..0000000 --- a/Difi.Felles.Utility.Tester/Testdata/Xsd/Sample.xsd +++ /dev/null @@ -1,54 +0,0 @@ - - - - Purchase order schema for Example.com. - Copyright 2000 Example.com. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs b/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs index 3b98fe3..20fd6ee 100755 --- a/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs +++ b/Difi.Felles.Utility.Tester/Utilities/CertificateChainUtilityTests.cs @@ -12,7 +12,7 @@ public class TestsertifikaterMethod : CertificateChainUtilityTests public void ReturnererFireSertifikaterMedThumbprint() { //Arrange - var sertifikater = CertificateChainUtility.TestCertificates(); + var sertifikater = CertificateChainUtility.FunksjoneltTestmiljøSertifikater(); //Act @@ -30,7 +30,7 @@ public class ProduksjonssertifikaterMethod : CertificateChainUtilityTests public void ReturnererFireSertifikaterMedThumbprint() { //Arrange - var sertifikater = CertificateChainUtility.ProductionCertificates(); + var sertifikater = CertificateChainUtility.ProduksjonsSertifikater(); //Act @@ -48,7 +48,7 @@ public class CertificateChainInfoTests : CertificateChainUtilityTests public void DebugMesages() { var i = 0; - foreach (var certificate in CertificateChainUtility.TestCertificates()) + foreach (var certificate in CertificateChainUtility.FunksjoneltTestmiljøSertifikater()) { Trace.WriteLine($"{i++}: Issuer `{certificate.Issuer}`, thumbprint `{certificate.Thumbprint}`"); } diff --git a/Difi.Felles.Utility.Tester/Validation/TestGenerator.cs b/Difi.Felles.Utility.Tester/Validation/TestGenerator.cs index 2b5fb7a..4bbfbca 100755 --- a/Difi.Felles.Utility.Tester/Validation/TestGenerator.cs +++ b/Difi.Felles.Utility.Tester/Validation/TestGenerator.cs @@ -1,20 +1,17 @@ using System.Collections.Generic; -using System.IO; -using System.Text; using System.Xml; using System.Xml.Schema; -using ApiClientShared; +using Difi.Felles.Utility.Resources.Xml; +using Difi.Felles.Utility.Resources.Xsd; namespace Difi.Felles.Utility.Tester.Validation { internal static class TestGenerator { - private static readonly ResourceUtility ResourceUtility = new ResourceUtility("Difi.Felles.Utility.Tester.Testdata"); - public static XmlSchemaSet XmlSchemaSet() { var xmlSchemaSet = new XmlSchemaSet(); - xmlSchemaSet.Add("http://tempuri.org/po.xsd", XmlReader.Create(new MemoryStream(ResourceUtility.ReadAllBytes(true, "Xsd.Sample.xsd")))); + xmlSchemaSet.Add("http://tempuri.org/po.xsd", XmlReader.Create(XsdResource.Sample())); return xmlSchemaSet; } @@ -31,7 +28,7 @@ public class ValidTestCouple : ITestCouple public string Input() { - return Encoding.UTF8.GetString(ResourceUtility.ReadAllBytes(true, "Xml.Valid.xml")); + return XmlResource.GetContent.GetValid(); } } @@ -49,7 +46,7 @@ public List ExpectedValidationMessages public string Input() { - return Encoding.UTF8.GetString(ResourceUtility.ReadAllBytes(true, "Xml.InvalidIdentifikatorContent.xml")); + return XmlResource.GetContent.GetInvalid(); } } @@ -67,7 +64,7 @@ public List ExpectedValidationMessages public string Input() { - return Encoding.UTF8.GetString(ResourceUtility.ReadAllBytes(true, "Xml.UnknownElement.xml")); + return XmlResource.GetContent.GetContentWithUnknownElement(); } } } diff --git a/Difi.Felles.Utility.Tester/Validation/XmlValidatorTestImplementation.cs b/Difi.Felles.Utility.Tester/Validation/XmlValidatorTestImplementation.cs index b6b9f08..87bdfba 100755 --- a/Difi.Felles.Utility.Tester/Validation/XmlValidatorTestImplementation.cs +++ b/Difi.Felles.Utility.Tester/Validation/XmlValidatorTestImplementation.cs @@ -1,22 +1,13 @@ -using System.IO; -using System.Xml; -using ApiClientShared; +using System.Xml; +using Difi.Felles.Utility.Resources.Xsd; namespace Difi.Felles.Utility.Tester.Validation { public class XmlValidatorTestImplementation : XmlValidator { - private static readonly ResourceUtility ResourceUtility = new ResourceUtility("Difi.Felles.Utility.Tester.Testdata"); - public XmlValidatorTestImplementation() { - AddXsd("http://tempuri.org/po.xsd", HentRessurs("Xsd.Sample.xsd")); - } - - private static XmlReader HentRessurs(string path) - { - var bytes = ResourceUtility.ReadAllBytes(true, path); - return XmlReader.Create(new MemoryStream(bytes)); + AddXsd("http://tempuri.org/po.xsd", XmlReader.Create(XsdResource.Sample())); } } } \ No newline at end of file diff --git a/Difi.Felles.Utility/CertificateChainValidator.cs b/Difi.Felles.Utility/CertificateChainValidator.cs index 7e17038..9c77381 100755 --- a/Difi.Felles.Utility/CertificateChainValidator.cs +++ b/Difi.Felles.Utility/CertificateChainValidator.cs @@ -18,7 +18,7 @@ public CertificateChainValidator(X509Certificate2Collection certificateStore) public X509Certificate2Collection SertifikatLager => CertificateStore; /// - /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot + /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// /// /// @@ -29,7 +29,7 @@ public bool ErGyldigSertifikatkjede(X509Certificate2 certificate) } /// - /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot + /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// /// /// @@ -39,7 +39,7 @@ public bool IsValidChain(X509Certificate2 certificate) } /// - /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot + /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// /// /// Status på kjeden etter validering hvis validering feilet. @@ -51,7 +51,7 @@ public bool ErGyldigSertifikatkjede(X509Certificate2 certificate, out string det } /// - /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot + /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// /// /// Status på kjeden etter validering hvis validering feilet. @@ -64,20 +64,19 @@ public bool IsValidChain(X509Certificate2 certificate, out string detailedErrorI return result.Type == CertificateValidationType.Valid; } - public CertificateValidationResult Validate(X509Certificate2 certificate) { var chain = BuildCertificateChain(certificate); var onlyUsingValidatorCertificatesResult = ValidateThatUsingOnlyValidatorCertificates(chain, certificate); - return onlyUsingValidatorCertificatesResult.Type != CertificateValidationType.Valid - ? onlyUsingValidatorCertificatesResult + return onlyUsingValidatorCertificatesResult.Type != CertificateValidationType.Valid + ? onlyUsingValidatorCertificatesResult : Validate(certificate, chain); } /// - /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot + /// Validerer sertifikatkjeden til sertifikatet. Gjør dette ved å validere mot /// /// /// Status på kjeden etter validering hvis validering feilet. @@ -88,7 +87,7 @@ public bool ErGyldigSertifikatkjede(X509Certificate2 certificate, out X509ChainS var chain = BuildCertificateChain(certificate); detailedErrorInformation = chain.ChainStatus; - var onlyUsingValidatorCertificatesResult = ValidateThatUsingOnlyValidatorCertificates(chain,certificate); + var onlyUsingValidatorCertificatesResult = ValidateThatUsingOnlyValidatorCertificates(chain, certificate); if (onlyUsingValidatorCertificatesResult.Type != CertificateValidationType.Valid) { return false; @@ -112,15 +111,21 @@ private CertificateValidationResult ValidateThatUsingOnlyValidatorCertificates(X foreach (var chainElement in chain.ChainElements) { var isCertificateToValidate = IsSameCertificate(chainElement.Certificate, certificate); - if (isCertificateToValidate) { continue; } + if (isCertificateToValidate) + { + continue; + } var isValidatorCertificate = CertificateStore.Cast().Any(lagerSertifikat => IsSameCertificate(chainElement.Certificate, lagerSertifikat)); - if (isValidatorCertificate) { continue; } + if (isValidatorCertificate) + { + continue; + } var chainAsString = chain.ChainElements .Cast() .Where(c => c.Certificate.Thumbprint != certificate.Thumbprint) - .Aggregate("",(result, curr) => GetCertificateInfo(result, curr.Certificate)); + .Aggregate("", (result, curr) => GetCertificateInfo(result, curr.Certificate)); var validatorCertificatesAsString = CertificateStore .Cast() @@ -134,9 +139,9 @@ private CertificateValidationResult ValidateThatUsingOnlyValidatorCertificates(X private static CertificateValidationResult UsedExternalCertificatesResult(X509Certificate2 certificate, string chainAsString, string validatorCertificatesAsString) { - return new CertificateValidationResult(CertificateValidationType.InvalidChain, + return new CertificateValidationResult(CertificateValidationType.InvalidChain, $"Validering av '{certificate.ToShortString()}' feilet. {Environment.NewLine}" + - $"Dette skjer fordi kjeden ble bygd med følgende sertifikater: {Environment.NewLine}{chainAsString}, " + + $"Dette skjer fordi kjeden ble bygd med følgende sertifikater: {Environment.NewLine}{chainAsString}, " + $"men kun følgende er godkjent for å bygge kjeden: {Environment.NewLine}{validatorCertificatesAsString}. Dette skjer som oftest om sertifikater blir hentet fra Certificate Store på Windows, " + "og det tillates ikke under validering. Det er kun gyldig å bygge en kjede med de sertifikatene sendt inn til validatoren."); } @@ -177,8 +182,8 @@ private static CertificateValidationResult Validate(X509Certificate2 certificate return ValidResult(certificate); case 1: var chainError = detailedErrorInformation.ElementAt(0).Status; - return chainError == X509ChainStatusFlags.UntrustedRoot - ? ValidResult(certificate) + return chainError == X509ChainStatusFlags.UntrustedRoot + ? ValidResult(certificate) : InvalidChainResult(certificate, detailedErrorInformation); //We tolerate this 'UntrustedRoot' because it occurs when loading a root certificate from file, which is always done here. We trust the certificates as they are preloaded in library. default: return InvalidChainResult(certificate, detailedErrorInformation); diff --git a/Difi.Felles.Utility/CertificateValidator.cs b/Difi.Felles.Utility/CertificateValidator.cs index ca9df28..504e246 100755 --- a/Difi.Felles.Utility/CertificateValidator.cs +++ b/Difi.Felles.Utility/CertificateValidator.cs @@ -78,7 +78,7 @@ private static CertificateValidationResult ExpiredResult(X509Certificate2 certif private static CertificateValidationResult ValidResult(X509Certificate2 certificate) { return new CertificateValidationResult( - CertificateValidationType.Valid, + CertificateValidationType.Valid, certificate.ToShortString("er et gyldig sertifikat.")); } diff --git a/Difi.Felles.Utility/Difi.Felles.Utility.csproj b/Difi.Felles.Utility/Difi.Felles.Utility.csproj index 0477c36..7b2c8be 100755 --- a/Difi.Felles.Utility/Difi.Felles.Utility.csproj +++ b/Difi.Felles.Utility/Difi.Felles.Utility.csproj @@ -57,23 +57,13 @@ - +
- - - - - - - - - - ..\packages\api-client-shared.1.0.5968.19413\lib\net45\ApiClientShared.dll @@ -86,6 +76,12 @@ + + + {c737ea02-e687-45c4-95db-72b5083246f2} + Difi.Felles.Utility.Resources + +