Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade to spec version 13 #12

Merged
merged 48 commits into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
163aa82
remove @request-params add @query-param
bblfish Nov 8, 2022
238d2e6
add support for "sf" https://github.com/bblfish/httpSig/issues/2
bblfish Nov 8, 2022
bc2db5d
update sbt-typelevel
bblfish Nov 8, 2022
9991d67
update to bobcats 0.3 with JWK support
bblfish Nov 11, 2022
1267e87
add support for ;tag in @signature-params
bblfish Nov 12, 2022
df612f9
Part I of rewrite: header selectors tested
bblfish Nov 14, 2022
4a9bdba
setup framework for testing new @method selectors
bblfish Nov 15, 2022
4ec5d3c
filled in all @xxx for Akka
bblfish Nov 15, 2022
3ec284e
finish tests for Akka implementation. good on JVM
bblfish Nov 16, 2022
06b2028
prePR fixes
bblfish Nov 16, 2022
7d8d044
renmaed some directories
bblfish Nov 16, 2022
0229f02
renmaed dir message -> messages
bblfish Nov 16, 2022
4cee7c1
renamed AkkaAtSelector to AkkaAtSelectors
bblfish Nov 16, 2022
2029d77
rename again
bblfish Nov 16, 2022
fa37c71
compiles
bblfish Nov 16, 2022
c45c195
compiles again
bblfish Nov 16, 2022
bd3a3f7
@xx tests pass for Http4s JS and JVM locally
bblfish Nov 16, 2022
855c7a6
refactored to remove duplication in selectors
bblfish Nov 17, 2022
67e681e
prePR
bblfish Nov 17, 2022
b3ab8b1
Add reasoning on types. (work in progress)
bblfish Nov 19, 2022
0965d2e
major rewrite simplifying code as per messages/README.md
bblfish Nov 23, 2022
57c3fab
added RequestSelectorDB but found HeaderSelector is not FP!
bblfish Nov 26, 2022
588e1cd
ComponentId uses dependent types + SF type of value
bblfish Nov 27, 2022
6ca13d5
use ByteVector in rfc8941. added Request Tests
bblfish Nov 28, 2022
787f6b4
basic http msg parser for Akka testing
bblfish Nov 28, 2022
3ab844a
add more tests
bblfish Nov 28, 2022
7a0b770
added more tests. Cleaned up code.
bblfish Nov 29, 2022
32f153d
renaming a HttpMsgInterpreter to TestMsgInterpreter...
bblfish Nov 29, 2022
f0205be
Try to Either migration. https://github.com/bblfish/httpSig/issues/14
bblfish Nov 29, 2022
fe25eee
develop typesafe approach to sigInput
bblfish Nov 30, 2022
36bdbfa
sbt 1.8, more tests, http4s static tests run
bblfish Dec 1, 2022
25415e3
req/res separation. Signature(-*) to HttpOps
bblfish Dec 4, 2022
018441b
add all other requests testing sig base from spec
bblfish Dec 5, 2022
a09a440
start preparing for signature
bblfish Dec 5, 2022
8eaead0
updating cats lead to updating bobcats
bblfish Dec 7, 2022
96b8cca
add signature tests with timing verification (JVM)
bblfish Dec 7, 2022
4d2361b
little fix enabling the declared JS tests pass
bblfish Dec 7, 2022
2c26135
clean up dependencies, %%->%%%, simplify test
bblfish Dec 8, 2022
aa87a36
JS tests compile but don't succeed.
bblfish Dec 8, 2022
9d6fcb7
minor change on io
bblfish Dec 8, 2022
792c253
@SystemFW idea: move time to fctn, delete Clock
bblfish Dec 8, 2022
d5498de
add test for HMAC
bblfish Dec 8, 2022
e760036
add notes prior to refactoring signatureAuthN
bblfish Dec 9, 2022
b491b8b
refactor signatureAuthN into a class.
bblfish Dec 9, 2022
612574c
added Akka Signature Test (fixed test)
bblfish Dec 12, 2022
ad96c6e
update READMEs
bblfish Dec 12, 2022
7dd6fea
remove annoying functor in Http. Add plain http4s test to make sure o…
bblfish Dec 13, 2022
c643385
add tests for signature creation (and verification)
bblfish Dec 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .editorconfig

This file was deleted.

6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
scala: [3.1.3]
scala: [3.2.1]
java: [temurin@17]
project: [rootJS, rootJVM]
jsenv: [NodeJS, Chrome, Firefox]
Expand Down Expand Up @@ -76,7 +76,7 @@ jobs:
node-version: 14

- name: Check that workflows are up to date
run: 'sbt ''project ${{ matrix.project }}'' ''++${{ matrix.scala }}'' ''set Global / useJSEnv := JSEnv.${{ matrix.jsenv }}'' ''project /'' githubWorkflowCheck'
run: sbt githubWorkflowCheck

- name: Check headers and formatting
if: matrix.java == 'temurin@17'
Expand All @@ -103,7 +103,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
scala: [3.1.3]
scala: [3.2.1]
java: [temurin@17]
runs-on: ${{ matrix.os }}
steps:
Expand Down
65 changes: 51 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,62 @@
## HttpSig library

This library consists of Scala and Scala-JS components implementing the
IETF's HTTP-Bis [Signing HTTP Messages](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures)
spec (version 13). That spec builds on the experience of [Amazon Web Services, Signing HTTP](https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html).
spec. It can be used in many ways, including authentication protocols such as
[HttpSig](https://github.com/solid/authentication-panel/blob/main/proposals/HttpSignature.md).
IETF's HTTP-Bis [HTTP Message Signatures](https://datatracker.ietf.org/doc/draft-ietf-httpbis-message-signatures/).

See also the web service
written in Python at [httpsig.org](https://httpsig.org)

## What is Http Message Signatures?

The first version of this spec appeared as [draftcavage-http-signatures](https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-00) in 2013. After which followed 12 more versions. The IETF HTTP Bis WG then took that work over improving it a lot.

Http Signatures can be used by clients and by servers, to sign messages. This can be used in authentication protocols such as the in development [Solid HttpSig](https://github.com/bblfish/authentication-panel/blob/main/proposals/HttpSignature.md).

### Where is it used?

Older versions of the spec have been used by Amazon Web Services and Mastodon, among others.

* see the [Amazon Web Services, Signing HTTP](https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html) spec.

* Version 06 of that spec is used by Mastodon. See
- [the joinmastodon /spec/security](https://docs.joinmastodon.org/spec/security/#http-sign) document.
- [signature_verification.rb](https://github.com/mastodon/mastodon/blob/736b4283b0936134e83092f8b16d686f6478a51f/app/controllers/concerns/signature_verification.rb) ruby file

## Content of this repository

This repository contains the following projects:

* rfc8941: a pure scala implementation
* **rfc8941**: a pure scala implementation
of [RFC 8941: Structured Field Values](https://datatracker.ietf.org/doc/html/rfc8941)
needed by "Signing HTTP Messages" that compiles to Java and JavaScript. This is a core component needed for "Signing Http Messages"
* akka: Implementation of "Signing HTTP Messages" for the [akka-http](https://akka.io/) Actor Framework of
* **ietfSig**: the main implementation in Scala compiling to JVM and JS, with an abstraction of HTTP so as to reduce duplication of code for the various frameworks such as Akka or HttpSig
* **ietfSigTests**: a project with tests that are then run by each of the implementations in their tests.
* **akka**: Implementation of "Signing HTTP Messages" for the [akka-http](https://akka.io/) Actor Framework of
of [Signing HTTP Messages](https://www.ietf.org/archive/id/draft-ietf-httpbis-message-signatures-07.html)
* [http4s](https://http4s.org) implementation of "Signing HTTP Messages" project for Java or JS clients (todo nodejs)
* **http4s** implementation of the cats based [http4s](https://http4s.org)

## Usage

The architecture of the third version of this library was worked out n [the ietfSig README.md](./ietfSig/shared/src/main/scala/run/cosy/http/messages/README.md).

Note: currently we only have implemented request signing and verification. That is most of the work needed for response verification, so it should not take much time to get done.

Look at examples in the test suite.
* [VerifyBaseOnRequests.scala](ietfSigTests/shared/src/main/scala/run/cosy/http/messages/VerifyBaseOnRequests.scala) shows how a client can build the base for all the examples in the spec using typesafe functions.
* [VerifySignatureTests.scala](ietfSigTests/shared/src/main/scala/run/cosy/http/auth/VerifySignatureTests.scala) shows how a server would verify the signatures in a request, given a DB of keyId to key material db.
* todo, verify the client correctly signs example messages
* todo, implement the same for response signing: this should be easier because most of the tools for request signing can be re-used

Another place to look is for applications using the library.
See for example:
* [Reactive Solid](https://github.com/co-operating-systems/Reactive-SoLiD) web server in Akka
* [SolidCtrlApp](https://github.com/bblfish/SolidCtrlApp)

(There may be a lag between the time this library is released and the time they use the latest version)

### JavaScript Testing

httpSig compiles to Java and JavaScript.
`httpSig` compiles to Java and JavaScript.
Testing in JS environments is done using [Selenium](https://www.selenium.dev).
This requires having a selenium driver.
On MacOs this is installed ([see Stack Overflow](https://stackoverflow.com/questions/18868743/how-to-install-selenium-webdriver-on-mac-os)) using `brew install selenium-server`. But one still requires Chrome and Firefox drivers to be installed after that.
Expand All @@ -34,9 +73,9 @@ Inside of sbt one can then run tests for Chrome only with
> set Global / useJSEnv := JSEnv.Chrome
> test
```
NodeJS is the default.
NodeJS is the default, but that won't run any tests in this case
as we have not implemented encryption for NodeJS in bobcats yet.

(Please fill in details for other environments)

### Released Artifacts

Expand All @@ -51,11 +90,9 @@ snapshot repository.
### Thanks

This work was made possible by the generous EU grant from nlnet for
the [Solid Control Project](https://nlnet.nl/project/SolidControl/).
That project is to end in January 2022.
the [Solid Control Project](https://nlnet.nl/project/SolidControl/) and for [Solid Wallet](https://nlnet.nl/project/SolidWallet/index.html)
That last will go through 2023.

If you wish to have the library run on a specific client or server environment, please
contact [[email protected]](mailto:[email protected]) or leave
issues in the Issue database.

We are looking for further funding opportunities to continue the work.
38 changes: 22 additions & 16 deletions akka/src/main/scala/run/cosy/akka/http/AkkaTp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,37 @@
package run.cosy.akka.http

import akka.http.scaladsl.model
import akka.http.scaladsl.model.{HttpHeader, HttpMessage, HttpRequest, HttpResponse}
import akka.http.scaladsl.model.headers.RawHeader
import run.cosy.http.{Http, HttpOps}
import akka.http.scaladsl.model as ak
import akka.http.scaladsl.model.{HttpHeader, HttpMessage, HttpRequest, HttpResponse}
import cats.Id
import cats.effect.IO
import run.cosy.http.headers.{SignatureInputMatcher, SignatureMatcher}
import run.cosy.http.{Http, HttpOps}

object AkkaTp extends Http:
override type Message[F[_]] = model.HttpMessage
override type Request[F[_]] = model.HttpRequest
override type Response[F[_]] = model.HttpResponse
override type Header = model.HttpHeader
override type F[A] = cats.Id[A]
override type Message = model.HttpMessage
override type Request = model.HttpRequest
override type Response = model.HttpResponse
override type Header = model.HttpHeader

given Conversion[model.HttpRequest, Http.Request[IO, HT]] with
def apply(req: HttpRequest): Http.Request[IO, HT] = req.asInstanceOf[Http.Request[IO, HT]]
given Conversion[model.HttpResponse, Http.Response[IO, HT]] with
def apply(req: HttpResponse): Http.Response[IO, HT] = req.asInstanceOf[Http.Response[IO, HT]]
// given Conversion[model.HttpRequest, Http.Request[IO, HT]] with
// def apply(req: HttpRequest): Http.Request[IO, HT] = req.asInstanceOf[Http.Request[IO, HT]]
// given Conversion[model.HttpResponse, Http.Response[IO, HT]] with
// def apply(req: HttpResponse): Http.Response[IO, HT] = req.asInstanceOf[Http.Response[IO, HT]]

given hOps: HttpOps[HT] with

extension [F[_]](msg: Http.Message[F, HT])
def headers: Seq[Http.Header[HT]] =
val m = msg.asInstanceOf[ak.HttpMessage]
extension (msg: Http.Message[HT])
def headerSeq: Seq[Http.Header[HT]] =
val m = msg.asInstanceOf[model.HttpMessage]
m.headers

extension [F[_], R <: Http.Message[F, HT]](msg: R)
override val Signature: SignatureMatcher[HT] = run.cosy.akka.http.headers.Signature
override val `Signature-Input`: SignatureInputMatcher[HT] =
run.cosy.akka.http.headers.`Signature-Input`

extension [R <: Http.Message[HT]](msg: R)
def addHeaders(headers: Seq[Http.Header[HT]]): R =
// don't know how to get rid of the asInstanceOf
val m = msg.asInstanceOf[HttpMessage]
Expand All @@ -53,7 +59,7 @@ object AkkaTp extends Http:
m.withHeaders(m.headers.prepended(RawHeader(name, value))).asInstanceOf[R]

def removeHeader(name: String): R =
val m = msg.asInstanceOf[ak.HttpMessage]
val m = msg.asInstanceOf[model.HttpMessage]
m.removeHeader(name).asInstanceOf[R]

def headerValue(name: String): Option[String] =
Expand Down

This file was deleted.

Loading