Skip to content
This repository has been archived by the owner on Jun 26, 2023. It is now read-only.

Commit

Permalink
feat: add basic crypto interface test suite
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobheun committed Oct 20, 2019
1 parent 0551fac commit 11f964c
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 2 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
},
"devDependencies": {
"aegir": "^20.4.1",
"it-handshake": "^1.0.0",
"it-pair": "^1.0.0",
"it-pipe": "^1.0.1",
"peer-info": "^0.17.0"
Expand Down
17 changes: 16 additions & 1 deletion src/crypto/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,22 @@ interface-crypto

## Using the Test Suite

TODO:
You can also check out the [internal test suite](../../test/crypto/compliance.spec.js) to see the setup in action.

```js
const tests = require('libp2p-interfaces/src/crypto/tests')
const yourCrypto = require('./your-crypto')

tests({
setup () {
// Set up your crypto if needed, then return it
return yourCrypto
},
teardown () {
// Clean up your crypto if needed
}
})
```

## API

Expand Down
86 changes: 86 additions & 0 deletions src/crypto/tests/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/* eslint-env mocha */
'use strict'

const duplexPair = require('it-pair/duplex')
const pipe = require('it-pipe')
const peers = require('../../utils/peers')
const PeerId = require('peer-id')
const { collect } = require('streaming-iterables')
const chai = require('chai')
const expect = chai.expect
chai.use(require('dirty-chai'))

module.exports = (common) => {
describe('interface-crypto', () => {
let crypto
let localPeer
let remotePeer

before(async () => {
[
crypto,
localPeer,
remotePeer
] = await Promise.all([
common.setup(),
PeerId.createFromJSON(peers[0]),
PeerId.createFromJSON(peers[1])
])
})

after(() => common.teardown && common.teardown())

it('has a protocol string', () => {
expect(crypto.protocol).to.exist()
expect(crypto.protocol).to.be.a('string')
})

it('it wraps the provided duplex connection', async () => {
const [localConn, remoteConn] = duplexPair()

const [
inboundResult,
outboundResult
] = await Promise.all([
crypto.secureInbound(remotePeer, localConn),
crypto.secureOutbound(localPeer, remoteConn, remotePeer)
])

// Echo server
pipe(inboundResult.conn, inboundResult.conn)

// Send some data and collect the result
const input = Buffer.from('data to encrypt')
const result = await pipe(
[input],
outboundResult.conn,
// Convert BufferList to Buffer via slice
(source) => (async function * toBuffer () {
for await (const chunk of source) {
yield chunk.slice()
}
})(),
collect
)

expect(result).to.eql([input])
})

it('should return the remote peer id', async () => {
const [localConn, remoteConn] = duplexPair()

const [
inboundResult,
outboundResult
] = await Promise.all([
crypto.secureInbound(remotePeer, localConn),
crypto.secureOutbound(localPeer, remoteConn, remotePeer)
])

// Inbound should return the initiator (local) peer
expect(inboundResult.remotePeer.id).to.eql(localPeer.id)
// Outbound should return the receiver (remote) peer
expect(outboundResult.remotePeer.id).to.eql(remotePeer.id)
})
})
}
File renamed without changes.
2 changes: 1 addition & 1 deletion test/connection/compliance.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

const tests = require('../../src/connection/tests')
const { Connection } = require('../../src/connection')
const peers = require('../utils/peers')
const peers = require('../../src/utils/peers')
const PeerId = require('peer-id')
const multiaddr = require('multiaddr')
const pair = require('it-pair')
Expand Down
13 changes: 13 additions & 0 deletions test/crypto/compliance.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* eslint-env mocha */
'use strict'

const tests = require('../../src/crypto/tests')
const mockCrypto = require('./mock-crypto')

describe('compliance tests', () => {
tests({
setup () {
return mockCrypto
}
})
})
69 changes: 69 additions & 0 deletions test/crypto/mock-crypto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use strict'

const PeerId = require('peer-id')
const handshake = require('it-handshake')
const duplexPair = require('it-pair/duplex')
const pipe = require('it-pipe')

// A basic transform that does nothing to the data
const transform = () => {
return (source) => (async function * () {
for await (const chunk of source) {
yield chunk
}
})()
}

module.exports = {
protocol: 'insecure',
secureInbound: async (localPeer, duplex) => {
// 1. Perform a basic handshake.
const shake = handshake(duplex)
shake.write(localPeer.id)
const remoteId = await shake.read()
shake.rest()

// 2. Create your encryption box/unbox wrapper
const wrapper = duplexPair()
const encrypt = transform() // Use transform iterables to modify data
const decrypt = transform()

pipe(
wrapper[0], // We write to wrapper
encrypt, // The data is encrypted
shake.stream, // It goes to the remote peer
decrypt, // Decrypt the incoming data
wrapper[0] // Pipe to the wrapper
)

return {
conn: wrapper[1],
remotePeer: new PeerId(remoteId.slice())
}
},
secureOutbound: async (localPeer, duplex, remotePeer) => {
// 1. Perform a basic handshake.
const shake = handshake(duplex)
shake.write(localPeer.id)
const remoteId = await shake.read()
shake.rest()

// 2. Create your encryption box/unbox wrapper
const wrapper = duplexPair()
const encrypt = transform()
const decrypt = transform()

pipe(
wrapper[0], // We write to wrapper
encrypt, // The data is encrypted
shake.stream, // It goes to the remote peer
decrypt, // Decrypt the incoming data
wrapper[0] // Pipe to the wrapper
)

return {
conn: wrapper[1],
remotePeer: new PeerId(remoteId.slice())
}
}
}

0 comments on commit 11f964c

Please sign in to comment.