public async Task <IActionResult> SignUsingAuthenticode(AuthenticodeSignRequest request) { AccessToken token; try { token = _accessTokenSerializer.Deserialize(request.AccessToken); } catch (Exception ex) { _logger.LogInformation(ex, "Access token could not be decrypted"); return(Unauthorized()); } if (!_accessTokenConfig.TryGetValue(token.Id, out var tokenConfig) || !tokenConfig.Valid) { _logger.LogWarning("Access token not in config file, or marked as invalid: {Id}", token.Id); return(Unauthorized()); } var cert = _secretStorage.LoadAuthenticodeCertificate(token.KeyName, token.Code); byte[] artifact; try { artifact = await GetFileFromPayloadAsync(token, tokenConfig, request); } catch (Exception ex) { _logger.LogError(ex, "Could not retrieve artifact to sign"); return(BadRequest(ex.Message)); } var signed = await _signer.SignAsync(artifact, cert, tokenConfig.SignDescription, tokenConfig.SignUrl); return(File(signed, "application/octet-stream")); }
private bool CheckIfRequestIsWhitelisted(AccessToken token, AccessTokenConfig tokenConfig, AuthenticodeSignRequest request) { if ( request.ArtifactUrl != null && tokenConfig.AllowedUrls != null && !tokenConfig.AllowedUrls.Any(item => Regex.IsMatch(request.ArtifactUrl.Host, item.Domain) && Regex.IsMatch(request.ArtifactUrl.AbsolutePath, item.Path) ) ) { _logger.LogWarning("[{Id}] URL signing requested, but url {Url} is not on the whitelist!", token.Id, request.ArtifactUrl); return(false); } if (request.Artifact != null && !tokenConfig.AllowUploads) { _logger.LogWarning("[{Id}] File uploaded, but access token is forbidden from doing so!", token.Id); return(false); } return(true); }
/// <summary> /// Gets the file to sign from the request payload. /// </summary> /// <param name="token">Access token for the request</param> /// <param name="tokenConfig">Configuration for this access token</param> /// <param name="request">The request</param> /// <returns>The file contents</returns> private async Task <byte[]> GetFileFromPayloadAsync(AccessToken token, AccessTokenConfig tokenConfig, AuthenticodeSignRequest request) { if (!CheckIfRequestIsWhitelisted(token, tokenConfig, request)) { throw new InvalidOperationException("Upload request is not allowed."); } if (request.ArtifactUrl != null) { _logger.LogInformation("Signing request received: {Id} is signing {ArtifactUrl}", token.Id, request.ArtifactUrl); return(await _httpClient.GetByteArrayAsync(request.ArtifactUrl)); } if (request.Artifact != null) { _logger.LogInformation("Signing request received: {Id} is signing {Filename}", token.Id, request.Artifact.FileName); using (var stream = new MemoryStream()) { await request.Artifact.CopyToAsync(stream); return(stream.ToArray()); } } // TODO: This should likely throw instead return(new byte[0]); }