public ApiActivity getActivityByUniqueKey(string key) { ApiActivity ac = null; ac = _db.ApiActivity.FirstOrDefault(item => item.UniqueKey == key); return(ac); }
private bool signFile(ApiActivity ac) { // ---- SIGN FILE // prepare run ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = Directory.GetCurrentDirectory() + @"\lib\signtool.exe"; psi.RedirectStandardError = true; psi.RedirectStandardOutput = true; psi.UseShellExecute = false; if (ac.EncCertPw != null && ac.EncCertPw.Length > 0) { // Read secrets --> decrpyt certPW JObject secretsConfig = JObject.Parse(System.IO.File.ReadAllText(@"secrets.json")); //secrets.json file not checked in. .gitignore var aesKey = (string)secretsConfig["aesKey"]; var certPw = EncryptProvider.AESDecrypt(ac.EncCertPw, aesKey); psi.Arguments = $"sign /debug /v /fd sha256 /f \"{ac.SystemCertFilename}\" /p {certPw} \"{ac.SystemOfficeFilename}\""; } else { psi.Arguments = $"sign /debug /v /fd sha256 /f \"{ac.SystemCertFilename}\" \"{ac.SystemOfficeFilename}\""; } _l.Debug($"Executing {psi.FileName} {psi.Arguments}..."); // execute run StringBuilder stdOut = new StringBuilder(); StringBuilder stdErr = new StringBuilder(); Process p = new Process(); p.StartInfo = psi; p.Start(); while (!p.StandardOutput.EndOfStream) { stdOut.AppendLine(p.StandardOutput.ReadLine()); } while (!p.StandardError.EndOfStream) { stdErr.AppendLine(p.StandardError.ReadLine()); } p.WaitForExit(); _l.Debug("Process exited. Parsing..."); // parse result, prepare return json ac = SignToolOutputParser.parseSignToolOutput(SignToolOutputParser.SignToolOperation.Sign, ac, stdOut.ToString(), stdErr.ToString()); if (ac.Status == ApiActivity.ApiStatus.Ready) { return(true); } else { return(false); } }
public async Task Transform_ALL() { var basePath = Path.Combine(Path.GetTempPath(), _context.DynamicContext.Manifest.Id); CommonActivity commonActivity = new CommonActivity("CommonActivity", basePath); await commonActivity.Initializing(_context); await commonActivity.Writing(); Assert.NotNull(commonActivity); ApiActivity apiActivity = new ApiActivity("ApiActivity", basePath); await apiActivity.Initializing(_context); await apiActivity.Writing(); Assert.NotNull(apiActivity); LayoutActivity layoutActivity = new LayoutActivity("LayoutActivity", basePath); await layoutActivity.Initializing(_context); await layoutActivity.Writing(); Assert.NotNull(layoutActivity); DataModelActivity dataModelActivity = new DataModelActivity("DataModelActivity", basePath); await dataModelActivity.Initializing(_context); await dataModelActivity.Writing(); Assert.NotNull(dataModelActivity); ViewModelActivity viewModelActivity = new ViewModelActivity("ViewModelActivity", basePath); await viewModelActivity.Initializing(_context); await viewModelActivity.Writing(); Assert.NotNull(viewModelActivity); LanguageActivity languageActivity = new LanguageActivity("LanguageActivity", basePath); await languageActivity.Initializing(_context); await languageActivity.Writing(); Assert.NotNull(languageActivity); UnitTestsActivity unitTestsActivity = new UnitTestsActivity("UnitTestsActivity", basePath); await unitTestsActivity.Initializing(_context); await unitTestsActivity.Writing(); Assert.NotNull(unitTestsActivity); }
public IHttpActionResult MyActivity(string token, byte limit = 10) { if (auth.IsNotValid(token)) { return(base.StatusCode(HttpStatusCode.Unauthorized)); } var results = this.activityCore.UserSearch(auth.Device.UserIdentifier, limit); if (null != results && 0 < results.Count()) { var activities = results.Select(r => ApiActivity.Map(r)); return(this.Ok <IEnumerable <ApiActivity> >(activities)); } else { return(this.BadRequest("found nothing")); } }
public static string generateUrl(UrlType urltype, ApiActivity ac, IHttpContextAccessor httpctx) { var scheme = httpctx.HttpContext.Request.Scheme; var host = httpctx.HttpContext.Request.Host; //var apiPath = httpctx.HttpContext.Request.Path.Value.Substring(0, httpctx.HttpContext.Request.Path.Value.LastIndexOf("/")); var apiPath = "/api/Signer"; if (urltype == UrlType.DownloadUrl) { var downloadApiPath = $"{apiPath}/DownloadFile"; return($"{scheme}://{host}{downloadApiPath}/{ac.UniqueKey}"); } if (urltype == UrlType.StatusUrl) { var statusApiPath = $"{apiPath}/Status"; return($"{scheme}://{host}{statusApiPath}/{ac.UniqueKey}"); } return("URL could not be generated"); }
public IActionResult Status(string key) { ApiActivity ac = new ApiActivity(); // new entry -> Status requested ac.Operation = ApiActivity.ApiOperation.Status; ac.Status = ApiActivity.ApiStatus.Ready; ac.Message = $"Status requested for key {key}, unique Key for this status request {ac.UniqueKey}"; _asvc.addUpdateApiActivity(ac); _l.Debug(ac.Message); //check if malicious content, GUID == 36 characters if (key.Length != 36) { ac.Message = $"key provided is not a valid key!"; ac.Status = ApiActivity.ApiStatus.Error; _asvc.addUpdateApiActivity(ac); _l.Error(ac.Message); return(Content(ac.getWebresult())); } //check if ID exixts / activity present // get DB entry for updating ApiActivity requestedStatus = _asvc.getActivityByUniqueKey(key); if (requestedStatus == null) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"Key {key} is invalid!"; _asvc.addUpdateApiActivity(ac); _l.Error(ac.Message); return(Content(ac.getWebresult())); } else { ac.Message = $"file found: returning status for key {key}"; ac.Status = ApiActivity.ApiStatus.Ready; _asvc.addUpdateApiActivity(ac); return(Content(requestedStatus.getWebresult())); } }
/// <summary> /// Adds ApiActivity Object to DB or updates existing object. /// </summary> /// <param name="ac">ApiActivity to add or update</param> public void addUpdateApiActivity(ApiActivity ac) { var entity = _db.ApiActivity.FirstOrDefault(item => item.Key == ac.Key); // entity already exists -> update if (entity != null) { _db.Entry(entity).CurrentValues.SetValues(ac); // update last updated entity.TsLastUpdate = DateTime.Now; _db.ApiActivity.Update(entity); _db.SaveChanges(); _l.Debug($"Updated in DB: {ac.ToString()}"); } else { // create new _db.ApiActivity.Add(ac); _db.SaveChanges(); _l.Debug($"Added to DB: {ac.ToString()}"); } }
public static ApiActivity parseSignToolOutput(SignToolOperation op, ApiActivity ac, string stdOut, string stdErr) { if (stdOut != null && stdOut.Length > 0) { //try to parse everything possible string patIssuedTo = @"Issued to: (.*?)$"; Match m2 = Regex.Match(stdOut, patIssuedTo, RegexOptions.Multiline); ac.CertIssuedTo = m2.Groups[1].Value.Trim(); string patIssuedBy = @"Issued by: (.*?)$"; Match m3 = Regex.Match(stdOut, patIssuedBy, RegexOptions.Multiline); ac.CertIssuedBy = m3.Groups[1].Value.Trim(); string patExpire = @"Expires: (.*?)$"; Match m4 = Regex.Match(stdOut, patExpire, RegexOptions.Multiline); ac.CertExpire = m4.Groups[1].Value.Trim(); string patCertHash = @"\s+.*?[H|h]ash: (\w+)"; Match mCertHash = Regex.Match(stdOut, patCertHash, RegexOptions.Multiline); ac.CertHash = mCertHash.Groups[1].Value.Trim(); string patFileHash = @"[H|h]ash of file.*?: (\w+)"; Match mFileHash = Regex.Match(stdOut, patFileHash, RegexOptions.Multiline); ac.FileHash = mFileHash.Groups[1].Value.Trim(); // if file hash was not parsed from output of signtool.exe, create our own hash if (ac.FileHash == "") { using (FileStream fs = System.IO.File.OpenRead(ac.SystemOfficeFilename)) { var sha = new SHA256Managed(); byte[] checksum = sha.ComputeHash(fs); ac.FileHash = BitConverter.ToString(checksum).Replace("-", String.Empty); } } //decide if error or success // note: error is raised if trust chain cannot be verified. This is a normal behavior, due the fact // that certificates were not installed in windows cert. store, but only uploaded for checking once. // So if cert data can be parsed from file this is success, although stderr is populated! if (op == SignToolOperation.Verify) { string patSigIdx = @"Signature Index: \d.*$"; Match m5 = Regex.Match(stdOut, patSigIdx, RegexOptions.Multiline); if (m5.Success) // signature could be read from file successfully! { ac.Status = ApiActivity.ApiStatus.Ready; ac.Message = ac.Message = $"File {ac.UserOfficeFilename} verified successfully."; return(ac); } } if (op == SignToolOperation.Sign) { string patSuccSigned = @"Successfully signed:.*$"; Match m6 = Regex.Match(stdOut, patSuccSigned, RegexOptions.Multiline); if (m6.Success) { ac.Status = ApiActivity.ApiStatus.Ready; ac.Message = $"File {ac.UserOfficeFilename} signed successfully."; return(ac); } } // if filehash was not on stdout, calculate seperately } if (stdErr != null && stdErr.Length > 0) { // If file was analysed for signatures, but none found -> also success string patSigNotFound = @"SignTool Error: No signature found"; Match mSigNotFound = Regex.Match(stdErr, patSigNotFound, RegexOptions.Multiline); if (mSigNotFound.Success) // signature could be read from file successfully! { ac.Status = ApiActivity.ApiStatus.Ready; ac.Message = ac.Message = $"File verified successfully: No signature found"; return(ac); } // all other errors ac.Status = ApiActivity.ApiStatus.Error; ac.Message = stdErr.Trim(); } return(ac); }
public IActionResult DownloadFile(string key) { ApiActivity ac = new ApiActivity(); ac.Operation = ApiActivity.ApiOperation.Download; ac.Status = ApiActivity.ApiStatus.Ready; ac.Message = $"Download of file {key} requested. Checking for file..."; _asvc.addUpdateApiActivity(ac); //check if malicious content, GUID == 36 characters if (key.Length != 36) { ac.Message = $"key provided is not a valid key!"; ac.Status = ApiActivity.ApiStatus.Error; _asvc.addUpdateApiActivity(ac); _l.Error(ac.Message); return(Content(ac.getWebresult())); } //check if file ID exixts / file present try { var activity = _asvc.getActivityByUniqueKey(key); var systemFileName = activity.SystemOfficeFilename; //if file not ready (still queued or signing) no download! if (activity.Status != ApiActivity.ApiStatus.Ready) { ac.Message = $"File Status of {key} is {activity.Status}. not ready for download yet!"; ac.Status = ApiActivity.ApiStatus.Error; _asvc.addUpdateApiActivity(ac); _l.Error(ac.Message); return(Content(ac.getWebresult())); } //check if file exists var storagePath = GHelper.getOfficeFilesSystemDir(_webHostEnv, _conf); var fullSystemFileName = Path.Combine(storagePath, systemFileName); if (System.IO.File.Exists(fullSystemFileName)) { _l.Debug($"System file {fullSystemFileName} found. Starting sending file..."); // send file for download var content = new FileStream(fullSystemFileName, FileMode.Open); var contentType = "APPLICATION/octet-stream"; // inject _signed.* in filename var fileNameSigned = Path.GetFileNameWithoutExtension(activity.UserOfficeFilename) + "_signed" + Path.GetExtension(activity.UserOfficeFilename); _l.Debug($"file {fullSystemFileName} found. Sending as {fileNameSigned}"); ac.Status = ApiActivity.ApiStatus.Ready; ac.Message = $"File {fileNameSigned} sent for download successfully!"; _asvc.addUpdateApiActivity(ac); return(File(content, contentType, fileNameSigned)); } else { //requested file in DB, but not found in filesystem ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"File for key {key} not found!"; _asvc.addUpdateApiActivity(ac); _l.Error(ac.Message); return(Content(ac.getWebresult())); } } catch (Exception) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"FileKey {key} is invalid!"; _asvc.addUpdateApiActivity(ac); _l.Error(ac.Message); return(Content(ac.getWebresult())); } }
public IActionResult CheckOfficeFile(IFormFile officeFile) { ApiActivity ac = new ApiActivity(); ac.ClientIPAddress = Request.HttpContext.Connection.RemoteIpAddress.ToString(); ac.Operation = ApiActivity.ApiOperation.Verify; ac.Message = $"Check Office File started"; ac.Status = ApiActivity.ApiStatus.Verifying; ac.StatusUrl = GHelper.generateUrl(GHelper.UrlType.StatusUrl, ac, _httpctx); ac.DownloadUrl = GHelper.generateUrl(GHelper.UrlType.DownloadUrl, ac, _httpctx); _asvc.addUpdateApiActivity(ac); if (officeFile != null) { ac.UserOfficeFilename = officeFile.FileName; //check valid file extension _l.Debug("Checking for valid file extensions..."); string officeFileExt = Path.GetExtension(officeFile.FileName.ToLowerInvariant()); if (!GHelper.fileHasAllowedExtension(GHelper.ExtensionType.OfficeFile, officeFileExt)) { ac.Message = $"Office File extension {officeFileExt} not valid!"; ac.Status = ApiActivity.ApiStatus.Error; _asvc.addUpdateApiActivity(ac); _l.Error(ac.Message); return(Content(ac.getWebresult())); } // check magic number file types _l.Debug("Checking for magic number of file..."); if (!(GHelper.fileHasValidFormat(GHelper.ExtensionType.OfficeFile, officeFile.OpenReadStream()))) { ac.Message = $"Office File {officeFile.FileName} not a valid office file!"; ac.Status = ApiActivity.ApiStatus.Error; _asvc.addUpdateApiActivity(ac); _l.Error(ac.Message); return(Content(ac.getWebresult())); } //save office file string uniFilenameOfficeFile = GHelper.createUniqueFileName(officeFile.FileName); string systemFolderOfficeFile = GHelper.getOfficeFilesSystemDir(_webHostEnv, _conf); string systemFileNameOfficeFile = Path.Combine(systemFolderOfficeFile, uniFilenameOfficeFile); ac.SystemOfficeFilename = systemFileNameOfficeFile; // create dir if not exist System.IO.Directory.CreateDirectory(systemFolderOfficeFile); _l.Debug($"Saving file to {systemFileNameOfficeFile}"); using (var fileStream = new FileStream(systemFileNameOfficeFile, FileMode.Create)) { officeFile.CopyTo(fileStream); } //verify file // prepare run ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = _webHostEnv.ContentRootPath + @"\lib\signtool.exe"; psi.RedirectStandardError = true; psi.RedirectStandardOutput = true; psi.UseShellExecute = false; //use quoted filename otherwise systempath is revealed in error message!! psi.Arguments = $"verify /pa /debug /v \"{systemFileNameOfficeFile}\""; _l.Debug($"Executing {psi.FileName} {psi.Arguments}..."); // execute run StringBuilder stdOut = new StringBuilder(); StringBuilder stdErr = new StringBuilder(); Process p = new Process(); p.StartInfo = psi; p.Start(); while (!p.StandardOutput.EndOfStream) { stdOut.AppendLine(p.StandardOutput.ReadLine()); } while (!p.StandardError.EndOfStream) { stdErr.AppendLine(p.StandardError.ReadLine()); } p.WaitForExit(); _l.Debug("Process exited. Parsing..."); // parse result ac = SignToolOutputParser.parseSignToolOutput(SignToolOutputParser.SignToolOperation.Verify, ac, stdOut.ToString(), stdErr.ToString()); _l.Debug($"Parsed result = {ac.ToString()}"); _l.Debug($"Deleting file {systemFileNameOfficeFile}"); // delete after verify System.IO.File.Delete(Path.Combine(systemFileNameOfficeFile)); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } else { var message = ("No Files submitted for Verifying!"); _l.Warning(message); ac.Operation = ApiActivity.ApiOperation.Verify; ac.Status = ApiActivity.ApiStatus.Error; ac.Message = message; return(Content(ac.getWebresult())); } }
public IActionResult RequestSigning(IFormFile officeFile, [FromForm] bool analyse, string profileName) { //prepare ac (used for logging / error return as well) ApiActivity ac = new ApiActivity(); ac.Operation = ApiActivity.ApiOperation.RequestSigning; ac.ClientIPAddress = HttpContext.Connection.RemoteIpAddress.ToString(); ac.StatusUrl = GHelper.generateUrl(GHelper.UrlType.StatusUrl, ac, _httpctx); ac.DownloadUrl = GHelper.generateUrl(GHelper.UrlType.DownloadUrl, ac, _httpctx); if (officeFile == null) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = "Office File not submitted. Required for signing!"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } ac.UserOfficeFilename = officeFile.FileName; ac.Message = $"Starting request Signing with {officeFile.FileName} and profile ID {profileName}..."; //--- check if valid profile name was provided //check if secrets file present string secretFilename = "secrets.json"; if (!System.IO.File.Exists(secretFilename)) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = "secrets file not found for reading profiles"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } //read secrets config JObject jsonConfig = JObject.Parse(System.IO.File.ReadAllText(secretFilename)); var profileCertFile = (string)jsonConfig["SigningProfiles"][profileName]["CertFile"]; var profileCertPw = (string)jsonConfig["SigningProfiles"][profileName]["CertPw"]; if (profileCertFile == null || profileCertPw == null) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"No certfile or certPW found for Profilename {profileName}"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } ac.UserCertFilename = profileCertFile; //check if cert file from settings is really on filesystem var systemCertFileName = Path.Combine(GHelper.getCertFilesSystemDir(_webHostEnv, _conf), ac.UserCertFilename); if (!System.IO.File.Exists(systemCertFileName)) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"certfile {ac.SystemCertFilename} not found for Profilename {profileName}"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } ac.SystemCertFilename = systemCertFileName; // Save certPW encyrpted in AC, to be decrypted by signer service later. // todo: better PW handling -> was already in cleartext in secrets file _l.Debug($"Provided cert PW = \"{profileCertPw}\""); // Read secrets JObject secretsConfig = JObject.Parse(System.IO.File.ReadAllText(@"secrets.json")); //secrets.json file not checked in. .gitignore var aesKey = (string)secretsConfig["aesKey"]; var encryptedCertPw = EncryptProvider.AESEncrypt(profileCertPw, aesKey); // save pw encrypted in DB ac.EncCertPw = encryptedCertPw; //------- CHECKS //check for valid file extension string officeFileExt = Path.GetExtension(officeFile.FileName.ToLowerInvariant()); if (!GHelper.fileHasAllowedExtension(GHelper.ExtensionType.OfficeFile, officeFileExt)) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"Office File extension {officeFileExt} not valid!"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } // check magic number file types if (!(GHelper.fileHasValidFormat(GHelper.ExtensionType.OfficeFile, officeFile.OpenReadStream()))) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"Office File {officeFile.FileName} not a valid office file!"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } // SAVE FILES //save office file with unique filename, not enumerable string uniFilenameOfficeFile = GHelper.createUniqueFileName(officeFile.FileName); string systemFolderOfficeFile = GHelper.getOfficeFilesSystemDir(_webHostEnv, _conf); string systemFileNameOfficeFile = Path.Combine(systemFolderOfficeFile, uniFilenameOfficeFile); // create dir if not exist System.IO.Directory.CreateDirectory(systemFolderOfficeFile); _l.Debug($"Saving Office file to {systemFolderOfficeFile}"); using (var fileStream = new FileStream(systemFileNameOfficeFile, FileMode.Create)) { officeFile.CopyTo(fileStream); } ac.SystemOfficeFilename = systemFileNameOfficeFile; if (analyse) { // Queue for ANALYSING ac.Status = ApiActivity.ApiStatus.QueuedAnalysis; ac.Message = "File queued for analysis"; _asvc.addUpdateApiActivity(ac); _l.Debug("Analysis requested, queuing for analysis..."); } else { // Queue for SIGNING ac.Status = ApiActivity.ApiStatus.QueuedSigning; ac.Message = "File queued for signing"; _asvc.addUpdateApiActivity(ac); _l.Debug("NO analysis requested, queuing for signing at once..."); } // RETURN STATUS _l.Debug($"Returning Queued API Status for Key {ac.UniqueKey}"); return(Content(ac.getWebresult())); }
public IActionResult RequestSigning(IFormFile officeFile, IFormFile certFile, [FromForm] string certPw, [FromForm] bool analyse) { //prepare ac (used for logging / error return as well) ApiActivity ac = new ApiActivity(); ac.Operation = ApiActivity.ApiOperation.RequestSigning; ac.ClientIPAddress = HttpContext.Connection.RemoteIpAddress.ToString(); ac.StatusUrl = GHelper.generateUrl(GHelper.UrlType.StatusUrl, ac, _httpctx); ac.DownloadUrl = GHelper.generateUrl(GHelper.UrlType.DownloadUrl, ac, _httpctx); if (officeFile != null && certFile != null) { ac.UserOfficeFilename = officeFile.FileName; ac.UserCertFilename = certFile.FileName; ac.Message = $"Starting request Signing with {officeFile.FileName} and cert file {certFile.FileName}..."; _asvc.addUpdateApiActivity(ac); if (certPw != null) { _l.Debug($"Provided cert PW = \"{certPw}\""); // Read secrets JObject secretsConfig = JObject.Parse(System.IO.File.ReadAllText(@"secrets.json")); //secrets.json file not checked in. .gitignore var aesKey = (string)secretsConfig["aesKey"]; var encryptedCertPw = EncryptProvider.AESEncrypt(certPw, aesKey); // save pw encrypted in DB ac.EncCertPw = encryptedCertPw; } else { _l.Debug($"No cert PW provided!"); } //------- CHECKS //check for valid file extension string officeFileExt = Path.GetExtension(officeFile.FileName.ToLowerInvariant()); if (!GHelper.fileHasAllowedExtension(GHelper.ExtensionType.OfficeFile, officeFileExt)) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"Office File extension {officeFileExt} not valid!"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } string certFileExt = Path.GetExtension(certFile.FileName.ToLowerInvariant()); if (!GHelper.fileHasAllowedExtension(GHelper.ExtensionType.CertFile, certFileExt)) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"Certificate File extension {certFileExt} not valid!"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } // check magic number file types if (!(GHelper.fileHasValidFormat(GHelper.ExtensionType.OfficeFile, officeFile.OpenReadStream()))) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"Office File {officeFile.FileName} not a valid office file!"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } if (!(GHelper.fileHasValidFormat(GHelper.ExtensionType.CertFile, certFile.OpenReadStream()))) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"Cert File {certFile.FileName} not a valid cert file!"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } // check PW field int maxPwLength = Int32.Parse(_conf.GetSection("Security")["MaxCertPwLength"]); if (certPw != null && certPw.Length > maxPwLength) { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = $"Cert Pw exceeding max Length: {maxPwLength}!"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } // SAVE FILES //save office file with unique filename, not enumerable string uniFilenameOfficeFile = GHelper.createUniqueFileName(officeFile.FileName); string systemFolderOfficeFile = GHelper.getOfficeFilesSystemDir(_webHostEnv, _conf); string systemFileNameOfficeFile = Path.Combine(systemFolderOfficeFile, uniFilenameOfficeFile); ac.SystemOfficeFilename = systemFileNameOfficeFile; // create dir if not exist System.IO.Directory.CreateDirectory(systemFolderOfficeFile); _l.Debug($"Saving Office file to {systemFolderOfficeFile}"); using (var fileStream = new FileStream(systemFileNameOfficeFile, FileMode.Create)) { officeFile.CopyTo(fileStream); } //save cert file with unique filename, not enumerable string uniFilenameCertFile = GHelper.createUniqueFileName(certFile.FileName); string systemFolderCertFile = GHelper.getCertFilesSystemDir(_webHostEnv, _conf); string systemFileNameCertFile = Path.Combine(systemFolderCertFile, uniFilenameCertFile); systemFileNameCertFile = systemFileNameCertFile.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar); ac.SystemCertFilename = systemFileNameCertFile; // create dir if not exist System.IO.Directory.CreateDirectory(systemFolderCertFile); _l.Debug($"Saving cert file to {systemFileNameCertFile}"); using (var fileStream = new FileStream(systemFileNameCertFile, FileMode.Create)) { certFile.CopyTo(fileStream); } if (analyse) { // Queue foor ANALYSING ac.Status = ApiActivity.ApiStatus.QueuedAnalysis; ac.Message = "File queued for analysis"; _asvc.addUpdateApiActivity(ac); _l.Debug("Analysis requested, queuing for analysis..."); } else { // Queue for SIGNING ac.Status = ApiActivity.ApiStatus.QueuedSigning; ac.Message = "File queued for signing"; _asvc.addUpdateApiActivity(ac); _l.Debug("NO analysis requested, queuing for signing at once..."); } // RETURN STATUS PAGE _l.Debug($"Returning Queued API Status for Key {ac.UniqueKey}"); return(Content(ac.getWebresult())); } else { ac.Status = ApiActivity.ApiStatus.Error; ac.Message = "Office File or Cert File not submitted. Both required for signing!"; _l.Error(ac.Message); _asvc.addUpdateApiActivity(ac); return(Content(ac.getWebresult())); } }