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); }
/// <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); }
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; }