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 SigFieldSettingsClass();
            SigFieldInfo     SignatureFieldInfo = new SigFieldInfoClass();
            SAPICrypt        SAPI   = new SAPICryptClass();
            SigFieldHandle   hField = null;
            int rc;

            SESHandle hSession = new SESHandleClass();

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

            SAPIContext ctxValidateSignature = new SAPIContextClass();
            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);
        }
Example #2
0
        /// <summary>
        /// A Lambda function that adds an order by customer.
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task <APIGatewayProxyResponse> AddOrderAsync(APIGatewayProxyRequest request, ILambdaContext context)
        {
            const string url = "https://maoproduce-stack-customer-signatures.s3-ap-southeast-2.amazonaws.com/";

            //instantiate new order object
            Orders newOrder   = new Orders();
            string customerId = null;
            string lastOrderId;

            //check for customerId parameter from url
            if (request.PathParameters != null && request.PathParameters.ContainsKey(ID_QUERY_STRING_NAME))
            {
                customerId = request.PathParameters[ID_QUERY_STRING_NAME];
            }
            else if (request.QueryStringParameters != null && request.QueryStringParameters.ContainsKey(ID_QUERY_STRING_NAME))
            {
                customerId = request.QueryStringParameters[ID_QUERY_STRING_NAME];
            }

            //GET the last order number
            var search = this.DDBContext.ScanAsync <CustomerOrders>(null);
            var page   = await search.GetNextSetAsync();

            List <int> list = new List <int>();


            if (!page.Any())
            {
                lastOrderId = "17050";
            }
            else
            {
                foreach (var customer in page)
                {
                    list.Add(int.Parse(customer.LastOrderId));
                }

                lastOrderId = (list.Max() + 1).ToString();
            }

            //get the request body
            var requestOrder = JsonConvert.DeserializeObject <Order_AllOrders>(request?.Body);

            //Convert sent All Orders to Orders Model
            newOrder.Id       = lastOrderId;
            newOrder.DateTime = DateTime.Now;
            newOrder.IsOpen   = requestOrder.IsOpen;

            //pass signature data to AWSS3BucketSave Function
            string          signatureTitle = newOrder.Id + "-" + String.Format("{0}.png", DateTime.Now.ToString("ddMMyyyyhhmmsstt"));
            AWSS3BucketSave bucket         = new AWSS3BucketSave();
            await bucket.WritingAnObjectAsync(requestOrder.Signature.Signature, signatureTitle);

            //New instance of signatture with url
            SignatureDetails sig = new SignatureDetails();
            var sigExist         = requestOrder.Signature;

            if (string.IsNullOrEmpty(sigExist.Signature))
            {
                sig.Signature = "";
                sig.Signee    = requestOrder.Signature.Signee;
            }
            else
            {
                sig.Signature = url + signatureTitle;
                sig.Signee    = requestOrder.Signature.Signee;
            }

            //Save new signature object
            newOrder.Signature  = sig;
            newOrder.TotalPrice = requestOrder.TotalPrice;
            newOrder.Products   = requestOrder.Products;

            ////load current customer data in dynamodb order table
            var custNewOrder = await DDBContext.LoadAsync <CustomerOrders>(customerId);

            if (custNewOrder != null)
            {
                custNewOrder.LastOrderId = lastOrderId;
                custNewOrder.Orders.Add(newOrder);

                //Save the order in the right customer.
                var saveOrder = DDBContext.SaveAsync <CustomerOrders>(custNewOrder);
            }
            else
            {
                CustomerOrders newCustOrder = new CustomerOrders();
                newCustOrder.CustomerId  = customerId;
                newCustOrder.LastOrderId = lastOrderId;
                newCustOrder.addList(newOrder);

                //Save to Dynamodb
                var saveOrder = DDBContext.SaveAsync <CustomerOrders>(newCustOrder);
            }

            //create success response
            var response = new APIGatewayProxyResponse
            {
                StatusCode = (int)HttpStatusCode.OK,
                Body       = JsonConvert.SerializeObject(new Dictionary <string, string> {
                    { "message", "Order sucessfully created" }, { "orderId", lastOrderId }
                }),
                Headers = new Dictionary <string, string> {
                    { "Content-Type", "application/json; charset=utf-8" }
                }
            };

            return(response);
        }
Example #3
0
        public static SignatureDetails ValidateSignature(Stream SignedData, Stream Signature)
        {
            if (SignedData == null)
            {
                throw new ArgumentNullException("SignedData");
            }
            if (Signature == null)
            {
                throw new ArgumentNullException("Signature");
            }

            //Make sure the SAPI Library is loaded
            SAPIInit();

            SignatureDetails SigDetails = new SignatureDetails();
            int rc;

            SAPICrypt SAPI = new SAPICryptClass();

            SESHandle hSession = new SESHandleClass();

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



            //Extract Signer Data from the Signature stream



            //Read Signature content from stream to the SAPI bytes array
            Array baSignature = new byte[(int)Signature.Length];

            Signature.Read((byte[])baSignature, 0, (int)Signature.Length);
            SAPIByteArray sSignature = new SAPIByteArrayClass();

            sSignature.FromArray(ref baSignature);

            //SAPIByteArray sSignedData = new SAPIByteArrayClass();
            //Array t1 = (Array)SignedData; sSignedData.FromArray(ref t1);


            object Certificate;
            // Extract the signer's certificate from signature
            SAPI_ENUM_DATA_TYPE SAPIType = SAPI_ENUM_DATA_TYPE.SAPI_ENUM_DATA_TYPE_NONE;

            if ((rc = SAPI.PKCS7BlobGetValue(hSession, sSignature, SAPI_ENUM_PKCS7_FIELD.SAPI_ENUM_PKCS7_FIELD_CERT, out Certificate, ref SAPIType)) != 0)
            {
                SAPI.HandleRelease(hSession);
                throw new Exception(string.Format(
                                        "An error occured while extracting the signer's certificate from the signature stream (#{0})", rc.ToString("X")));
            }

            SigDetails.SignerCertificate = new X509Certificate2((byte[])(((SAPIByteArray)Certificate).ToArray()));
            SigDetails.SignerName        = SigDetails.SignerCertificate.GetNameInfo(X509NameType.SimpleName, false);
            SigDetails.SignerEmail       = SigDetails.SignerCertificate.GetNameInfo(X509NameType.EmailName, false);


            //Run the signature validation process
            SAPIContext ctxValidateSignature = new SAPIContextClass();

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


            int remaining    = (int)SignedData.Length;
            int chunkMaxSize = 1 << 20; //1MB

            //Calculate first chunk size
            int chunkSize = remaining < chunkMaxSize ?
                            remaining : chunkMaxSize;

            while (remaining > 0)
            {
                Array chunk = new byte[chunkSize]; //Read in chunks of 1MB
                int   read  = SignedData.Read((byte[])chunk, 0, chunkSize);
                if (read <= 0)
                {
                    throw new EndOfStreamException(String.Format("End of stream reached with {0} bytes left to read", remaining));
                }

                //Build SAPI-Compatible byte array
                SAPIByteArray tmpBuff = new SAPIByteArrayClass();
                tmpBuff.FromArray(ref chunk);

                //Add read buffer to the validation calculation
                if ((rc = SAPI.BufferVerifySignatureCont(hSession, ctxValidateSignature, tmpBuff)) != 0)
                {
                    SAPI.ContextRelease(ctxValidateSignature);
                    SAPI.HandleRelease(hSession);

                    throw new Exception(string.Format(
                                            "An error occured while validating the digital signature (#{0})", rc.ToString("X")));
                }

                remaining -= read;
                chunkSize  = Math.Min(remaining, chunkSize);
            }


            //Get the final validation result
            SAPIFileTime signingTime = new SAPIFileTimeClass();

            rc = SAPI.BufferVerifySignatureEnd(hSession, ctxValidateSignature, signingTime, new CertStatusClass());
            if ((uint)rc == 0x90030360)  //SAPI_SIGNATURE_NOT_VALID
            {
                SigDetails.isValid            = false;
                SigDetails.SignatureTimeTicks = 0;
            }
            else if (rc == 0)
            {
                SigDetails.isValid = true;

                //Convert FILE_TIME to ticks
                ulong filetime = signingTime.HighDateTime;
                filetime <<= 32;
                filetime  += signingTime.LowDateTime;
                SigDetails.SignatureTimeTicks = DateTime.FromFileTimeUtc((long)filetime).Ticks;
            }
            else
            {
                SAPI.ContextRelease(ctxValidateSignature);
                SAPI.HandleRelease(hSession);

                throw new Exception(string.Format(
                                        "Failed to validate Digital Signature (#{0})", rc.ToString("X")));
            }


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

            return(SigDetails);
        }
        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 SigFieldSettingsClass();
            SigFieldInfo SignatureFieldInfo = new SigFieldInfoClass();
            SAPICrypt SAPI = new SAPICryptClass();
            SigFieldHandle hField = null;
            int rc;

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

            SAPIContext ctxValidateSignature = new SAPIContextClass();
            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;
        }
        public static SignatureDetails ValidateSignature(Stream SignedData, Stream Signature)
        {
            if (SignedData == null) throw new ArgumentNullException("SignedData");
            if (Signature == null) throw new ArgumentNullException ("Signature");

            //Make sure the SAPI Library is loaded
            SAPIInit();

            SignatureDetails SigDetails = new SignatureDetails();
            int rc;

            SAPICrypt SAPI = new SAPICryptClass();

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

            //Extract Signer Data from the Signature stream

            //Read Signature content from stream to the SAPI bytes array
            Array baSignature = new byte[(int)Signature.Length];
            Signature.Read((byte[])baSignature, 0, (int)Signature.Length);
            SAPIByteArray sSignature = new SAPIByteArrayClass();
            sSignature.FromArray(ref baSignature);

            //SAPIByteArray sSignedData = new SAPIByteArrayClass();
            //Array t1 = (Array)SignedData; sSignedData.FromArray(ref t1);

            object Certificate;
            // Extract the signer's certificate from signature
            SAPI_ENUM_DATA_TYPE SAPIType = SAPI_ENUM_DATA_TYPE.SAPI_ENUM_DATA_TYPE_NONE;
            if ((rc = SAPI.PKCS7BlobGetValue(hSession, sSignature, SAPI_ENUM_PKCS7_FIELD.SAPI_ENUM_PKCS7_FIELD_CERT, out Certificate, ref SAPIType)) != 0)
            {
                SAPI.HandleRelease(hSession);
                throw new Exception(string.Format(
                    "An error occured while extracting the signer's certificate from the signature stream (#{0})", rc.ToString("X")));
            }

            SigDetails.SignerCertificate = new X509Certificate2((byte[])(((SAPIByteArray)Certificate).ToArray()));
            SigDetails.SignerName = SigDetails.SignerCertificate.GetNameInfo (X509NameType.SimpleName, false);
            SigDetails.SignerEmail = SigDetails.SignerCertificate.GetNameInfo (X509NameType.EmailName, false);

            //Run the signature validation process
            SAPIContext ctxValidateSignature = new SAPIContextClass();

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

            int remaining = (int) SignedData.Length;
            int chunkMaxSize = 1 << 20; //1MB

            //Calculate first chunk size
            int chunkSize = remaining < chunkMaxSize ?
                remaining : chunkMaxSize;

            while (remaining > 0)
            {
                Array chunk = new byte[chunkSize]; //Read in chunks of 1MB
                int read = SignedData.Read((byte[])chunk, 0, chunkSize);
                if (read <= 0) throw new EndOfStreamException (String.Format("End of stream reached with {0} bytes left to read", remaining));

                //Build SAPI-Compatible byte array
                SAPIByteArray tmpBuff = new SAPIByteArrayClass();
                tmpBuff.FromArray(ref chunk);

                //Add read buffer to the validation calculation
                if ((rc = SAPI.BufferVerifySignatureCont(hSession, ctxValidateSignature, tmpBuff)) != 0)
                {
                    SAPI.ContextRelease(ctxValidateSignature);
                    SAPI.HandleRelease(hSession);

                    throw new Exception(string.Format(
                        "An error occured while validating the digital signature (#{0})", rc.ToString("X")));
                }

                remaining -= read;
                chunkSize = Math.Min(remaining, chunkSize);
            }

            //Get the final validation result
            SAPIFileTime signingTime = new SAPIFileTimeClass();

            rc = SAPI.BufferVerifySignatureEnd(hSession, ctxValidateSignature, signingTime, new CertStatusClass());
            if ((uint)rc == 0x90030360)  //SAPI_SIGNATURE_NOT_VALID
            {
                SigDetails.isValid = false;
                SigDetails.SignatureTimeTicks = 0;
            }
            else if (rc == 0)
            {
                SigDetails.isValid  = true;

                //Convert FILE_TIME to ticks
                ulong filetime = signingTime.HighDateTime;
                filetime <<= 32;
                filetime += signingTime.LowDateTime;
                SigDetails.SignatureTimeTicks = DateTime.FromFileTimeUtc((long)filetime).Ticks;
            }
            else
            {
                SAPI.ContextRelease(ctxValidateSignature);
                SAPI.HandleRelease(hSession);

                throw new Exception(string.Format(
                    "Failed to validate Digital Signature (#{0})", rc.ToString("X")));
            }

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

            return SigDetails;
        }