コード例 #1
0
        public static SignatureDetails ValidateXMLSignature(string SignedXML)
        {
            if (SignedXML == null)
            {
                throw new ArgumentNullException("SignedXML");
            }

            //Make sure the SAPI Library is loaded
            SAPIInit();
            SignatureDetails SigDetails         = new SignatureDetails();
            SigFieldSettings SigFieldSettings   = new SigFieldSettings();
            SigFieldInfo     SignatureFieldInfo = new SigFieldInfo();
            SAPICrypt        SAPI   = new SAPICrypt();
            SigFieldHandle   hField = null;
            int rc;

            SESHandle hSession = new SESHandle();

            if ((rc = SAPI.HandleAcquire(out hSession)) != 0)
            {
                throw new Exception(string.Format(
                                        "Memory allocation error (#{0})", rc.ToString("X")));
            }

            SAPIContext ctxValidateSignature = new SAPIContext();
            int         num = 0;

            if ((rc = SAPI.SignatureFieldEnumInit(hSession, ctxValidateSignature, SAPI_ENUM_FILE_TYPE.SAPI_ENUM_FILE_XML, SignedXML, 0, ref num)) != 0)
            {
                SAPI.HandleRelease(hSession);
                throw new Exception(string.Format(
                                        "An error occured while initializing the signature validation process (#{0})", rc.ToString("X")));
            }

            if (num < 1)
            {
                throw new Exception("The XML file is not signed!");
            }
            if (num > 1)
            {
                throw new Exception("SAPI only supports a single signature per XML file!");
            }

            if ((rc = SAPI.SignatureFieldEnumCont(hSession, ctxValidateSignature, out hField)) != 0)
            {
                SAPI.ContextRelease(ctxValidateSignature);
                SAPI.HandleRelease(hSession);
                throw new Exception(string.Format(
                                        "Failed to retrieve signature (#{0})", rc.ToString("X")));
            }

            if ((rc = SAPI.SignatureFieldInfoGet(hSession, hField, SigFieldSettings, SignatureFieldInfo)) != 0)
            {
                SAPI.ContextRelease(ctxValidateSignature);
                SAPI.HandleRelease(hSession);
                throw new Exception(string.Format(
                                        "Failed to parse signature details (#{0})", rc.ToString("X")));
            }

            CertStatus not_used = new CertStatus();

            SigDetails.isValid = SAPI.SignatureFieldVerify(hSession, hField, not_used, 0) == 0;

            SigDetails.SignerCertificate = new X509Certificate2(
                (byte[])(((SAPIByteArray)SignatureFieldInfo.Certificate).ToArray()));
            SigDetails.SignerName = SignatureFieldInfo.SignerName;

            //Convert FILE_TIME to ticks
            ulong filetime = SignatureFieldInfo.SignatureTime.HighDateTime;

            filetime <<= 32;
            filetime  += SignatureFieldInfo.SignatureTime.LowDateTime;
            SigDetails.SignatureTimeTicks = DateTime.FromFileTimeUtc((long)filetime).Ticks;

            //Cleanup memory
            SAPI.ContextRelease(ctxValidateSignature);
            SAPI.HandleRelease(hSession);

            return(SigDetails);
        }