Skip to content

Commit

Permalink
feature: support for aes-cbc then hmac direct enc (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
IceManGreen authored Aug 2, 2024
1 parent 6d77caa commit b7b140e
Show file tree
Hide file tree
Showing 73 changed files with 1,423 additions and 167 deletions.
32 changes: 32 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: bug
assignees: ''

---

## Describe the bug
> A clear and concise description of what the bug is.
## How To Reproduce
> Steps to reproduce the behavior:
> 1. Go to '...'
> 2. Click on '....'
> 3. Scroll down to '....'
> 4. See error
## Expected behavior
> A clear and concise description of what you expected to happen.
## Logs or Screenshots
> If applicable, add screenshots to help explain your problem.
## Desktop (please complete the following information):
> - OS: [e.g. iOS]
> - Browser [e.g. chrome, safari]
> - Version [e.g. 22]
## Additional context
> Add any other context about the problem here.
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[NEW]"
labels: enhancement
assignees: ''

---

## Is your feature request related to a problem? Please describe.
> A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
## Describe the solution you'd like
> A clear and concise description of what you want to happen.
## Describe alternatives you've considered
> A clear and concise description of any alternative solutions or features you've considered.
## Additional context
> Add any other context or screenshots about the feature request here.
34 changes: 34 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!-- HTML Comments can be left in place or removed. -->

#### Proposed Changes ####

<!-- Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. -->

#### Types of Changes ####

<!-- What types of changes does your code introduce ? Bugfix, New Feature, Breaking Change, etc -->

#### Verification ####

<!-- How can the changes be verified? Please provide whatever additional information necessary to help verify the proposed changes. -->

#### Testing ####

<!-- Is this change covered by testing? If not, consider adding a Unit or Integration test. -->

#### Linked Issues ####

<!-- Link any related issues, pull-requests, or commit hashes that are relevant to this pull request. If you are opening a PR without a corresponding issue please consider creating one first. A functional example will greatly help QA with verifying/reproducing a bug or testing new features. -->

#### User-Facing Change ####
<!--
Does this PR introduce a user-facing change? If no, just write "NONE" in the release-note block below.
If the PR requires additional action from users switching to the new release, include the string "action required".
-->
```release-note
```

#### Further Comments ####

<!-- If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc... -->
34 changes: 33 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,34 @@
/.idea/
# IntelliJ project files
.idea
*.iml
out
gen
build/
.DS_Store
generated/
deployed.json
.socket
coverage.out

### Go template
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
vendor/

# Go workspace file
go.work
2 changes: 1 addition & 1 deletion LICENCE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License.

Copyright 2019 Thales e-Security, Inc
Copyright 2024 Thales Group

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![Build Status](https://travis-ci.com/ThalesIgnite/gose.svg?branch=master)](https://travis-ci.com/ThalesIgnite/gose)

# GOSE - JOSE and friends for the Go developer

## Overview
Expand All @@ -7,6 +7,9 @@ GOSE is JOSE/JWT/JWK/JWS/JWKS implemented in Go with Helpers, and examples.

It contains implementations of the JOSE suite of types and helpers for many different use cases.

## Known Issues

* Direct encryption with AEAD mechanisms is not completely following [RFC 7516](https://tools.ietf.org/html/rfc7516)

## Mission

Expand All @@ -20,6 +23,11 @@ It contains implementations of the JOSE suite of types and helpers for many diff

Examples are provided under the `/examples` folder to illustrate correct use of this package.

## Vulnerability check

```sh
$ govulncheck ./... ─╯
Scanning your code and 139 packages across 9 dependent modules for known vulnerabilities...


No vulnerabilities found.
```
92 changes: 92 additions & 0 deletions aes_cbc_cryptor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright 2024 Thales Group
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package gose

import (
"crypto/cipher"
"github.com/ThalesGroup/gose/jose"
)

// AesCbcCryptor provides AES CBC encryption and decryption functions.
// It implements BlockEcryptionKey
type AesCbcCryptor struct {
kid string
alg jose.Alg
blockCipher cipher.BlockMode
}

// NewAesCbcCryptor create a new instance of an AesCbcCryptor from the supplied parameters.
// It implements AeadEncryptionKey
func NewAesCbcCryptor(blockCipher cipher.BlockMode, kid string, alg jose.Alg) BlockEncryptionKey {
return &AesCbcCryptor{
kid: kid,
alg: alg,
blockCipher: blockCipher,
}
}

func (cryptor *AesCbcCryptor) trimSize(input []byte) (res []byte) {
blockSize := cryptor.blockCipher.BlockSize()
if len(input) % blockSize != 0 {
multiplier := len(input) / blockSize
res = make([]byte, (multiplier + 1)*blockSize)
copy(res, input)
return
}
return input
}

func (cryptor *AesCbcCryptor) Kid() string {
return cryptor.kid
}

func (cryptor *AesCbcCryptor) Algorithm() jose.Alg {
return cryptor.alg
}

func getDestinationSize(inputLength int, blockSize int) int {
var finalSize int
if multiplier := inputLength / blockSize; multiplier > 0 {
finalSize = multiplier*blockSize + blockSize
} else {
finalSize = blockSize
}
return finalSize
}

func (cryptor *AesCbcCryptor) Seal(plaintext []byte) []byte {
src := cryptor.trimSize(plaintext)
dstSize := getDestinationSize(len(plaintext), cryptor.blockCipher.BlockSize())
dst := make([]byte, dstSize)
cryptor.blockCipher.CryptBlocks(dst, src)
return dst
}

func (cryptor *AesCbcCryptor) Open(ciphertext []byte) []byte {
dstSize := getDestinationSize(len(ciphertext), cryptor.blockCipher.BlockSize())
dst := make([]byte, dstSize)
cryptor.blockCipher.CryptBlocks(dst, ciphertext)
return dst
}



116 changes: 116 additions & 0 deletions aes_cbc_cryptor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright 2024 Thales Group
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package gose

import (
"crypto/rand"
"github.com/ThalesGroup/gose/jose"
"github.com/stretchr/testify/require"
"testing"
)



func TestAesCbcCryptor(t *testing.T) {
var err error
iv := make([]byte, 16)
_, err = rand.Read(iv)
require.NoError(t, err)

expectedKid := "aes0"
expectedAlg := jose.AlgA256CBC

// mocking the block mode cipher
mc1 := &MockBlockMode{}
mc1.On("BlockSize").Return(len(iv))
require.NoError(t, err)
c1 := NewAesCbcCryptor(mc1, expectedKid, expectedAlg)

t.Run("testKid", func(t *testing.T) {
testKid(t, expectedKid, c1)
})

t.Run("testAlgorithm", func(t *testing.T) {
testAlgorithm(t, expectedAlg, c1)
})

t.Run("testSeal", func(t *testing.T) {
// mocking the block mode cipher for encryption
mc2 := &MockBlockMode{
mode: ModeEncrypt,
}
mc2.On("BlockSize").Return(len(iv))
require.NoError(t, err)
c2 := NewAesCbcCryptor(mc2, expectedKid, expectedAlg)
testSeal(t, c2)
})

t.Run("testOpen", func(t *testing.T) {
// mocking the block mode cipher for decryption
mc3 := &MockBlockMode{
mode: ModeDecrypt,
}
mc3.On("BlockSize").Return(len(iv))
require.NoError(t, err)
c3 := NewAesCbcCryptor(mc3, expectedKid, expectedAlg)
testOpen(t, c3)
})
}


func testKid(t *testing.T, expectedKid string, cryptor BlockEncryptionKey){
kid := cryptor.Kid()
require.Equal(t, expectedKid, kid)
}

func testAlgorithm(t *testing.T, expectedAlg jose.Alg, cryptor BlockEncryptionKey){
alg := cryptor.Algorithm()
require.Equal(t, expectedAlg, alg)
}

func testSeal(t *testing.T, cryptor BlockEncryptionKey){
small := []byte("ping")
cSmall := cryptor.Seal(small)
require.Equal(t, 0, len(cSmall)%16)
require.NotEqual(t, small, cSmall)
require.Contains(t, string(cSmall), mockExpectedCiphertext)

big := []byte("pingpingpingpingpingpingpingpingpingping")
cBig := cryptor.Seal(big)
require.Equal(t, 0, len(cBig)%16)
require.NotEqual(t, big, cBig)
require.Contains(t, string(cBig), mockExpectedCiphertext)
}

func testOpen(t *testing.T, cryptor BlockEncryptionKey){
small := []byte("ping")
cSmall := cryptor.Open(small)
require.Equal(t, 0, len(cSmall)%16)
require.NotEqual(t, small, cSmall)
require.Contains(t, string(cSmall), mockExpectedCleartext)

big := []byte("pingpingpingpingpingpingpingpingpingping")
cBig := cryptor.Open(big)
require.Equal(t, 0, len(cBig)%16)
require.NotEqual(t, big, cBig)
require.Contains(t, string(cBig), mockExpectedCleartext)
}
Loading

0 comments on commit b7b140e

Please sign in to comment.