├── .circleci └── config.yml ├── .gitignore ├── CHANGELOG.md ├── CLA.md ├── CODE-OF-CONDUCT.md ├── CODING-CONVENTIONS.md ├── CONTRIBUTING.md ├── GOVERNANCE.md ├── LICENSE ├── README.md ├── build.gradle ├── database ├── README.md ├── oracle_ddl.sql └── postgres_ddl.sql ├── docker ├── .gitignore ├── Dockerfile ├── ha │ ├── docker-compose.yml │ ├── init.sql │ ├── keys │ │ ├── nodeKey.key │ │ ├── nodeKey.pub │ │ └── passwordFile │ ├── nginx.conf │ ├── orion.conf │ └── partyinfo.cbor ├── test.sh ├── test_ha.sh └── tests │ ├── 01 │ ├── goss.yaml │ └── goss_wait.yaml │ ├── dgoss │ └── goss-linux-amd64 ├── docs ├── README.md ├── community │ ├── code-reviews.md │ └── community-membership.md └── development │ ├── building.md │ ├── code-coverage.md │ ├── docker.md │ ├── machine_setup.md │ ├── oracle_jdbc.md │ └── running_developer_builds.md ├── gradle.properties ├── gradle ├── check-licenses.gradle ├── eclipse-java-consensys-style.xml ├── greclipse-gradle-consensys-style.properties ├── spotless.license.java ├── versions.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── keys ├── password.txt ├── tm1.key ├── tm1.pub ├── tm1a.key ├── tm1a.pub └── unknown_type.key ├── pre-commit ├── scripts └── cloudsmith-upload.sh ├── settings.gradle └── src ├── acceptance-test ├── java │ └── net │ │ └── consensys │ │ └── orion │ │ └── acceptance │ │ ├── EthClientStub.java │ │ ├── NodeUtils.java │ │ ├── dsl │ │ ├── AcceptanceTestBase.java │ │ ├── KeyDefinition.java │ │ ├── OrionConfigFileGenerator.java │ │ ├── OrionFactory.java │ │ ├── OrionNode.java │ │ └── OrionProcessRunner.java │ │ ├── oracle │ │ └── OracleSendReceiveTest.java │ │ ├── postgresql │ │ └── PostgresqlSendReceiveTest.java │ │ └── send │ │ ├── MultiKeyOperationAcceptanceTest.java │ │ ├── SingleNodeSendTest.java │ │ └── receive │ │ ├── DualNodesSendReceiveTest.java │ │ ├── SingleNodeSendReceiveTest.java │ │ └── privacyGroup │ │ ├── DualNodesPrivacyGroupsTest.java │ │ ├── DualNodesSendReceiveUsingPrivacyGroupTest.java │ │ ├── QueryGroupRestartTest.java │ │ └── SingleNodeDualSendReceiveTest.java └── resources │ ├── key1.key │ ├── key1.pub │ ├── key2.key │ ├── key2.pub │ ├── key3.key │ ├── key3.pub │ ├── key4.key │ ├── key4.pub │ ├── key5.key │ └── key5.pub ├── main ├── java │ └── net │ │ └── consensys │ │ └── orion │ │ ├── cmd │ │ ├── Orion.java │ │ ├── OrionArguments.java │ │ ├── OrionStartException.java │ │ └── PeerCountHandler.java │ │ ├── config │ │ ├── Config.java │ │ └── ConfigException.java │ │ ├── enclave │ │ ├── Enclave.java │ │ ├── EnclaveException.java │ │ ├── EncryptedKey.java │ │ ├── EncryptedPayload.java │ │ ├── KeyStore.java │ │ ├── PrivacyGroupPayload.java │ │ ├── QueryPrivacyGroupPayload.java │ │ └── sodium │ │ │ ├── FileKeyStore.java │ │ │ ├── MemoryKeyStore.java │ │ │ ├── SodiumEnclave.java │ │ │ ├── StoredPrivateKey.java │ │ │ └── serialization │ │ │ ├── PublicKeyDeserializer.java │ │ │ ├── PublicKeyMapKeyDeserializer.java │ │ │ ├── PublicKeyMapKeySerializer.java │ │ │ ├── PublicKeySerializer.java │ │ │ ├── PublicKeyURISerializer.java │ │ │ ├── StoredPrivateKeyDeserializer.java │ │ │ └── StoredPrivateKeySerializer.java │ │ ├── exception │ │ ├── OrionErrorCode.java │ │ └── OrionException.java │ │ ├── http │ │ ├── handler │ │ │ ├── knownnodes │ │ │ │ ├── KnownNode.java │ │ │ │ └── KnownNodesHandler.java │ │ │ ├── partyinfo │ │ │ │ └── PartyInfoHandler.java │ │ │ ├── privacy │ │ │ │ ├── CreatePrivacyGroupHandler.java │ │ │ │ ├── DeletePrivacyGroupHandler.java │ │ │ │ ├── DeletePrivacyGroupRequest.java │ │ │ │ ├── FindPrivacyGroupHandler.java │ │ │ │ ├── FindPrivacyGroupRequest.java │ │ │ │ ├── PrivacyGroup.java │ │ │ │ ├── PrivacyGroupRequest.java │ │ │ │ ├── RetrievePrivacyGroupHandler.java │ │ │ │ └── RetrievePrivacyGroupRequest.java │ │ │ ├── push │ │ │ │ ├── PushHandler.java │ │ │ │ └── PushPrivacyGroupHandler.java │ │ │ ├── receive │ │ │ │ ├── ReceiveHandler.java │ │ │ │ ├── ReceiveRequest.java │ │ │ │ └── ReceiveResponse.java │ │ │ ├── send │ │ │ │ ├── SendHandler.java │ │ │ │ ├── SendRequest.java │ │ │ │ └── SendResponse.java │ │ │ ├── sendraw │ │ │ │ └── SendRawHandler.java │ │ │ ├── upcheck │ │ │ │ └── UpcheckHandler.java │ │ │ └── version │ │ │ │ └── VersionHandler.java │ │ └── server │ │ │ ├── HttpContentType.java │ │ │ ├── HttpError.java │ │ │ └── vertx │ │ │ ├── HttpErrorHandler.java │ │ │ └── OrionLoggerHandler.java │ │ ├── network │ │ ├── HttpTlsOptionHelpers.java │ │ ├── NetworkDiscovery.java │ │ ├── NetworkNodes.java │ │ ├── NodeHttpClientBuilder.java │ │ ├── PersistentNetworkNodes.java │ │ └── ReadOnlyNetworkNodes.java │ │ ├── payload │ │ └── DistributePayloadManager.java │ │ ├── storage │ │ ├── EncryptedPayloadStorage.java │ │ ├── JpaEntityManagerProvider.java │ │ ├── PrivacyGroupStorage.java │ │ ├── QueryPrivacyGroupStorage.java │ │ ├── Sha512_256StorageKeyBuilder.java │ │ ├── Storage.java │ │ ├── StorageKeyBuilder.java │ │ ├── StorageUtils.java │ │ └── Store.java │ │ └── utils │ │ ├── OrionInfo.java │ │ ├── PlatformDetector.java │ │ ├── Serializer.java │ │ └── TLS.java └── resources │ ├── META-INF │ └── persistence.xml │ ├── default.conf │ ├── log4j2.xml │ └── sample.conf ├── performance-test ├── resources │ ├── bar.key │ ├── bar.pub │ ├── config-8081.txt │ ├── config-8083.txt │ ├── config-8085.txt │ ├── foo.key │ ├── foo.pub │ ├── foobar.key │ ├── foobar.pub │ └── log4j2.xml └── scala │ └── net │ └── consensys │ └── orion │ └── load │ └── LoadSimulation.scala └── test ├── java └── net │ └── consensys │ └── orion │ ├── TestUtils.java │ ├── cmd │ ├── OrionArgumentsTest.java │ └── OrionTest.java │ ├── config │ └── TomlConfigTest.java │ ├── enclave │ ├── EnclaveExceptionTest.java │ ├── EncryptedPayloadTest.java │ ├── PrivacyGroupGenerationTest.java │ └── sodium │ │ ├── FileKeyStoreTest.java │ │ ├── SodiumEnclavePrivacyGroupIdTest.java │ │ ├── SodiumEnclaveStub.java │ │ ├── SodiumEnclaveStubTest.java │ │ └── SodiumEnclaveTest.java │ ├── exception │ └── OrionErrorCodeTest.java │ ├── helpers │ ├── FakePeer.java │ └── StubEnclave.java │ ├── http │ ├── CAOrTofuSecurityTest.java │ ├── CertificateAuthoritySecurityTest.java │ ├── ClientOrionTlsCertificateAutoCreateTest.java │ ├── InsecureSecurityTest.java │ ├── TofuSecurityTest.java │ ├── WhiteListSecurityTest.java │ └── handler │ │ ├── CreatePrivacyGroupHandlerTest.java │ │ ├── DeletePrivacyGroupHandlerTest.java │ │ ├── FindPrivacyGroupHandlerTest.java │ │ ├── HandlerTest.java │ │ ├── PartyInfoHandlerTest.java │ │ ├── PushHandlerTest.java │ │ ├── ReceiveHandlerTest.java │ │ ├── RetrievePrivacyGroupHandlerTest.java │ │ ├── SendHandlerTest.java │ │ ├── SendRawHandlerTest.java │ │ ├── SendRawHandlerWithNodeKeys.java │ │ ├── SendRequestTest.java │ │ ├── UpcheckHandlerTest.java │ │ ├── VersionHandlerTest.java │ │ └── knownnodes │ │ └── KnownNodesHandlerTest.java │ ├── network │ ├── CaOrTofuNodeClientTest.java │ ├── CertificateAuthorityNodeClientTest.java │ ├── InsecureNodeClientTest.java │ ├── NetworkDiscoveryTest.java │ ├── PersistentNetworkNodesTest.java │ ├── TofuNodeClientTest.java │ └── WhitelistNodeClientTest.java │ ├── payload │ └── DistributePayloadManagerTest.java │ ├── storage │ ├── EncryptedPayloadStorageTest.java │ └── PrivacyGroupStorageTest.java │ └── utils │ └── SerializerTest.java └── resources ├── alwaysSendToKeyStoreTest.toml ├── defaultConfigTest.toml ├── fullConfigMissingStoragePathTest.toml ├── fullConfigTest.toml ├── invalidConfigTest.toml ├── keySets.json ├── keyStoreTest.toml ├── missingMandatoryConfigTest.toml └── multipleKeyStoreTest.toml /.gitignore: -------------------------------------------------------------------------------- 1 | *.db.test 2 | /keys.test 3 | /tests 4 | mapdb 5 | db 6 | routerdb 7 | routerdb.wal.0 8 | 9 | 10 | ### Gradle ### 11 | .gradle 12 | oracle.properties 13 | 14 | 15 | ### IntelliJ ### 16 | *.iml 17 | .idea 18 | build/ 19 | out/ 20 | 21 | 22 | ### Eclipse ### 23 | *.bak 24 | *.swp 25 | *.tmp 26 | *~.nib 27 | .loadpath 28 | .metadata 29 | .prefs 30 | .recommenders 31 | .settings/ 32 | bin/ 33 | local.properties 34 | target/ 35 | tmp/ 36 | 37 | # Eclipse Core 38 | .project 39 | 40 | # External tool builders 41 | .externalToolBuilders/ 42 | 43 | # Locally stored "Eclipse launch configurations" 44 | *.launch 45 | 46 | # JDT-specific (Eclipse Java Development Tools) 47 | .classpath 48 | 49 | # STS (Spring Tool Suite) 50 | .springBeans 51 | -------------------------------------------------------------------------------- /CLA.md: -------------------------------------------------------------------------------- 1 | Sign the CLA 2 | ============= 3 | 4 | This page is the step-by-step guide to signing the Consensys Software Inc. 5 | Individual Contributor License Agreement. 6 | 7 | 1. First and foremost, read [the current version of the CLA]. 8 | It is written to be as close to plain English as possible. 9 | 10 | 2. Make an account on [GitHub] if you don't already have one. 11 | 12 | 3. After creating your first pull request, you will see a merge 13 | pre-requisite requiring to you read and sign the CLA. 14 | 15 | If you have any questions, you can reach us on [Discord](README.md#chat). 16 | 17 | [GitHub]: https://github.com/ 18 | [the current version of the CLA]: https://gist.github.com/rojotek/978b48a5e8b68836856a8961d6887992 -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [private-quorum@consensys.net]. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [Contributor Covenant]: https://www.contributor-covenant.org 74 | [private-quorum@consensys.net]: mailto:private-quorum@consensys.net -------------------------------------------------------------------------------- /GOVERNANCE.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | This project is led by a benevolent dictator (ConsenSys) and managed by the community. That is, the 3 | community actively contributes to the day-to-day maintenance of the project, but the general 4 | strategic line is drawn by the benevolent dictator. In case of disagreement, they have the last word. 5 | It is the benevolent dictator’s job to resolve disputes within the community and to ensure that the 6 | project is able to progress in a coordinated way. In turn, it is the community’s job to guide the 7 | decisions of the benevolent dictator through active engagement and contribution. 8 | 9 | 10 | # Principles 11 | 12 | The community adheres to the following principles: 13 | * Open: Orion is open source. See repository guidelines and CLA, below. 14 | * Welcoming and respectful: See Code of Conduct, below. 15 | * Transparent and accessible: Work and collaboration should be done in public. 16 | * Merit: Ideas and contributions are accepted according to their technical merit and alignment with 17 | project objectives and design principles. 18 | 19 | # Code of Conduct 20 | See [code of conduct] 21 | 22 | # Community membership 23 | 24 | See [community membership] 25 | 26 | # Decision Making 27 | Decision making will be handled by the Approvers (see [community membership]). If consensus cannot 28 | be reached, the Benevolent Dictator will provide the final word on the decision. 29 | 30 | 31 | # CLA 32 | 33 | All contributors must sign the CLA, as described in [CLA.md]. 34 | ## Attribution 35 | 36 | This document was influenced by the following: 37 | - Kubernetes community-membership.md, available at [kub community membership]. 38 | - Kubernetes governance.md, available at [kub governance] 39 | - OSSWatch Benevolent Dictator Governance Model, available at [oss watch benevolent dictator]. 40 | 41 | [CLA.md]: /CLA.md 42 | [code of conduct]: /CODE-OF-CONDUCT.md 43 | [oss watch benevolent dictator]: http://oss-watch.ac.uk/resources/benevolentdictatorgovernancemodel 44 | [kub community membership]: https://raw.githubusercontent.com/kubernetes/community/master/community-membership.md 45 | [kub governance]:https://github.com/kubernetes/community/blob/master/governance.md 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Orion 2 | 3 | [![CircleCI](https://circleci.com/gh/ConsenSys/orion.svg?style=svg&circle-token=5f92fd966a971e60e57f53f2257fe5dda0fcf52c)](https://circleci.com/gh/ConsenSys/orion) 4 | [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/PegasysEng/pantheon/blob/master/LICENSE) 5 | 6 | Orion is an Apache 2.0 licensed, private transaction manager. 7 | 8 | ## ⚠️ Project Deprecation ⚠️ 9 | Now that all primary Orion functionality has been merged into Tessera, Orion is being deprecated. 10 | We encourage all users with active projects to use the provided migration instructions, 11 | documented [here](https://docs.orion.consensys.net/en/latest/Tutorials/Migrating-from-Orion-to-Tessera/). 12 | 13 | We will continue to support Orion users until 30th November 2021. If you have any questions or 14 | concerns, please reach out to the ConsenSys protocol engineering team in the 15 | [#orion channel on Discord](https://discord.gg/hYpHRjK) or by [email](mailto:quorum@consensys.net). 16 | 17 | ## Issues 18 | 19 | See our [contribution guidelines](CONTRIBUTING.md) for details on searching and creating issues. 20 | 21 | If you've commented on existing issue and have been waiting for a reply, feel free to ping us on [Discord](https://discord.gg/n8m22JK). 22 | 23 | ## Chat 24 | 25 | Come and join us in the Orion channel on Discord - here's an [invite](https://discord.gg/n8m22JK). 26 | 27 | ## Orion Users 28 | 29 | See our [User Documentation](https://docs.orion.consensys.net/en/latest/). 30 | 31 | ## Orion Developers 32 | 33 | * [Contribution Guidelines](CONTRIBUTING.md) 34 | * [Coding Conventions](CODING-CONVENTIONS.md) 35 | * [User Documentation](https://docs.orion.consensys.net/en/latest/) 36 | 37 | ### Development 38 | 39 | Instructions for how to get started with developing on the Orion codebase. Please also read the 40 | [contribution guidelines](CONTRIBUTING.md) for more detail on how to submit a pull request (PR). 41 | 42 | * [Machine Setup](docs/development/machine_setup.md) 43 | * [Oracle Maven Repo Credentials for JDBC Driver](docs/development/oracle_jdbc.md) 44 | * [Checking Out and Building](docs/development/building.md) 45 | * [Running Developer Builds](documentation/development/running_developer_builds.md) 46 | * [Code Coverage](docs/development/code-coverage.md) 47 | 48 | ## Running Orion on Docker 49 | 50 | * [Running on Docker](docs/development/docker.md) 51 | -------------------------------------------------------------------------------- /database/README.md: -------------------------------------------------------------------------------- 1 | # Orion Database files 2 | 3 | These files are used when configuring Orion to use database storage. Details on how to configure Orion 4 | to use database storage are in the [User Documentation](https://docs.orion.consensys.net/en/latest/). -------------------------------------------------------------------------------- /database/oracle_ddl.sql: -------------------------------------------------------------------------------- 1 | /* Creates the database table needed when using Oracle DB for Orion storage. */ 2 | 3 | CREATE TABLE store ( 4 | key char(60) primary key, 5 | value blob 6 | ); -------------------------------------------------------------------------------- /database/postgres_ddl.sql: -------------------------------------------------------------------------------- 1 | /* Creates the database table needed when using PostgreSQL for Orion storage. */ 2 | 3 | CREATE TABLE store ( 4 | key char(60), 5 | value bytea, 6 | primary key(key) 7 | ); -------------------------------------------------------------------------------- /docker/.gitignore: -------------------------------------------------------------------------------- 1 | reports 2 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM openjdk:11.0.7-jre-slim-buster 3 | 4 | # Install libsodium 5 | RUN set -eux; \ 6 | apt-get update; \ 7 | apt-get install -y --no-install-recommends curl=7.64.0-4+deb10u2 libsodium23=1.0.17-1; \ 8 | apt-get clean; \ 9 | rm -rf /var/lib/apt/lists/* 10 | 11 | # add Orion user 12 | # hadolint ignore=DL3059 13 | RUN adduser --disabled-password --gecos "" --home /opt/orion orion && \ 14 | chown orion:orion /opt/orion 15 | 16 | USER orion 17 | WORKDIR /opt/orion 18 | 19 | COPY --chown=orion:orion orion /opt/orion/ 20 | 21 | # Expose services ports 22 | # 8080 Node Port, 8888 Client Port 23 | EXPOSE 8080 8888 24 | 25 | ENV PATH="/opt/orion/bin:${PATH}" 26 | ENTRYPOINT ["orion"] 27 | 28 | # Build-time metadata as defined at http://label-schema.org 29 | ARG BUILD_DATE 30 | ARG VCS_REF 31 | ARG VERSION 32 | LABEL org.label-schema.build-date=$BUILD_DATE \ 33 | org.label-schema.name="Orion" \ 34 | org.label-schema.description="Private Transaction Manager" \ 35 | org.label-schema.url="https://docs.orion.pegasys.tech/" \ 36 | org.label-schema.vcs-ref=$VCS_REF \ 37 | org.label-schema.vcs-url="https://github.com/PegaSysEng/orion.git" \ 38 | org.label-schema.vendor="PegaSys" \ 39 | org.label-schema.version=$VERSION \ 40 | org.label-schema.schema-version="1.0" 41 | -------------------------------------------------------------------------------- /docker/ha/docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3' 3 | services: 4 | nginx: 5 | depends_on: 6 | - orion_1 7 | - orion_2 8 | image: nginx:latest 9 | container_name: load_balancer 10 | volumes: 11 | - ./nginx.conf:/etc/nginx/nginx.conf 12 | ports: 13 | - 8080:8080 14 | - 8888:8888 15 | 16 | postgres: 17 | image: postgres:12 18 | container_name: postgres 19 | ports: 20 | - 5432 21 | volumes: 22 | - ./init.sql:/docker-entrypoint-initdb.d/init.sql 23 | environment: 24 | - POSTGRES_HOST_AUTH_METHOD=trust 25 | 26 | orion_1: 27 | depends_on: 28 | - postgres 29 | image: $DOCKER_IMAGE 30 | container_name: orion_1 31 | volumes: 32 | - ./orion.conf:/etc/orion.conf 33 | - ./keys:/var/keys 34 | - orion1-data:/data 35 | command: /etc/orion.conf 36 | restart: always 37 | healthcheck: 38 | test: ["CMD", "curl", "-f", "http://localhost:8080/upcheck"] 39 | interval: 10s 40 | timeout: 10s 41 | retries: 10 42 | # Same configuration as orion_1, but with environment variables 43 | orion_2: 44 | image: $DOCKER_IMAGE 45 | container_name: orion_2 46 | volumes: 47 | - ./keys:/var/keys 48 | - orion2-data:/data 49 | environment: 50 | - ORION_NODEURL=http://load_balancer:8080/ 51 | - ORION_NODEPORT=8080 52 | - ORION_NODENETWORKINTERFACE=0.0.0.0 53 | - ORION_CLIENTURL=http://load_balancer:8888/ 54 | - ORION_CLIENTPORT=8888 55 | - ORION_CLIENTNETWORKINTERFACE=0.0.0.0 56 | - ORION_PUBLICKEYS=/var/keys/nodeKey.pub 57 | - ORION_PRIVATEKEYS=/var/keys/nodeKey.key 58 | - ORION_PASSWORDS=/var/keys/passwordFile 59 | - ORION_WORKDIR=/data 60 | - ORION_TLS=off 61 | - ORION_STORAGE=sql:jdbc:postgresql://postgres:5432/payloaddb 62 | - ORION_KNOWNNODESSTORAGE=sql:jdbc:postgresql://postgres:5432/knownnodes 63 | 64 | restart: always 65 | healthcheck: 66 | test: ["CMD", "curl", "-f", "http://localhost:8080/upcheck"] 67 | interval: 10s 68 | timeout: 10s 69 | retries: 10 70 | 71 | volumes: 72 | orion1-data: 73 | 74 | orion2-data: -------------------------------------------------------------------------------- /docker/ha/init.sql: -------------------------------------------------------------------------------- 1 | CREATE USER orion; 2 | 3 | CREATE DATABASE payloaddb; 4 | GRANT ALL PRIVILEGES ON DATABASE payloaddb TO orion; 5 | 6 | \connect payloaddb 7 | CREATE TABLE store ( 8 | key char(60), 9 | value bytea, 10 | primary key(key) 11 | ); 12 | GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO orion; 13 | 14 | 15 | CREATE DATABASE knownnodes; 16 | GRANT ALL PRIVILEGES ON DATABASE knownnodes TO orion; 17 | 18 | \connect knownnodes 19 | CREATE TABLE store ( 20 | key char(60), 21 | value bytea, 22 | primary key(key) 23 | ); 24 | GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO orion; -------------------------------------------------------------------------------- /docker/ha/keys/nodeKey.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"blPR7FvzHf80uGDrf/bBoN1VONkgWGqeL0JZWDj1n/MSXg3X6Ct5aHLZ0pBlpnx1qk5DFEy1yz8bAS+3iv6K8Eeq0BOOM7MR"},"type":"sodium-encrypted"} -------------------------------------------------------------------------------- /docker/ha/keys/nodeKey.pub: -------------------------------------------------------------------------------- 1 | m1O1hgfEhGnhOJnu4+ZcGfUdwkokqkje+c+dD0rPrQM= -------------------------------------------------------------------------------- /docker/ha/keys/passwordFile: -------------------------------------------------------------------------------- 1 | 123456 2 | -------------------------------------------------------------------------------- /docker/ha/nginx.conf: -------------------------------------------------------------------------------- 1 | events { } 2 | 3 | http { 4 | upstream orion_8080 { 5 | server orion_1:8080 max_fails=1 fail_timeout=5s; 6 | server orion_2:8080 max_fails=1 fail_timeout=5s; 7 | } 8 | 9 | upstream orion_8888 { 10 | server orion_1:8888 max_fails=1 fail_timeout=5s; 11 | server orion_2:8888 max_fails=1 fail_timeout=5s; 12 | } 13 | 14 | server { 15 | listen 8080; 16 | 17 | location / { 18 | proxy_pass http://orion_8080; 19 | } 20 | } 21 | 22 | server { 23 | listen 8888; 24 | 25 | location / { 26 | proxy_pass http://orion_8888; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /docker/ha/orion.conf: -------------------------------------------------------------------------------- 1 | nodeurl = "http://load_balancer:8080/" 2 | nodeport = 8080 3 | nodenetworkinterface = "0.0.0.0" 4 | clienturl = "http://load_balancer:8888/" 5 | clientport = 8888 6 | clientnetworkinterface = "0.0.0.0" 7 | publickeys = ["/var/keys/nodeKey.pub"] 8 | privatekeys = ["/var/keys/nodeKey.key"] 9 | passwords = "/var/keys/passwordFile" 10 | workdir = "/data" 11 | tls = "off" 12 | storage = "sql:jdbc:postgresql://postgres:5432/payloaddb" 13 | knownnodesstorage = "sql:jdbc:postgresql://postgres:5432/knownnodes" -------------------------------------------------------------------------------- /docker/ha/partyinfo.cbor: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Consensys/orion/0c000637da565f16fbc8632467933d55c9e6e401/docker/ha/partyinfo.cbor -------------------------------------------------------------------------------- /docker/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export GOSS_PATH=tests/goss-linux-amd64 4 | export GOSS_OPTS="$GOSS_OPTS --format junit" 5 | export GOSS_FILES_STRATEGY=cp 6 | DOCKER_IMAGE=$1 7 | DOCKER_FILE="${2:-$PWD/Dockerfile}" 8 | 9 | cleanup() { 10 | set +e 11 | echo "Cleaning temporary data directory" 12 | rm -rf "$tmp_dir" 13 | } 14 | 15 | i=0 16 | 17 | tmp_dir=$(mktemp -d /tmp/tmp.XXXXXXXXXX) 18 | chmod 777 "$tmp_dir" 19 | trap 'ret=$?;cleanup;exit $ret' EXIT 20 | echo "Temp Data Directory: ${tmp_dir}" 21 | ls $tmp_dir 22 | mkdir -p ./reports 23 | 24 | ## Generate public/private key pair 25 | # pipe password 123456 to orion 26 | yes 123456 | docker run -i --rm --mount type=bind,source=$tmp_dir,target=/data $DOCKER_IMAGE -g /data/nodeKey 27 | 28 | # Create password file 29 | cat << EOF > $tmp_dir/passwordFile 30 | 123456 31 | EOF 32 | 33 | ## Create orion configuration file 34 | cat << EOF > $tmp_dir/orion.conf 35 | nodeurl = "http://127.0.0.1:8080/" 36 | nodeport = 8080 37 | nodenetworkinterface = "0.0.0.0" 38 | clienturl = "http://127.0.0.1:8888/" 39 | clientport = 8888 40 | clientnetworkinterface = "0.0.0.0" 41 | publickeys = ["/data/nodeKey.pub"] 42 | privatekeys = ["/data/nodeKey.key"] 43 | passwords = "/data/passwordFile" 44 | workdir = "/data" 45 | tls = "off" 46 | EOF 47 | 48 | ls -l $tmp_dir/ 49 | 50 | # Test for normal startup with ports opened 51 | GOSS_FILES_PATH=tests/01 \ 52 | bash tests/dgoss run --mount type=bind,source=$tmp_dir,target=/data $DOCKER_IMAGE /data/orion.conf \ 53 | > ./reports/01.xml || i=`expr $i + 1` 54 | 55 | if [[ $i != 0 ]]; then exit $i; fi 56 | 57 | # Test for normal startup with clearing known hosts 58 | GOSS_FILES_PATH=tests/01 \ 59 | bash tests/dgoss run --mount type=bind,source=$tmp_dir,target=/data $DOCKER_IMAGE /data/orion.conf --clear-known-nodes \ 60 | > ./reports/01_clear.xml || i=`expr $i + 1` 61 | 62 | exit $i 63 | -------------------------------------------------------------------------------- /docker/test_ha.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set +x 3 | 4 | DOCKER_IMAGE=$1 5 | 6 | if [[ $# -eq 0 ]]; then 7 | echo "[ERROR] No Docker image parameter passed" 8 | echo "Usage: $0 " 9 | exit 1 10 | fi 11 | 12 | cd ha 13 | DOCKER_IMAGE="$DOCKER_IMAGE" docker-compose up -d 14 | i=0 15 | while [ $i -lt 10 ] 16 | do 17 | if [[ $(docker ps | grep healthy | wc -l) -eq 2 ]]; then 18 | break 19 | fi 20 | echo "Wait for 5s" 21 | sleep 5 22 | i=$((i+1)) 23 | done 24 | 25 | exit_code=0 26 | if [[ $i -lt 10 ]]; then 27 | echo "Orion started successfully." 28 | curl -s http://localhost:8080/upcheck 29 | exit_code=$((exit_code+$?)) 30 | 31 | peercount=$(curl http://localhost:8888/peercount) 32 | exit_code=$((exit_code+$?)) 33 | knownnodes=$(curl http://localhost:8888/knownnodes) 34 | exit_code=$((exit_code+$?)) 35 | echo "Peers: $peercount -- Known nodes: $knownnodes" 36 | 37 | curl -X POST http://localhost:8080/partyinfo -H "Content-Type: application/cbor" -d @partyinfo.cbor 38 | exit_code=$((exit_code+$?)) 39 | sleep 5 40 | 41 | peercount=$(curl http://localhost:8888/peercount) 42 | exit_code=$((exit_code+$?)) 43 | knownnodes=$(curl http://localhost:8888/knownnodes) 44 | exit_code=$((exit_code+$?)) 45 | echo "Peers: $peercount -- Known nodes: $knownnodes" 46 | 47 | if [[ $peercount -ne 2 ]]; then 48 | echo "Should have had 2 peers" 49 | exit_code=$((exit_code+1)) 50 | fi 51 | 52 | docker stop orion_2 53 | knownnodes_orion1=$(curl http://localhost:8888/knownnodes) 54 | exit_code=$((exit_code+$?)) 55 | docker start orion_2 56 | docker stop orion_1 57 | sleep 10 58 | 59 | knownnodes_orion2=$(curl http://localhost:8888/knownnodes) 60 | exit_code=$((exit_code+$?)) 61 | if [[ "$knownnodes_orion1" != "$knownnodes_orion2" ]]; then 62 | echo "Should have had the same known nodes, was:" 63 | echo $knownnodes_orion1 64 | echo $knownnodes_orion2 65 | exit_code=$((exit_code+1)) 66 | fi 67 | else 68 | echo "Orion failed to start successfully." 69 | exit_code=1 70 | fi 71 | DOCKER_IMAGE="$DOCKER_IMAGE" docker-compose down 72 | 73 | exit $exit_code -------------------------------------------------------------------------------- /docker/tests/01/goss.yaml: -------------------------------------------------------------------------------- 1 | file: 2 | /opt/orion/bin/orion: 3 | exists: true 4 | mode: "0755" 5 | owner: orion 6 | group: orion 7 | filetype: file 8 | contains: [] 9 | port: 10 | tcp:8080: 11 | listening: true 12 | ip: 13 | - 0.0.0.0 14 | tcp:8888: 15 | listening: true 16 | ip: 17 | - 0.0.0.0 18 | process: 19 | java: 20 | running: true 21 | -------------------------------------------------------------------------------- /docker/tests/01/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | port: 2 | tcp:8080: 3 | listening: true 4 | ip: 5 | - 0.0.0.0 6 | tcp:8888: 7 | listening: true 8 | ip: 9 | - 0.0.0.0 -------------------------------------------------------------------------------- /docker/tests/goss-linux-amd64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Consensys/orion/0c000637da565f16fbc8632467933d55c9e6e401/docker/tests/goss-linux-amd64 -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | Orion documentation was moved to as separate repository to help manage versions and releases. 2 | 3 | If you want to contribute to the doc site, make a pull request against https://github.com/PegaSysEng/doc.orion 4 | 5 | The generated doc website is at https://docs.orion.consensys.net/en/latest/ -------------------------------------------------------------------------------- /docs/community/code-reviews.md: -------------------------------------------------------------------------------- 1 | #Code review guidelines for Orion developers 2 | 3 | All changes must be code reviewed. For non-approvers this is obvious, since 4 | you can't commit anyway. But even for approvers, we want all changes to get at 5 | least one review, preferably (for non-trivial changes obligatorily) from someone 6 | who knows the areas the change touches. For non-trivial changes we may want two 7 | reviewers. The primary reviewer will make this decision and nominate a second 8 | reviewer, if needed. Except for trivial changes, PRs should not be committed 9 | until relevant parties (e.g. owners of the subsystem affected by the PR) have 10 | had a reasonable chance to look at PR in their local business hours. 11 | 12 | Most PRs will find reviewers organically. If an approver intends to be the 13 | primary reviewer of a PR they should set themselves as the assignee on GitHub 14 | and say so in a reply to the PR. Only the primary approver of a change should 15 | actually do the merge, except in rare cases (e.g. they are unavailable in a 16 | reasonable timeframe). 17 | 18 | If a PR has gone 2 work days without an approver emerging, please ask on [Discord](../README.md#chat). 19 | 20 | ## Attribution 21 | 22 | This Document was adapted by the following: 23 | - Kubernetes collab.md, available at [kub collab] 24 | 25 | [kub collab]: https://raw.githubusercontent.com/kubernetes/community/master/contributors/devel/collab.md -------------------------------------------------------------------------------- /docs/development/building.md: -------------------------------------------------------------------------------- 1 | # Check Out Code and Build it 2 | 3 | ## Pre-requisites 4 | 5 | [libsodium](https://docs.orion.consensys.net/en/latest/HowTo/Dependencies/) 6 | 7 | ## Check Out Source Code 8 | 9 | ``` 10 | git clone git@github.com:ConsenSys/orion.git 11 | ``` 12 | 13 | ## Build From Source 14 | Build the distribution binaries: 15 | ``` 16 | cd orion 17 | ./gradlew build 18 | ``` 19 | 20 | ## Run Tests 21 | These tasks are run as part of the default Gradle build but to run them separately: 22 | ``` 23 | ./gradlew test 24 | ./gradlew acceptanceTest 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/development/code-coverage.md: -------------------------------------------------------------------------------- 1 | ## Code coverage 2 | 3 | We use the jacoco test coverage plugin, which generates coverage data whenever tests are run. 4 | 5 | To run the report: 6 | ``` 7 | ./gradlew test jacocoTestReport 8 | ``` 9 | 10 | The report is available at `build/reports/jacoco/test/html/index.html` -------------------------------------------------------------------------------- /docs/development/docker.md: -------------------------------------------------------------------------------- 1 | # Docker 2 | 3 | There is a provided `Dockerfile` that can be used to build an image of Orion. 4 | 5 | To start the container, one needs to provide a volume with a set of keys and a configuration file. 6 | 7 | **Example:** 8 | 9 | **`orion.conf` configuration file:** 10 | ``` 11 | nodeurl = "http://127.0.0.1:8080/" 12 | nodeport = 8080 13 | clienturl = "http://127.0.0.1:8888/" 14 | clientport = 8888 15 | workdir = "/data" 16 | publickeys = ["orion.pub"] 17 | privatekeys = ["orion.key"] 18 | tls = "off" 19 | nodenetworkinterface = "0.0.0.0" 20 | clientnetworkinterface = "0.0.0.0" 21 | ``` 22 | 23 | **`data` folder:** 24 | ``` 25 | data 26 | |--- orion.conf 27 | |--- orion.pub 28 | |--- orion.key 29 | ``` 30 | (you need to use orion to generate the keys) 31 | 32 | **Building the image:** 33 | ``` 34 | $ docker build --force-rm -t orion . 35 | ``` 36 | (make sure that you have built the project with `./gradlew build` before building the image) 37 | 38 | **Starting the container:** 39 | ``` 40 | $ docker run -d -p 8080:8080 -v :/data orion 41 | ``` 42 | 43 | **To check that orion is up and running:** 44 | ``` 45 | $ curl -X GET http://localhost:8080/upcheck 46 | > I'm up! 47 | ``` -------------------------------------------------------------------------------- /docs/development/machine_setup.md: -------------------------------------------------------------------------------- 1 | # Working on Java on MacOS 2 | 3 | We use Java 11, Gradle for builds, and IntelliJ as an IDE. Feel free to use something else as your IDE if you are so 4 | inclined, but IntelliJ rocks. 5 | 6 | ## Install Java 11 on your mac 7 | 8 | ``` 9 | brew tap caskroom/versions 10 | brew cask install java11 11 | ``` 12 | 13 | According to the "brew way" that should work. 14 | 15 | But you might want to fall back to: 16 | ` 17 | brew install caskroom/versions/java11 18 | ` 19 | 20 | ## Install Gradle 21 | 22 | ` 23 | brew install gradle 24 | ` 25 | 26 | You'll also want to setup a JAVA_HOME so Gradle will play nicely and compile using Java 11. 27 | ``` 28 | export JAVA_HOME="$(/usr/libexec/java_home -v 11)" 29 | ``` 30 | 31 | ## Install IntelliJ community edition 32 | 33 | ` 34 | brew cask install intellij-idea-ce 35 | ` 36 | After doing this you are pretty close to ready. 37 | 38 | We'll just need to setup IntelliJ, then checkout Orion and get it working. 39 | 40 | * First startup IntelliJ, and then setup the default JDK: 41 | https://stackoverflow.com/a/31420120 42 | * Then (if you haven't done so already) outside of IntelliJ [checkout](building.md) Orion. Then open this folder in 43 | IntelliJ. 44 | * You'll be presented with an import project screen, and series of steps to complete. Set the 45 | path to Gradle will be something like: `/usr/local/Cellar/gradle/4.3.1/libexec/` 46 | (based on your brew config and setup). 47 | 48 | 49 | Once you've done this you should have an environment that is nicely setup for working with Orion. 50 | -------------------------------------------------------------------------------- /docs/development/oracle_jdbc.md: -------------------------------------------------------------------------------- 1 | # Oracle Maven Access 2 | * Orion bundles Oracle JDBC driver which is downloaded from Oracle Maven repository by Gradle. 3 | * You need to provide your Oracle account credentials to access Oracle Maven repository. 4 | If you don't have Oracle credentials, you can create one at 5 | https://profile.oracle.com/myprofile/account/create-account.jspx 6 | * Create (or update) `oracle.properties` in project root folder and add following properties 7 | ``` 8 | oracleMavenUser=YourOracleAccountEmail 9 | oracleMavenPassword=YourOracleAccountPassword 10 | ``` 11 | * Instead of modifying `oracle.properties`, following environment variables can also be used 12 | ``` 13 | ORG_GRADLE_PROJECT_oracleMavenUser 14 | ORG_GRADLE_PROJECT_oracleMavenPassword 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/development/running_developer_builds.md: -------------------------------------------------------------------------------- 1 | # Running Developer Builds 2 | 3 | Build and run Orion with default options using: 4 | 5 | ``` 6 | ./gradlew run 7 | ``` 8 | 9 | To add runtime options, use `-Pargs`. For example: 10 | 11 | ``` 12 | ./gradlew run -Pargs="-g my-key"` 13 | ``` -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | version=21.1.2-SNAPSHOT 2 | includeOptional=oracle.properties 3 | -------------------------------------------------------------------------------- /gradle/greclipse-gradle-consensys-style.properties: -------------------------------------------------------------------------------- 1 | #Whether to use 'space', 'tab' or 'mixed' (both) characters for indentation. 2 | #The default value is 'tab'. 3 | org.eclipse.jdt.core.formatter.tabulation.char=space 4 | 5 | #Number of spaces used for indentation in case 'space' characters 6 | #have been selected. The default value is 4. 7 | org.eclipse.jdt.core.formatter.tabulation.size=2 8 | 9 | #Number of spaces used for indentation in case 'mixed' characters 10 | #have been selected. The default value is 4. 11 | org.eclipse.jdt.core.formatter.indentation.size=1 12 | 13 | #Whether or not indentation characters are inserted into empty lines. 14 | #The default value is 'true'. 15 | org.eclipse.jdt.core.formatter.indent_empty_lines=false 16 | 17 | #Number of spaces used for multiline indentation. 18 | #The default value is 2. 19 | groovy.formatter.multiline.indentation=1 20 | 21 | #Length after which list are considered too long. These will be wrapped. 22 | #The default value is 30. 23 | groovy.formatter.longListLength=30 24 | 25 | #Whether opening braces position shall be the next line. 26 | #The default value is 'same'. 27 | groovy.formatter.braces.start=same 28 | 29 | #Whether closing braces position shall be the next line. 30 | #The default value is 'next'. 31 | groovy.formatter.braces.end=next 32 | 33 | #Remove unnecessary semicolons. The default value is 'false'. 34 | groovy.formatter.remove.unnecessary.semicolons=false 35 | 36 | org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line 37 | org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line 38 | org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line 39 | org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line 40 | org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line 41 | org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert 42 | org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line 43 | org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line 44 | org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line 45 | org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line 46 | org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert 47 | org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line 48 | org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line 49 | org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line 50 | 51 | org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert 52 | -------------------------------------------------------------------------------- /gradle/spotless.license.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright $YEAR ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | -------------------------------------------------------------------------------- /gradle/versions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | dependencyManagement { 15 | dependencies { 16 | dependency 'org.antlr:antlr4-runtime:4.7.1' 17 | 18 | dependency "com.google.errorprone:javac:9+181-r4173-1" 19 | 20 | dependency 'com.fasterxml.jackson.core:jackson-databind:2.10.0' 21 | dependency 'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.10.0' 22 | dependency 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.0' 23 | 24 | dependency 'com.github.jnr:jnr-ffi:2.1.8' 25 | 26 | dependency 'com.google.errorprone:error_prone_core:2.3.3' 27 | dependency 'com.google.guava:guava:27.0.1-jre' 28 | 29 | dependency 'com.h2database:h2:1.4.200' 30 | 31 | dependency 'com.jolbox:bonecp:0.8.0.RELEASE' 32 | 33 | dependency 'com.moandjiezana.toml:toml4j:0.7.2' 34 | 35 | dependency 'com.radcortez.gradle:openjpa-gradle-plugin:3.0.0' 36 | 37 | dependency 'com.squareup.okhttp3:mockwebserver:3.10.0' 38 | dependency 'com.squareup.okhttp3:okhttp:3.10.0' 39 | 40 | dependency 'com.oracle.ojdbc:ojdbc10:19.3.0.0' 41 | 42 | dependency 'io.gatling.highcharts:gatling-charts-highcharts:2.3.1' 43 | dependency 'io.gatling:gatling-app:2.3.1' 44 | dependency 'io.gatling:gatling-core:2.3.1' 45 | dependency 'io.gatling:gatling-http:2.3.1' 46 | 47 | dependency 'io.vertx:vertx-core:3.7.1' 48 | dependency 'io.vertx:vertx-web:3.7.1' 49 | dependency 'io.vertx:vertx-unit:3.7.1' 50 | dependency 'io.vertx:vertx-junit5:3.7.1' 51 | 52 | dependency 'javax.xml.bind:jaxb-api:2.3.0' 53 | 54 | dependencySet(group: 'org.apache.tuweni', version: '1.3.0') { 55 | entry 'bytes' 56 | entry 'concurrent' 57 | entry 'concurrent-coroutines' 58 | entry 'config' 59 | entry 'crypto' 60 | entry 'io' 61 | entry 'junit' 62 | entry 'kv' 63 | entry 'net' 64 | entry 'rlp' 65 | entry 'toml' 66 | } 67 | 68 | dependency 'org.apache.logging.log4j:log4j-api:2.11.2' 69 | dependency 'org.apache.logging.log4j:log4j-core:2.11.2' 70 | dependency 'org.apache.logging.log4j:log4j-slf4j-impl:2.11.2' 71 | 72 | dependency 'org.apache.openjpa:openjpa:3.1.0' 73 | 74 | dependency 'org.awaitility:awaitility:3.1.0' 75 | 76 | dependency 'org.bouncycastle:bcpkix-jdk15on:1.64' 77 | dependency 'org.bouncycastle:bcprov-jdk15on:1.64' 78 | 79 | dependency 'org.fusesource.leveldbjni:leveldbjni-all:1.8' 80 | 81 | dependency 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2' 82 | 83 | dependency 'org.junit.jupiter:junit-jupiter-api:5.5.2' 84 | dependency 'org.junit.jupiter:junit-jupiter-engine:5.5.2' 85 | dependency 'org.junit.jupiter:junit-jupiter-params:5.5.2' 86 | 87 | dependency 'org.mapdb:mapdb:3.0.7' 88 | dependency 'org.lz4:lz4-java:1.6.0' 89 | 90 | dependency 'org.postgresql:postgresql:42.2.6' 91 | 92 | dependency 'org.scala-lang:scala-library:2.12.6' 93 | 94 | dependency 'org.scalatest:scalatest_2.12:3.0.5' 95 | 96 | dependency 'org.mockito:mockito-all:1.10.19' 97 | 98 | dependency 'org.assertj:assertj-core:3.11.1' 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Consensys/orion/0c000637da565f16fbc8632467933d55c9e6e401/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /keys/password.txt: -------------------------------------------------------------------------------- 1 | yolo -------------------------------------------------------------------------------- /keys/tm1.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"Wl+xSyXVuuqzpvznOS7dOobhcn4C5auxkFRi7yLtgtA="},"type":"unlocked"} -------------------------------------------------------------------------------- /keys/tm1.pub: -------------------------------------------------------------------------------- 1 | BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo= -------------------------------------------------------------------------------- /keys/tm1a.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"wGEar7J9G0JAgdisp61ZChyrJWeW2QPyKvecjjeVHOY="},"type":"unlocked"} -------------------------------------------------------------------------------- /keys/tm1a.pub: -------------------------------------------------------------------------------- 1 | 8SjRHlUBe4hAmTk3KDeJ96RhN+s10xRrHDrxEi1O5W0= -------------------------------------------------------------------------------- /keys/unknown_type.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"Wl+xSyXVuuqzpvznOS7dOobhcn4C5auxkFRi7yLtgtA="},"type":"unknown"} 2 | -------------------------------------------------------------------------------- /pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # To enable this hook, create a symbolic link from this file to .git/hooks 4 | # ln -s $(pwd)/pre-commit .git/hooks/ 5 | 6 | set -e 7 | # Redirect output to stderr. 8 | exec 1>&2 9 | 10 | # do a spotlessCheck, don't apply automatically just now. 11 | exec ./gradlew spotlessCheck 12 | -------------------------------------------------------------------------------- /scripts/cloudsmith-upload.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | ORION_VERSION=${1:?Must specify orion version} 5 | TAR_DIST=${2:?Must specify path to tar distribution} 6 | ZIP_DIST=${3:?Must specify path to zip distribution} 7 | 8 | REPUBLISH="" 9 | if [[ $ORION_VERSION == *"develop"* ]]; then 10 | REPUBLISH="--republish" 11 | fi 12 | 13 | ENV_DIR=./build/tmp/cloudsmith-env 14 | if [[ -d ${ENV_DIR} ]] ; then 15 | source ${ENV_DIR}/bin/activate 16 | else 17 | python3 -m venv ${ENV_DIR} 18 | source ${ENV_DIR}/bin/activate 19 | fi 20 | 21 | python3 -m pip install --upgrade cloudsmith-cli 22 | 23 | if [ -z ${CLOUDSMITH_USER+x} ]; then echo "CLOUDSMITH_USER is unset"; else echo "CLOUDSMITH_USER is set to '$CLOUDSMITH_USER'"; fi 24 | 25 | cloudsmith push raw consensys/orion $TAR_DIST ${REPUBLISH} --name 'orion.tar.gz' --version "${ORION_VERSION}" --summary "Orion ${ORION_VERSION} binary distribution" --description "Binary distribution of Orion ${ORION_VERSION}." --content-type 'application/tar+gzip' 26 | cloudsmith push raw consensys/orion $ZIP_DIST ${REPUBLISH} --name 'orion.zip' --version "${ORION_VERSION}" --summary "Orion ${ORION_VERSION} binary distribution" --description "Binary distribution of Orion ${ORION_VERSION}." --content-type 'application/zip' 27 | 28 | echo "files uploaded to cloudsmith for version ${ORION_VERSION}" -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | rootProject.name = "orion" 15 | -------------------------------------------------------------------------------- /src/acceptance-test/java/net/consensys/orion/acceptance/dsl/AcceptanceTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.acceptance.dsl; 14 | 15 | 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | 19 | import com.google.common.collect.Lists; 20 | import org.awaitility.Awaitility; 21 | 22 | public class AcceptanceTestBase { 23 | 24 | private static final OrionFactory orionFactory = new OrionFactory(); 25 | 26 | public OrionFactory orionFactory() { 27 | return orionFactory; 28 | } 29 | 30 | public void waitForClientInterconnect(final int timeoutSeconds, final OrionNode... nodes) { 31 | final List nodeList = Lists.newArrayList(nodes); 32 | 33 | final int expectedKeyEndpoints = nodeList.size(); 34 | 35 | for (final OrionNode node : nodeList) { 36 | Awaitility.waitAtMost(timeoutSeconds, TimeUnit.SECONDS).until(() -> node.peerCount() == expectedKeyEndpoints); 37 | } 38 | } 39 | 40 | public void waitForClientInterconnect(final OrionNode... nodes) { 41 | waitForClientInterconnect(30, nodes); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/acceptance-test/java/net/consensys/orion/acceptance/dsl/KeyDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.acceptance.dsl; 14 | 15 | import java.nio.file.Path; 16 | 17 | import org.apache.tuweni.crypto.sodium.Box; 18 | import org.apache.tuweni.crypto.sodium.Box.KeyPair; 19 | 20 | public class KeyDefinition { 21 | 22 | final private Box.KeyPair keys; 23 | final private Path publicKeyPath; 24 | final private Path privateKeyPath; 25 | 26 | public KeyDefinition(final KeyPair keys, final Path publicKeyPath, final Path privateKeyPath) { 27 | this.keys = keys; 28 | this.publicKeyPath = publicKeyPath; 29 | this.privateKeyPath = privateKeyPath; 30 | } 31 | 32 | public KeyPair getKeys() { 33 | return keys; 34 | } 35 | 36 | public Path getPublicKeyPath() { 37 | return publicKeyPath; 38 | } 39 | 40 | public Path getPrivateKeyPath() { 41 | return privateKeyPath; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/acceptance-test/java/net/consensys/orion/acceptance/dsl/OrionConfigFileGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.acceptance.dsl; 14 | 15 | import java.io.File; 16 | import java.io.IOException; 17 | import java.nio.charset.StandardCharsets; 18 | import java.nio.file.Files; 19 | import java.nio.file.Path; 20 | import java.nio.file.StandardOpenOption; 21 | import java.util.List; 22 | import java.util.stream.Collectors; 23 | 24 | public class OrionConfigFileGenerator { 25 | 26 | private final List keys; 27 | private final String libSodiumPath; 28 | private final List bootnodeClientUrl; 29 | private final Path workPath; 30 | 31 | public static final String CONFIG_FILENAME = "config.toml"; 32 | public static final String networkInterface = "127.0.0.1"; 33 | public static final String URL_PATTERN = "http://" + networkInterface + ":%d"; 34 | 35 | public OrionConfigFileGenerator( 36 | final List keys, 37 | final String libSodiumPath, 38 | final List bootnodeClientUrl, 39 | final Path workPath) { 40 | this.keys = keys; 41 | this.libSodiumPath = libSodiumPath; 42 | this.bootnodeClientUrl = bootnodeClientUrl; 43 | this.workPath = workPath; 44 | } 45 | 46 | public Path generateConfigFile() throws IOException { 47 | final String pubKeys = keys.stream().map(k -> "\"" + k.getPublicKeyPath().getFileName().toString() + "\"").collect( 48 | Collectors.joining(",")); 49 | final String privKeys = 50 | keys.stream().map(k -> "\"" + k.getPrivateKeyPath().getFileName().toString() + "\"").collect( 51 | Collectors.joining(",")); 52 | 53 | final String otherNodes = bootnodeClientUrl.stream().map(k -> "\"" + k + "\"").collect(Collectors.joining(",")); 54 | 55 | // 0 means Vertx will find a suitable port. 56 | String configContent = "workdir = \"" + workPath.toString() + "\"\n"; 57 | configContent += "nodeUrl = \"" + String.format(URL_PATTERN, 0) + "\"\n"; 58 | configContent += "clientUrl = \"" + String.format(URL_PATTERN, 0) + "\"\n"; 59 | configContent += "nodenetworkinterface = \"" + networkInterface + "\"\n"; 60 | configContent += "clientnetworkinterface = \"" + networkInterface + "\"\n"; 61 | configContent += "libsodiumPath = \"" + libSodiumPath + "\"\n"; 62 | configContent += "nodeport = 0\n"; 63 | configContent += "clientport = 0\n"; 64 | 65 | configContent += "publickeys = [" + pubKeys + "]\n"; 66 | configContent += "privatekeys = [" + privKeys + "]\n"; 67 | configContent += "othernodes = [" + otherNodes + "]\n"; 68 | 69 | final File configFile = new File(workPath.toFile(), CONFIG_FILENAME); 70 | Files.write(configFile.toPath(), configContent.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE); 71 | 72 | return configFile.toPath(); 73 | } 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/acceptance-test/java/net/consensys/orion/acceptance/dsl/OrionFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.acceptance.dsl; 14 | 15 | import net.consensys.orion.config.Config; 16 | import net.consensys.orion.enclave.sodium.FileKeyStore; 17 | 18 | import java.io.IOException; 19 | import java.nio.file.Files; 20 | import java.nio.file.Path; 21 | import java.util.Collections; 22 | import java.util.List; 23 | import java.util.stream.Collectors; 24 | 25 | import com.google.common.collect.Lists; 26 | import org.apache.logging.log4j.LogManager; 27 | import org.apache.logging.log4j.Logger; 28 | import org.apache.tuweni.crypto.sodium.Box; 29 | 30 | public class OrionFactory { 31 | 32 | private static final Logger LOG = LogManager.getLogger(); 33 | 34 | private static final String libSodiumPath = "/usr/local/lib/libsodium.dylib"; 35 | 36 | 37 | public OrionNode create(final String nodeName, final int keyCount) throws IOException { 38 | return create(nodeName, keyCount, Collections.emptyList()); 39 | } 40 | 41 | public OrionNode create(final String nodeName, final int keyCount, final List bootnodes) 42 | throws IOException { 43 | final Path nodePath; 44 | try { 45 | nodePath = Files.createTempDirectory("orion"); 46 | } catch (final IOException e) { 47 | LOG.error("Failed to create tmpdir for orion instance."); 48 | throw e; 49 | } 50 | 51 | final List nodeKeys = generateKeys(keyCount, nodePath); 52 | 53 | final List bootnodeStrings = bootnodes.stream().map(OrionNode::nodeUrl).collect(Collectors.toList()); 54 | 55 | final OrionConfigFileGenerator fileGenerator = 56 | new OrionConfigFileGenerator(nodeKeys, libSodiumPath, bootnodeStrings, nodePath); 57 | final Path configFilePath = fileGenerator.generateConfigFile(); 58 | final OrionProcessRunner runner = new OrionProcessRunner(configFilePath); 59 | runner.start(nodeName); 60 | 61 | return new OrionNode( 62 | nodeKeys.stream().map(key -> key.getKeys().publicKey()).collect(Collectors.toList()), 63 | runner, 64 | bootnodes.size()); 65 | } 66 | 67 | private List generateKeys(final int keyCount, final Path nodePath) throws IOException { 68 | 69 | try { 70 | final FileKeyStore fileKeyStore = new FileKeyStore(Config.defaultConfig()); 71 | 72 | final List nodeKeys = Lists.newArrayList(); 73 | for (int i = 0; i < keyCount; i++) { 74 | final String keyFileName = String.format("key_%d", i); 75 | final Path rootPath = nodePath.resolve(keyFileName); 76 | final Box.PublicKey pubKey = fileKeyStore.generateKeyPair(rootPath, null); 77 | 78 | final KeyDefinition keys = new KeyDefinition( 79 | new Box.KeyPair(pubKey, fileKeyStore.privateKey(pubKey)), 80 | rootPath.resolveSibling(rootPath.getFileName() + ".pub"), 81 | rootPath.resolveSibling(rootPath.getFileName() + ".key")); 82 | nodeKeys.add(keys); 83 | } 84 | return nodeKeys; 85 | } catch (final IOException ex) { 86 | LOG.error("Failed to create filekeyStore"); 87 | throw ex; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/acceptance-test/resources/key1.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"hBsuQsGJzx4QHmFmBkNoI7YGnTmaZP4P+wBOdu56ljk="},"type":"unlocked"} -------------------------------------------------------------------------------- /src/acceptance-test/resources/key1.pub: -------------------------------------------------------------------------------- 1 | A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo= -------------------------------------------------------------------------------- /src/acceptance-test/resources/key2.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"wjeHURxQJUqZvhjMv+lxoRlXYnX/mpm0Iu/ldBr32Qs="},"type":"unlocked"} -------------------------------------------------------------------------------- /src/acceptance-test/resources/key2.pub: -------------------------------------------------------------------------------- 1 | Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs= -------------------------------------------------------------------------------- /src/acceptance-test/resources/key3.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"0SXAkYZio3b8BeDjZKsJY4sdqNqMT6Cnj2HWvuCYTOs="},"type":"unlocked"} -------------------------------------------------------------------------------- /src/acceptance-test/resources/key3.pub: -------------------------------------------------------------------------------- 1 | SANQhg9hXMn0xcbll6wFcE6ICPKZjsC8gHg8YpmG+m0= -------------------------------------------------------------------------------- /src/acceptance-test/resources/key4.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"SAZ1A1hxpzRd1nE2uk3FpypZ71spMLrAJySn+sMsRVA="},"type":"unlocked"} -------------------------------------------------------------------------------- /src/acceptance-test/resources/key4.pub: -------------------------------------------------------------------------------- 1 | LSHik/TRY49hCZ/CQjQHCvd8VZwJxTbX+9594mBK4nM= -------------------------------------------------------------------------------- /src/acceptance-test/resources/key5.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"ARM37QrChlQgS8lC1Fp+EtdGlSCpi0jldBG57B+Y3pY="},"type":"unlocked"} -------------------------------------------------------------------------------- /src/acceptance-test/resources/key5.pub: -------------------------------------------------------------------------------- 1 | FEPb+LDOZ3E+kxX2RnNqygG2QlNPaGX9xrhD16rSWwQ= -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/cmd/OrionArguments.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.cmd; 14 | 15 | 16 | import net.consensys.orion.utils.OrionInfo; 17 | 18 | import java.io.PrintStream; 19 | import java.util.Optional; 20 | 21 | class OrionArguments { 22 | 23 | private boolean argumentExit = false; 24 | private boolean clearKnownNodes = false; 25 | 26 | private Optional configFileName = Optional.empty(); 27 | private Optional keysToGenerate = Optional.empty(); 28 | 29 | OrionArguments(final PrintStream out, final PrintStream err, final String[] args) { 30 | 31 | boolean showUsage = false; 32 | // Process Arguments 33 | // Usage Orion [--generatekeys|-g names] [config] 34 | // names - comma separated list of key file prefixes (can include directory information) to 35 | // generate key(s) for 36 | for (int i = 0; i < args.length; i++) { 37 | switch (args[i]) { 38 | case "--generatekeys": 39 | case "-g": 40 | if (++i >= args.length) { 41 | err.println("Error: Missing key names to generate."); 42 | argumentExit = true; 43 | showUsage = true; 44 | break; 45 | } 46 | final String keys = args[i]; 47 | keysToGenerate = Optional.of(keys.split(",")); 48 | break; 49 | case "--help": 50 | case "-h": 51 | argumentExit = true; 52 | showUsage = true; 53 | break; 54 | case "--version": 55 | case "-v": 56 | displayVersion(out, err); 57 | argumentExit = true; 58 | break; 59 | case "--clear-known-nodes": 60 | clearKnownNodes = true; 61 | break; 62 | default: 63 | if (args[i].startsWith("-")) { 64 | err.printf("Invalid option: %s\n", args[i]); 65 | argumentExit = true; 66 | showUsage = true; 67 | } else { 68 | configFileName = Optional.of(args[i]); 69 | } 70 | } 71 | } 72 | 73 | if (showUsage) { 74 | displayHelp(out); 75 | } 76 | } 77 | 78 | private void displayHelp(final PrintStream out) { 79 | out.println("Usage: " + Orion.NAME + " [options] [config file]"); 80 | out.println("where options include:"); 81 | out.println("\t-g"); 82 | out.println("\t--generatekeys "); 83 | out.println("\t\tgenerate key pairs for each of the names supplied"); 84 | out.println("\t\twhere are a comma-separated list"); 85 | out.println("\t--clear-known-nodes\tclear known nodes information."); 86 | out.println("\t-h"); 87 | out.println("\t--help\tprint this help message"); 88 | out.println("\t-v"); 89 | out.println("\t--version\tprint version information"); 90 | } 91 | 92 | private void displayVersion(final PrintStream out, final PrintStream err) { 93 | try { 94 | out.println(OrionInfo.version()); 95 | } catch (final Exception e) { 96 | err.println("Error reading Orion version " + e.getMessage()); 97 | } 98 | } 99 | 100 | boolean argumentExit() { 101 | return argumentExit; 102 | } 103 | 104 | boolean clearKnownNodes() { 105 | return clearKnownNodes; 106 | } 107 | 108 | Optional configFileName() { 109 | return configFileName; 110 | } 111 | 112 | Optional keysToGenerate() { 113 | return keysToGenerate; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/cmd/OrionStartException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.cmd; 14 | 15 | class OrionStartException extends RuntimeException { 16 | 17 | OrionStartException(final String message) { 18 | super(message); 19 | } 20 | 21 | OrionStartException(final String message, final Throwable cause) { 22 | super(message, cause); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/cmd/PeerCountHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.cmd; 14 | 15 | import java.util.function.Supplier; 16 | 17 | import io.vertx.core.Handler; 18 | import io.vertx.ext.web.RoutingContext; 19 | 20 | // Responsible for reporting the number of connected peers: 21 | public class PeerCountHandler implements Handler { 22 | 23 | private final Supplier peerCountSupplier; 24 | 25 | public PeerCountHandler(final Supplier peerCountSupplier) { 26 | this.peerCountSupplier = peerCountSupplier; 27 | } 28 | 29 | @Override 30 | public void handle(final RoutingContext routingContext) { 31 | routingContext.response().end(this.peerCountSupplier.get().toString()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/config/ConfigException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.config; 14 | 15 | public class ConfigException extends RuntimeException { 16 | 17 | ConfigException(final String message) { 18 | super(message); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/Enclave.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave; 14 | 15 | import org.apache.tuweni.crypto.sodium.Box; 16 | 17 | public interface Enclave { 18 | 19 | /** 20 | * Encrypts the plaintext from the sender to the recipients. Creates the encrypted payload that encapsulates the 21 | * ciphertext and related keying data. 22 | * 23 | * @param plaintext Plaintext to encrypt 24 | * @param senderKey public key of the sender of the message. 25 | * @param recipients public keys of the recipients. 26 | * @param seed random seed to generate privacy group Id 27 | * @return Returns a EncryptedPayload that encapsulates the ciphertext and related metadata. 28 | */ 29 | EncryptedPayload encrypt(byte[] plaintext, Box.PublicKey senderKey, Box.PublicKey[] recipients, byte[] seed); 30 | 31 | /** 32 | * Decrypt the cipher text in the encrypted payload, using the private key associated with the public key identity. It 33 | * is the responsibility of the enclave to look up the private key, which may be stored securely. 34 | * 35 | * @param ciphertextAndMetadata EncryptedPayload containing the ciphertext and related metadata to decrypt. 36 | * @param identity PublicKey identity that wants to perform the decryption. Will be used to look up the private key to 37 | * perform the decryption. 38 | * @return return the decrypted byte array that is the data. 39 | */ 40 | byte[] decrypt(EncryptedPayload ciphertextAndMetadata, Box.PublicKey identity); 41 | 42 | Box.PublicKey[] alwaysSendTo(); 43 | 44 | Box.PublicKey[] nodeKeys(); 45 | 46 | Box.PublicKey readKey(String b64); 47 | 48 | byte[] generatePrivacyGroupId(Box.PublicKey[] recipientsAndSender, byte[] seed, PrivacyGroupPayload.Type type); 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/EnclaveException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave; 14 | 15 | import net.consensys.orion.exception.OrionErrorCode; 16 | import net.consensys.orion.exception.OrionException; 17 | 18 | public class EnclaveException extends OrionException { 19 | 20 | public EnclaveException(final OrionErrorCode code, final String message) { 21 | super(code, message); 22 | } 23 | 24 | public EnclaveException(final OrionErrorCode code, final Throwable cause) { 25 | super(code, cause); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/EncryptedKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave; 14 | 15 | import java.util.Arrays; 16 | 17 | import com.fasterxml.jackson.annotation.JsonCreator; 18 | import com.fasterxml.jackson.annotation.JsonProperty; 19 | 20 | public class EncryptedKey { 21 | 22 | private final byte[] encoded; 23 | 24 | @JsonCreator 25 | public EncryptedKey(@JsonProperty("encoded") final byte[] encoded) { 26 | this.encoded = encoded; 27 | } 28 | 29 | public byte[] getEncoded() { 30 | return encoded; 31 | } 32 | 33 | @Override 34 | public boolean equals(final Object o) { 35 | if (this == o) { 36 | return true; 37 | } 38 | if (o == null || getClass() != o.getClass()) { 39 | return false; 40 | } 41 | final EncryptedKey that = (EncryptedKey) o; 42 | return Arrays.equals(encoded, that.encoded); 43 | } 44 | 45 | @Override 46 | public int hashCode() { 47 | return Arrays.hashCode(encoded); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/KeyStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave; 14 | 15 | import javax.annotation.Nullable; 16 | 17 | import org.apache.tuweni.crypto.sodium.Box; 18 | 19 | /** 20 | * Interface for key put. Provides a mechanism for generating keys, and looking up a private key for a given public key. 21 | * Typically used internally by an enclave to look up private keys. 22 | */ 23 | public interface KeyStore { 24 | 25 | /** 26 | * Lookup the private key for a given public key. 27 | * 28 | * @param publicKey PublicKey to get the private key for. 29 | * @return Optional Return the public key. 30 | */ 31 | @Nullable 32 | Box.SecretKey privateKey(Box.PublicKey publicKey); 33 | 34 | Box.PublicKey[] alwaysSendTo(); 35 | 36 | Box.PublicKey[] nodeKeys(); 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/PrivacyGroupPayload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave; 14 | 15 | import java.io.Serializable; 16 | import java.util.Arrays; 17 | import java.util.Objects; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | 22 | public class PrivacyGroupPayload implements Serializable { 23 | 24 | private final String[] addresses; 25 | private final String name; 26 | private final String description; 27 | private State state; 28 | private final Type type; 29 | private final byte[] randomSeed; 30 | 31 | @JsonCreator 32 | public PrivacyGroupPayload( 33 | @JsonProperty("addresses") final String[] addresses, 34 | @JsonProperty("name") final String name, 35 | @JsonProperty("description") final String description, 36 | @JsonProperty("state") final State state, 37 | @JsonProperty("type") final Type type, 38 | @JsonProperty("randomSeed") final byte[] randomSeed) { 39 | this.addresses = addresses; 40 | this.name = name; 41 | this.description = description; 42 | this.state = state; 43 | this.type = type; 44 | this.randomSeed = randomSeed; 45 | } 46 | 47 | @JsonProperty("addresses") 48 | public String[] addresses() { 49 | return addresses; 50 | } 51 | 52 | @JsonProperty("name") 53 | public String name() { 54 | return name; 55 | } 56 | 57 | @JsonProperty("description") 58 | public String description() { 59 | return description; 60 | } 61 | 62 | @JsonProperty("state") 63 | public State state() { 64 | return state; 65 | } 66 | 67 | @JsonProperty("type") 68 | public Type type() { 69 | return type; 70 | } 71 | 72 | @JsonProperty("randomSeed") 73 | public byte[] randomSeed() { 74 | return randomSeed; 75 | } 76 | 77 | public void setState(final State state) { 78 | this.state = state; 79 | } 80 | 81 | @Override 82 | public boolean equals(final Object o) { 83 | if (this == o) { 84 | return true; 85 | } 86 | if (o == null || getClass() != o.getClass()) { 87 | return false; 88 | } 89 | final PrivacyGroupPayload that = (PrivacyGroupPayload) o; 90 | return Arrays.equals(addresses, that.addresses) 91 | && Objects.equals(name, that.name) 92 | && Objects.equals(description, that.description) 93 | && Objects.equals(state, that.state) 94 | && Objects.equals(type, that.type) 95 | && Arrays.equals(randomSeed, that.randomSeed); 96 | } 97 | 98 | @Override 99 | public int hashCode() { 100 | int result = Arrays.hashCode(addresses); 101 | result = 31 * result + name.hashCode(); 102 | result = 31 * result + description.hashCode(); 103 | result = 31 * result + state.hashCode(); 104 | result = 31 * result + type.hashCode(); 105 | result = 31 * result + Arrays.hashCode(randomSeed); 106 | return result; 107 | } 108 | 109 | public enum State { 110 | ACTIVE, DELETED 111 | } 112 | public enum Type { 113 | LEGACY, PANTHEON 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/QueryPrivacyGroupPayload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave; 14 | 15 | import java.io.Serializable; 16 | import java.util.Arrays; 17 | import java.util.List; 18 | import java.util.Objects; 19 | 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.fasterxml.jackson.annotation.JsonSetter; 23 | 24 | public class QueryPrivacyGroupPayload implements Serializable { 25 | 26 | private final String[] addresses; 27 | private final List privacyGroupId; 28 | private String privacyGroupToAppend = null; 29 | 30 | private boolean toDelete = false; 31 | 32 | @JsonCreator 33 | public QueryPrivacyGroupPayload( 34 | @JsonProperty("addresses") final String[] addresses, 35 | @JsonProperty("privacyGroupId") final List privacyGroupId) { 36 | this.addresses = addresses; 37 | this.privacyGroupId = privacyGroupId; 38 | } 39 | 40 | @JsonProperty("addresses") 41 | public String[] addresses() { 42 | return addresses; 43 | } 44 | 45 | @JsonProperty("privacyGroupId") 46 | public List privacyGroupId() { 47 | return privacyGroupId; 48 | } 49 | 50 | @JsonProperty("privacyGroupToAppend") 51 | public String privacyGroupToAppend() { 52 | return privacyGroupToAppend; 53 | } 54 | 55 | @JsonSetter("privacyGroupToAppend") 56 | public void setPrivacyGroupToAppend(String privacyGroupToAppend) { 57 | this.privacyGroupToAppend = privacyGroupToAppend; 58 | } 59 | 60 | 61 | public boolean isToDelete() { 62 | return toDelete; 63 | } 64 | 65 | public void setToDelete(final boolean toDelete) { 66 | this.toDelete = toDelete; 67 | } 68 | 69 | @Override 70 | public boolean equals(final Object o) { 71 | if (this == o) { 72 | return true; 73 | } 74 | if (o == null || getClass() != o.getClass()) { 75 | return false; 76 | } 77 | final QueryPrivacyGroupPayload that = (QueryPrivacyGroupPayload) o; 78 | return Arrays.equals(addresses, that.addresses) 79 | && Objects.equals(privacyGroupId, that.privacyGroupId) 80 | && Objects.equals(privacyGroupToAppend, that.privacyGroupToAppend); 81 | 82 | } 83 | 84 | @Override 85 | public int hashCode() { 86 | int result = Arrays.hashCode(addresses); 87 | result = 31 * result + privacyGroupId.hashCode(); 88 | result = 31 * result + privacyGroupToAppend.hashCode(); 89 | return result; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/sodium/MemoryKeyStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave.sodium; 14 | 15 | import net.consensys.orion.enclave.EnclaveException; 16 | import net.consensys.orion.enclave.KeyStore; 17 | import net.consensys.orion.exception.OrionErrorCode; 18 | 19 | import java.util.ArrayList; 20 | import java.util.HashMap; 21 | import java.util.List; 22 | import java.util.Map; 23 | import javax.annotation.Nullable; 24 | 25 | import org.apache.tuweni.crypto.sodium.Box; 26 | import org.apache.tuweni.crypto.sodium.Box.PublicKey; 27 | import org.apache.tuweni.crypto.sodium.SodiumException; 28 | 29 | public class MemoryKeyStore implements KeyStore { 30 | 31 | private final Map store = new HashMap<>(); 32 | private final List nodeKeys = new ArrayList<>(); 33 | 34 | @Override 35 | @Nullable 36 | public Box.SecretKey privateKey(final Box.PublicKey publicKey) { 37 | return store.get(publicKey); 38 | } 39 | 40 | /** 41 | * Generate and put a new keypair, returning the public key for external use. 42 | * 43 | * @return Return the public key part of the key pair. 44 | */ 45 | public PublicKey generateKeyPair() { 46 | try { 47 | final Box.KeyPair keyPair = Box.KeyPair.random(); 48 | final Box.PublicKey publicKey = keyPair.publicKey(); 49 | store.put(publicKey, keyPair.secretKey()); 50 | return publicKey; 51 | } catch (final SodiumException e) { 52 | throw new EnclaveException(OrionErrorCode.ENCLAVE_CREATE_KEY_PAIR, e); 53 | } 54 | } 55 | 56 | @Override 57 | public Box.PublicKey[] alwaysSendTo() { 58 | return new Box.PublicKey[0]; 59 | } 60 | 61 | public void addNodeKey(final Box.PublicKey key) { 62 | nodeKeys.add(key); 63 | } 64 | 65 | @Override 66 | public Box.PublicKey[] nodeKeys() { 67 | return nodeKeys.toArray(new Box.PublicKey[0]); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/sodium/serialization/PublicKeyDeserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave.sodium.serialization; 14 | 15 | import static org.apache.tuweni.io.Base64.decodeBytes; 16 | 17 | import java.io.IOException; 18 | 19 | import com.fasterxml.jackson.core.JsonParser; 20 | import com.fasterxml.jackson.databind.DeserializationContext; 21 | import com.fasterxml.jackson.databind.JsonDeserializer; 22 | import org.apache.tuweni.crypto.sodium.Box; 23 | 24 | public final class PublicKeyDeserializer extends JsonDeserializer { 25 | 26 | @Override 27 | public Box.PublicKey deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException { 28 | return Box.PublicKey.fromBytes(decodeBytes(p.getValueAsString())); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/sodium/serialization/PublicKeyMapKeyDeserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave.sodium.serialization; 14 | 15 | import static org.apache.tuweni.io.Base64.decode; 16 | 17 | import com.fasterxml.jackson.databind.DeserializationContext; 18 | import com.fasterxml.jackson.databind.KeyDeserializer; 19 | import org.apache.tuweni.bytes.Bytes; 20 | 21 | public final class PublicKeyMapKeyDeserializer extends KeyDeserializer { 22 | 23 | @Override 24 | public Bytes deserializeKey(final String key, final DeserializationContext ctxt) { 25 | return decode(key); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/sodium/serialization/PublicKeyMapKeySerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave.sodium.serialization; 14 | 15 | import static org.apache.tuweni.io.Base64.encodeBytes; 16 | 17 | import java.io.IOException; 18 | 19 | import com.fasterxml.jackson.core.JsonGenerator; 20 | import com.fasterxml.jackson.databind.JsonSerializer; 21 | import com.fasterxml.jackson.databind.SerializerProvider; 22 | import org.apache.tuweni.crypto.sodium.Box; 23 | import org.apache.tuweni.crypto.sodium.Box.PublicKey; 24 | 25 | public final class PublicKeyMapKeySerializer extends JsonSerializer { 26 | 27 | @Override 28 | public void serialize(final PublicKey key, final JsonGenerator gen, final SerializerProvider serializers) 29 | throws IOException { 30 | gen.writeFieldName(encodeBytes(key.bytesArray())); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/sodium/serialization/PublicKeySerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave.sodium.serialization; 14 | 15 | import static org.apache.tuweni.io.Base64.encodeBytes; 16 | 17 | import java.io.IOException; 18 | 19 | import com.fasterxml.jackson.core.JsonGenerator; 20 | import com.fasterxml.jackson.databind.JsonSerializer; 21 | import com.fasterxml.jackson.databind.SerializerProvider; 22 | import org.apache.tuweni.crypto.sodium.Box; 23 | import org.apache.tuweni.crypto.sodium.Box.PublicKey; 24 | 25 | public final class PublicKeySerializer extends JsonSerializer { 26 | 27 | @Override 28 | public void serialize(final PublicKey key, final JsonGenerator gen, final SerializerProvider serializers) 29 | throws IOException { 30 | gen.writeString(encodeBytes(key.bytesArray())); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/sodium/serialization/PublicKeyURISerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave.sodium.serialization; 14 | 15 | import static org.apache.tuweni.io.Base64.encode; 16 | 17 | import java.io.IOException; 18 | import java.net.URI; 19 | import java.util.Map; 20 | 21 | import com.fasterxml.jackson.core.JsonGenerator; 22 | import com.fasterxml.jackson.databind.JsonSerializer; 23 | import com.fasterxml.jackson.databind.SerializerProvider; 24 | import org.apache.tuweni.bytes.Bytes; 25 | 26 | public class PublicKeyURISerializer extends JsonSerializer>> { 27 | 28 | @Override 29 | public void serialize( 30 | final Iterable> entries, 31 | final JsonGenerator gen, 32 | final SerializerProvider serializers) throws IOException { 33 | gen.writeStartObject(); 34 | for (Map.Entry entry : entries) { 35 | gen.writeObjectField(encode(entry.getKey()), entry.getValue().toString()); 36 | } 37 | gen.writeEndObject(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/sodium/serialization/StoredPrivateKeyDeserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave.sodium.serialization; 14 | 15 | import net.consensys.orion.enclave.sodium.StoredPrivateKey; 16 | 17 | import java.io.IOException; 18 | 19 | import com.fasterxml.jackson.core.JsonParser; 20 | import com.fasterxml.jackson.databind.DeserializationContext; 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.fasterxml.jackson.databind.deser.std.StdDeserializer; 23 | 24 | public final class StoredPrivateKeyDeserializer extends StdDeserializer { 25 | 26 | public StoredPrivateKeyDeserializer() { 27 | this(null); 28 | } 29 | 30 | public StoredPrivateKeyDeserializer(final Class vc) { 31 | super(vc); 32 | } 33 | 34 | @Override 35 | public StoredPrivateKey deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException { 36 | final JsonNode rootNode = p.getCodec().readTree(p); 37 | final JsonNode typeNode = rootNode.get("type"); 38 | if (typeNode == null) { 39 | throw new IOException("Unknown stored key format (missing 'type')"); 40 | } 41 | final String type = typeNode.textValue(); 42 | final JsonNode dataNode = rootNode.get("data"); 43 | if (dataNode == null) { 44 | throw new IOException("Invalid stored key format (missing 'data')"); 45 | } 46 | final JsonNode bytesNode = dataNode.get("bytes"); 47 | if (bytesNode == null) { 48 | throw new IOException("Invalid stored key format (missing 'data.bytes')"); 49 | } 50 | final String encoded = bytesNode.textValue(); 51 | return new StoredPrivateKey(encoded, type); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/enclave/sodium/serialization/StoredPrivateKeySerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave.sodium.serialization; 14 | 15 | import net.consensys.orion.enclave.sodium.StoredPrivateKey; 16 | 17 | import java.io.IOException; 18 | 19 | import com.fasterxml.jackson.core.JsonGenerator; 20 | import com.fasterxml.jackson.databind.JsonSerializer; 21 | import com.fasterxml.jackson.databind.SerializerProvider; 22 | 23 | public final class StoredPrivateKeySerializer extends JsonSerializer { 24 | 25 | @Override 26 | public void serialize(final StoredPrivateKey key, final JsonGenerator gen, final SerializerProvider serializers) 27 | throws IOException { 28 | gen.writeStartObject(); 29 | gen.writeFieldName("data"); 30 | gen.writeStartObject(); 31 | gen.writeFieldName("bytes"); 32 | gen.writeString(key.encoded()); 33 | gen.writeEndObject(); 34 | gen.writeFieldName("type"); 35 | gen.writeString(key.type()); 36 | gen.writeEndObject(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/exception/OrionErrorCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.exception; 14 | 15 | import java.util.Optional; 16 | 17 | /** 18 | * The set of error conditions that can be expected as output from an Orion. 19 | * 20 | *

21 | * The error codes are granular, ideally with each code mapping to a single permutation of each error scenario. 22 | */ 23 | public enum OrionErrorCode { 24 | UNMAPPED("0x000000F"), 25 | 26 | /** Node communication issues. */ 27 | NODE_MISSING_PEER_URL("NodeMissingPeerUrl"), 28 | NODE_PUSHING_TO_PEER("NodePushingToPeer"), 29 | NODE_PROPAGATING_TO_ALL_PEERS("NodePropagatingToAllPeers"), 30 | NO_SENDER_KEY("NoSenderKey"), 31 | INVALID_PAYLOAD("InvalidPayload"), 32 | 33 | /** Object mapping issues. */ 34 | OBJECT_JSON_DESERIALIZATION("ObjectJsonDeserialization"), 35 | OBJECT_JSON_SERIALIZATION("ObjectJsonSerialization"), 36 | OBJECT_UNSUPPORTED_TYPE("ObjectUnsupportedType"), 37 | 38 | /** Enclave category of issues. */ 39 | ENCLAVE_CREATE_KEY_PAIR("EnclaveCreateKeyPair"), 40 | ENCLAVE_DECODE_PUBLIC_KEY("EnclaveDecodePublicKey"), 41 | ENCLAVE_DECRYPT_WRONG_PRIVATE_KEY("EnclaveDecryptWrongPrivateKey"), 42 | ENCLAVE_ENCRYPT_COMBINE_KEYS("EnclaveEncryptCombineKeys"), 43 | ENCLAVE_MISSING_PRIVATE_KEY_PASSWORD("EnclaveMissingPrivateKeyPasswords"), 44 | ENCLAVE_NO_MATCHING_PRIVATE_KEY("EnclaveNoMatchingPrivateKey"), 45 | ENCLAVE_NOT_PAYLOAD_OWNER("EnclaveNotPayloadOwner"), 46 | ENCLAVE_UNSUPPORTED_PRIVATE_KEY_TYPE("EnclaveUnsupportedPrivateKeyType"), 47 | ENCLAVE_STORAGE_DECRYPT("EnclaveStorageDecrypt"), 48 | ENCLAVE_PRIVACY_GROUP_CREATION("EnclavePrivacyGroupIdCreation"), 49 | ENCLAVE_PAYLOAD_NOT_FOUND("EnclavePayloadNotFound"), 50 | ENCLAVE_KEYS_CANNOT_DECRYPT_PAYLOAD("EnclaveKeysCannotDecryptPayload"), 51 | 52 | /** Storing privacy group issue */ 53 | ENCLAVE_UNABLE_STORE_PRIVACY_GROUP("PrivacyGroupNotStored"), 54 | ENCLAVE_UNABLE_DELETE_PRIVACY_GROUP("PrivacyGroupNotDeleted"), 55 | ENCLAVE_UNABLE_PUSH_DELETE_PRIVACY_GROUP("PrivacyGroupNotPushed"), 56 | ENCLAVE_PRIVACY_GROUP_MISSING("PrivacyGroupNotFound"), 57 | ENCLAVE_PRIVACY_QUERY_ERROR("PrivacyGroupQueryError"), 58 | METHOD_UNIMPLEMENTED("MethodUnimplemented"), 59 | CREATE_GROUP_INCLUDE_SELF("CreatePrivacyGroupShouldIncludeSelf"), 60 | CREATE_GROUP_INVALID_PARAMS("CreateGroupInvalidParams"); 61 | 62 | private final String code; 63 | 64 | OrionErrorCode(final String code) { 65 | this.code = code; 66 | } 67 | 68 | public String code() { 69 | return code; 70 | } 71 | 72 | public static Optional get(final String code) { 73 | 74 | for (final OrionErrorCode candidate : OrionErrorCode.values()) { 75 | if (candidate.code.equals(code)) { 76 | return Optional.of(candidate); 77 | } 78 | } 79 | 80 | return Optional.empty(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/exception/OrionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.exception; 14 | 15 | import javax.annotation.Nullable; 16 | 17 | import com.google.common.base.Objects; 18 | 19 | /** Base exception class encapsulating the Orion error codes. */ 20 | public class OrionException extends RuntimeException { 21 | 22 | private final OrionErrorCode code; 23 | 24 | public OrionException(final OrionErrorCode code) { 25 | this.code = code; 26 | } 27 | 28 | public OrionException(final OrionErrorCode code, final String message) { 29 | this(code, message, null); 30 | } 31 | 32 | public OrionException(final OrionErrorCode code, @Nullable final Throwable cause) { 33 | super(cause); 34 | this.code = code; 35 | } 36 | 37 | public OrionException(final OrionErrorCode code, final String message, @Nullable final Throwable cause) { 38 | super(message, cause); 39 | this.code = code; 40 | } 41 | 42 | public OrionErrorCode code() { 43 | return code; 44 | } 45 | 46 | @Override 47 | public boolean equals(final Object o) { 48 | if (this == o) { 49 | return true; 50 | } 51 | if (o == null || getClass() != o.getClass()) { 52 | return false; 53 | } 54 | final OrionException that = (OrionException) o; 55 | return Objects.equal(this.code, that.code); 56 | } 57 | 58 | @Override 59 | public int hashCode() { 60 | return Objects.hashCode(code); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/knownnodes/KnownNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.knownnodes; 14 | 15 | import java.net.URI; 16 | 17 | import com.fasterxml.jackson.annotation.JsonCreator; 18 | import com.fasterxml.jackson.annotation.JsonProperty; 19 | import com.google.common.base.Objects; 20 | import org.apache.tuweni.bytes.Bytes; 21 | import org.postgresql.util.Base64; 22 | 23 | class KnownNode { 24 | 25 | private final String publicKey; 26 | private final String nodeURI; 27 | 28 | KnownNode(final Bytes publicKey, final URI nodeURI) { 29 | this.publicKey = Base64.encodeBytes(publicKey.toArrayUnsafe()); 30 | this.nodeURI = nodeURI.toString(); 31 | } 32 | 33 | @JsonCreator 34 | KnownNode(@JsonProperty("publicKey") final String publicKey, final @JsonProperty("nodeUrl") String nodeURI) { 35 | this.publicKey = publicKey; 36 | this.nodeURI = nodeURI; 37 | } 38 | 39 | @JsonProperty("publicKey") 40 | String getPublicKey() { 41 | return publicKey; 42 | } 43 | 44 | @JsonProperty("nodeUrl") 45 | String getNodeURI() { 46 | return nodeURI; 47 | } 48 | 49 | @Override 50 | public boolean equals(final Object o) { 51 | if (this == o) { 52 | return true; 53 | } 54 | if (o == null || getClass() != o.getClass()) { 55 | return false; 56 | } 57 | final KnownNode knownNode = (KnownNode) o; 58 | return Objects.equal(publicKey, knownNode.publicKey) && Objects.equal(nodeURI, knownNode.nodeURI); 59 | } 60 | 61 | @Override 62 | public int hashCode() { 63 | return Objects.hashCode(publicKey, nodeURI); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/knownnodes/KnownNodesHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.knownnodes; 14 | 15 | import net.consensys.orion.http.server.HttpContentType; 16 | import net.consensys.orion.network.PersistentNetworkNodes; 17 | import net.consensys.orion.utils.Serializer; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | import io.vertx.core.Handler; 23 | import io.vertx.core.buffer.Buffer; 24 | import io.vertx.ext.web.RoutingContext; 25 | 26 | public class KnownNodesHandler implements Handler { 27 | 28 | private final PersistentNetworkNodes networkNodes; 29 | 30 | public KnownNodesHandler(final PersistentNetworkNodes networkNodes) { 31 | this.networkNodes = networkNodes; 32 | } 33 | 34 | @Override 35 | public void handle(final RoutingContext routingContext) { 36 | final List knownNodes = new ArrayList<>(); 37 | 38 | networkNodes.nodePKs().forEach((entry) -> { 39 | if (!entry.getValue().equals(networkNodes.uri())) { 40 | knownNodes.add(new KnownNode(entry.getKey(), entry.getValue())); 41 | } 42 | }); 43 | 44 | final Buffer bufferResponse = Buffer.buffer(Serializer.serialize(HttpContentType.JSON, knownNodes)); 45 | 46 | routingContext.response().end(bufferResponse); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/partyinfo/PartyInfoHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.partyinfo; 14 | 15 | import net.consensys.orion.http.server.HttpContentType; 16 | import net.consensys.orion.network.PersistentNetworkNodes; 17 | import net.consensys.orion.network.ReadOnlyNetworkNodes; 18 | import net.consensys.orion.utils.Serializer; 19 | 20 | import io.vertx.core.Handler; 21 | import io.vertx.core.buffer.Buffer; 22 | import io.vertx.ext.web.RoutingContext; 23 | 24 | /** 25 | * Used as a part of the network discovery process. Look up the binary list of constellation nodes that a node has 26 | * knowledge of. 27 | */ 28 | public class PartyInfoHandler implements Handler { 29 | private final PersistentNetworkNodes networkNodes; 30 | 31 | public PartyInfoHandler(final PersistentNetworkNodes networkNodes) { 32 | this.networkNodes = networkNodes; 33 | } 34 | 35 | @Override 36 | public void handle(final RoutingContext routingContext) { 37 | final ReadOnlyNetworkNodes callerPeers = 38 | Serializer.deserialize(HttpContentType.CBOR, ReadOnlyNetworkNodes.class, routingContext.getBody().getBytes()); 39 | final Buffer toReturn = Buffer.buffer(Serializer.serialize(HttpContentType.CBOR, networkNodes)); 40 | routingContext.response().end(toReturn); 41 | 42 | // merge callerPeers into our peers 43 | networkNodes.merge(callerPeers); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/privacy/DeletePrivacyGroupRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.privacy; 14 | 15 | import java.io.Serializable; 16 | 17 | import com.fasterxml.jackson.annotation.JsonCreator; 18 | import com.fasterxml.jackson.annotation.JsonProperty; 19 | 20 | public class DeletePrivacyGroupRequest implements Serializable { 21 | 22 | private final String privacyGroupId; 23 | private final String from; 24 | 25 | @JsonCreator 26 | public DeletePrivacyGroupRequest( 27 | @JsonProperty("privacyGroupId") final String privacyGroupId, 28 | @JsonProperty("from") final String from) { 29 | this.privacyGroupId = privacyGroupId; 30 | this.from = from; 31 | } 32 | 33 | @JsonProperty("privacyGroupId") 34 | public String privacyGroupId() { 35 | return privacyGroupId; 36 | } 37 | 38 | @JsonProperty("from") 39 | public String from() { 40 | return from; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/privacy/FindPrivacyGroupRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.privacy; 14 | 15 | import java.io.Serializable; 16 | 17 | import com.fasterxml.jackson.annotation.JsonCreator; 18 | import com.fasterxml.jackson.annotation.JsonProperty; 19 | 20 | public class FindPrivacyGroupRequest implements Serializable { 21 | 22 | private final String[] addresses; 23 | 24 | @JsonCreator 25 | public FindPrivacyGroupRequest(@JsonProperty("addresses") final String[] addresses) { 26 | this.addresses = addresses; 27 | } 28 | 29 | @JsonProperty("addresses") 30 | public String[] addresses() { 31 | return addresses; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/privacy/PrivacyGroup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.privacy; 14 | 15 | import net.consensys.orion.enclave.PrivacyGroupPayload; 16 | 17 | import java.io.Serializable; 18 | import java.util.Arrays; 19 | 20 | public class PrivacyGroup implements Serializable { 21 | 22 | private String privacyGroupId; 23 | private String name; 24 | private String description; 25 | private PrivacyGroupPayload.Type type; 26 | private String[] members; 27 | 28 | public String getPrivacyGroupId() { 29 | return privacyGroupId; 30 | } 31 | 32 | public void setPrivacyGroupId(final String privacyGroupId) { 33 | this.privacyGroupId = privacyGroupId; 34 | } 35 | 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | public void setName(final String name) { 41 | this.name = name; 42 | } 43 | 44 | public String getDescription() { 45 | return description; 46 | } 47 | 48 | public void setDescription(final String description) { 49 | this.description = description; 50 | } 51 | 52 | public PrivacyGroupPayload.Type getType() { 53 | return type; 54 | } 55 | 56 | public void setType(final PrivacyGroupPayload.Type type) { 57 | this.type = type; 58 | } 59 | 60 | public String[] getMembers() { 61 | return members; 62 | } 63 | 64 | public void setMembers(final String[] members) { 65 | this.members = members; 66 | } 67 | 68 | public PrivacyGroup() {} 69 | 70 | 71 | 72 | public PrivacyGroup( 73 | final String privacyGroupId, 74 | final PrivacyGroupPayload.Type type, 75 | final String name, 76 | final String description, 77 | final String[] members) { 78 | this.privacyGroupId = privacyGroupId; 79 | this.type = type; 80 | this.name = name; 81 | this.description = description; 82 | this.members = members; 83 | } 84 | 85 | @Override 86 | public String toString() { 87 | return "PrivacyGroup{" 88 | + "privacyGroupId='" 89 | + privacyGroupId 90 | + '\'' 91 | + ", name='" 92 | + name 93 | + '\'' 94 | + ", description='" 95 | + description 96 | + '\'' 97 | + ", type=" 98 | + type 99 | + ", members=" 100 | + Arrays.toString(members) 101 | + '}'; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/privacy/PrivacyGroupRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.privacy; 14 | 15 | import java.io.Serializable; 16 | import java.util.Optional; 17 | 18 | import com.fasterxml.jackson.annotation.JsonCreator; 19 | import com.fasterxml.jackson.annotation.JsonProperty; 20 | import com.fasterxml.jackson.annotation.JsonSetter; 21 | 22 | public class PrivacyGroupRequest implements Serializable { 23 | 24 | private final String[] addresses; 25 | private final String from; // b64 encoded 26 | private final String name; 27 | private final String description; 28 | 29 | private byte[] seed; 30 | 31 | @JsonCreator 32 | public PrivacyGroupRequest( 33 | @JsonProperty("addresses") final String[] addresses, 34 | @JsonProperty("from") final String from, 35 | @JsonProperty("name") final String name, 36 | @JsonProperty("description") final String description) { 37 | this.addresses = addresses; 38 | this.from = from; 39 | this.name = name; 40 | this.description = description; 41 | } 42 | 43 | @JsonSetter 44 | public void setSeed(final byte[] seed) { 45 | this.seed = seed; 46 | } 47 | 48 | @JsonProperty("addresses") 49 | public String[] addresses() { 50 | return addresses; 51 | } 52 | 53 | @JsonProperty("name") 54 | public String name() { 55 | return name; 56 | } 57 | 58 | @JsonProperty("description") 59 | public String description() { 60 | return description; 61 | } 62 | 63 | @JsonProperty("from") 64 | public String from() { 65 | return from; 66 | } 67 | 68 | public Optional getSeed() { 69 | return Optional.ofNullable(seed); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/privacy/RetrievePrivacyGroupHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.privacy; 14 | 15 | import static net.consensys.orion.http.server.HttpContentType.JSON; 16 | 17 | import net.consensys.orion.enclave.PrivacyGroupPayload; 18 | import net.consensys.orion.enclave.PrivacyGroupPayload.State; 19 | import net.consensys.orion.exception.OrionErrorCode; 20 | import net.consensys.orion.exception.OrionException; 21 | import net.consensys.orion.storage.Storage; 22 | import net.consensys.orion.utils.Serializer; 23 | 24 | import io.vertx.core.Handler; 25 | import io.vertx.core.buffer.Buffer; 26 | import io.vertx.ext.web.RoutingContext; 27 | import org.apache.logging.log4j.LogManager; 28 | import org.apache.logging.log4j.Logger; 29 | 30 | /** 31 | * Retrieves a privacy group given the privacyGroupId. 32 | */ 33 | public class RetrievePrivacyGroupHandler implements Handler { 34 | 35 | private static final Logger log = LogManager.getLogger(); 36 | 37 | private final Storage privacyGroupStorage; 38 | 39 | public RetrievePrivacyGroupHandler(final Storage privacyGroupStorage) { 40 | this.privacyGroupStorage = privacyGroupStorage; 41 | } 42 | 43 | @Override 44 | @SuppressWarnings("rawtypes") 45 | public void handle(final RoutingContext routingContext) { 46 | final byte[] request = routingContext.getBody().getBytes(); 47 | final RetrievePrivacyGroupRequest retrievePrivacyGroupRequest = 48 | Serializer.deserialize(JSON, RetrievePrivacyGroupRequest.class, request); 49 | 50 | final String privacyGroupId = retrievePrivacyGroupRequest.privacyGroupId(); 51 | 52 | if (privacyGroupId == null) { 53 | routingContext.fail(400); 54 | } else { 55 | handleRequest(routingContext, privacyGroupId); 56 | } 57 | } 58 | 59 | private void handleRequest(final RoutingContext routingContext, final String privacyGroupId) { 60 | privacyGroupStorage.get(privacyGroupId).thenAccept((result) -> { 61 | if (result.isPresent()) { 62 | final PrivacyGroupPayload privacyGroupPayload = result.get(); 63 | log.info("Found privacy group {}", privacyGroupId); 64 | if (privacyGroupPayload.state().equals(State.ACTIVE)) { 65 | responseWithPrivacyGroup(routingContext, privacyGroupId, privacyGroupPayload); 66 | } else { 67 | responseWithNotFoundError(routingContext); 68 | } 69 | } else { 70 | responseWithNotFoundError(routingContext); 71 | } 72 | }); 73 | } 74 | 75 | private void responseWithPrivacyGroup( 76 | final RoutingContext routingContext, 77 | final String privacyGroupId, 78 | final PrivacyGroupPayload privacyGroupPayload) { 79 | final PrivacyGroup response = new PrivacyGroup( 80 | privacyGroupId, 81 | privacyGroupPayload.type(), 82 | privacyGroupPayload.name(), 83 | privacyGroupPayload.description(), 84 | privacyGroupPayload.addresses()); 85 | routingContext.response().end(Buffer.buffer(Serializer.serialize(JSON, response))); 86 | } 87 | 88 | private void responseWithNotFoundError(final RoutingContext routingContext) { 89 | routingContext.fail(404, new OrionException(OrionErrorCode.ENCLAVE_PRIVACY_GROUP_MISSING)); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/privacy/RetrievePrivacyGroupRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.privacy; 14 | 15 | import java.io.Serializable; 16 | 17 | import com.fasterxml.jackson.annotation.JsonCreator; 18 | import com.fasterxml.jackson.annotation.JsonProperty; 19 | 20 | public class RetrievePrivacyGroupRequest implements Serializable { 21 | 22 | private final String privacyGroupId; 23 | 24 | @JsonCreator 25 | public RetrievePrivacyGroupRequest(@JsonProperty("privacyGroupId") final String privacyGroupId) { 26 | this.privacyGroupId = privacyGroupId; 27 | } 28 | 29 | @JsonProperty("privacyGroupId") 30 | public String privacyGroupId() { 31 | return privacyGroupId; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/push/PushHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.push; 14 | 15 | import net.consensys.orion.enclave.EncryptedPayload; 16 | import net.consensys.orion.http.server.HttpContentType; 17 | import net.consensys.orion.storage.Storage; 18 | import net.consensys.orion.utils.Serializer; 19 | 20 | import io.vertx.core.Handler; 21 | import io.vertx.ext.web.RoutingContext; 22 | import org.apache.logging.log4j.LogManager; 23 | import org.apache.logging.log4j.Logger; 24 | 25 | /** used to push a payload to a node. */ 26 | public class PushHandler implements Handler { 27 | private static final Logger log = LogManager.getLogger(); 28 | private final Storage storage; 29 | 30 | public PushHandler(final Storage storage) { 31 | this.storage = storage; 32 | } 33 | 34 | @Override 35 | public void handle(final RoutingContext routingContext) { 36 | final EncryptedPayload pushRequest = 37 | Serializer.deserialize(HttpContentType.CBOR, EncryptedPayload.class, routingContext.getBody().getBytes()); 38 | 39 | storage.put(pushRequest).thenAccept((digest) -> { 40 | log.debug("stored payload. resulting digest: {}", digest); 41 | routingContext.response().end(digest); 42 | }).exceptionally(e -> routingContext.fail(e)); 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/push/PushPrivacyGroupHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.push; 14 | 15 | import net.consensys.orion.enclave.PrivacyGroupPayload; 16 | import net.consensys.orion.enclave.QueryPrivacyGroupPayload; 17 | import net.consensys.orion.http.server.HttpContentType; 18 | import net.consensys.orion.storage.Storage; 19 | import net.consensys.orion.utils.Serializer; 20 | 21 | import io.vertx.core.Handler; 22 | import io.vertx.ext.web.RoutingContext; 23 | import org.apache.logging.log4j.LogManager; 24 | import org.apache.logging.log4j.Logger; 25 | 26 | /** used to push a privacy group to a node. */ 27 | public class PushPrivacyGroupHandler implements Handler { 28 | private static final Logger log = LogManager.getLogger(); 29 | private final Storage storage; 30 | private final Storage queryPrivacyGroupStorage; 31 | 32 | public PushPrivacyGroupHandler( 33 | final Storage storage, 34 | final Storage queryPrivacyGroupStorage) { 35 | this.storage = storage; 36 | this.queryPrivacyGroupStorage = queryPrivacyGroupStorage; 37 | } 38 | 39 | @Override 40 | public void handle(final RoutingContext routingContext) { 41 | final PrivacyGroupPayload pushRequest = 42 | Serializer.deserialize(HttpContentType.CBOR, PrivacyGroupPayload.class, routingContext.getBody().getBytes()); 43 | 44 | storage.put(pushRequest).thenAccept((digest) -> { 45 | final QueryPrivacyGroupPayload queryPrivacyGroupPayload = 46 | new QueryPrivacyGroupPayload(pushRequest.addresses(), null); 47 | if (pushRequest.state().equals(PrivacyGroupPayload.State.DELETED)) { 48 | queryPrivacyGroupPayload.setToDelete(true); 49 | } 50 | queryPrivacyGroupPayload.setPrivacyGroupToAppend(storage.generateDigest(pushRequest)); 51 | final String key = queryPrivacyGroupStorage.generateDigest(queryPrivacyGroupPayload); 52 | queryPrivacyGroupStorage.update(key, queryPrivacyGroupPayload).thenApply((res) -> { 53 | log.info("Stored privacy group. resulting digest: {}", digest); 54 | routingContext.response().end(digest); 55 | return null; 56 | }).exceptionally(e -> { 57 | routingContext.fail(e); 58 | return null; 59 | }); 60 | 61 | }).exceptionally(routingContext::fail); 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/receive/ReceiveRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.receive; 14 | 15 | import java.io.Serializable; 16 | import java.util.Objects; 17 | 18 | import com.fasterxml.jackson.annotation.JsonCreator; 19 | import com.fasterxml.jackson.annotation.JsonProperty; 20 | 21 | public class ReceiveRequest implements Serializable { 22 | public final String key; 23 | public final String to; // b64 encoded 24 | 25 | @JsonCreator 26 | public ReceiveRequest(@JsonProperty("key") final String key, @JsonProperty("to") final String to) { 27 | this.key = key; 28 | this.to = to; 29 | } 30 | 31 | @Override 32 | public boolean equals(final Object o) { 33 | if (this == o) { 34 | return true; 35 | } 36 | if (!(o instanceof ReceiveRequest)) { 37 | return false; 38 | } 39 | final ReceiveRequest that = (ReceiveRequest) o; 40 | return Objects.equals(key, that.key) && Objects.equals(to, that.to); 41 | } 42 | 43 | @Override 44 | public int hashCode() { 45 | return Objects.hash(key, to); 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return "ReceiveRequest{" + "key='" + key + '\'' + ", to='" + to + '\'' + '}'; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/receive/ReceiveResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.receive; 14 | 15 | import java.io.Serializable; 16 | 17 | public class ReceiveResponse implements Serializable { 18 | byte[] payload; 19 | byte[] privacyGroupId; 20 | byte[] senderKey; 21 | 22 | public ReceiveResponse() {} 23 | 24 | public ReceiveResponse(final byte[] payload, final byte[] privacyGroupId, final byte[] senderKey) { 25 | this.payload = payload; 26 | this.privacyGroupId = privacyGroupId; 27 | this.senderKey = senderKey; 28 | } 29 | 30 | public byte[] getPayload() { 31 | return payload; 32 | } 33 | 34 | public void setPayload(final byte[] payload) { 35 | this.payload = payload; 36 | } 37 | 38 | public byte[] getPrivacyGroupId() { 39 | return privacyGroupId; 40 | } 41 | 42 | public void setPrivacyGroupId(final byte[] privacyGroupId) { 43 | this.privacyGroupId = privacyGroupId; 44 | } 45 | 46 | public byte[] getSenderKey() { 47 | return senderKey; 48 | } 49 | 50 | public void setSenderKey(final byte[] senderKey) { 51 | this.senderKey = senderKey; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/send/SendHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.send; 14 | 15 | import static net.consensys.orion.http.server.HttpContentType.JSON; 16 | 17 | import net.consensys.orion.exception.OrionErrorCode; 18 | import net.consensys.orion.exception.OrionException; 19 | import net.consensys.orion.payload.DistributePayloadManager; 20 | import net.consensys.orion.utils.Serializer; 21 | 22 | import io.vertx.core.Handler; 23 | import io.vertx.core.json.Json; 24 | import io.vertx.ext.web.RoutingContext; 25 | 26 | public class SendHandler implements Handler { 27 | 28 | private final DistributePayloadManager distributePayloadManager; 29 | 30 | public SendHandler(final DistributePayloadManager distributePayloadManager) { 31 | this.distributePayloadManager = distributePayloadManager; 32 | } 33 | 34 | @Override 35 | public void handle(final RoutingContext routingContext) { 36 | final SendRequest sendRequest = parseRequest(routingContext); 37 | 38 | distributePayloadManager.processSendRequest(sendRequest, res -> { 39 | if (res.succeeded()) { 40 | routingContext.response().end(Json.encodeToBuffer(res.result())); 41 | } else { 42 | routingContext.fail(res.cause()); 43 | } 44 | }); 45 | } 46 | 47 | private SendRequest parseRequest(final RoutingContext routingContext) { 48 | final SendRequest sendRequest = 49 | Serializer.deserialize(JSON, SendRequest.class, routingContext.getBody().getBytes()); 50 | 51 | if (!sendRequest.isValid()) { 52 | throw new OrionException(OrionErrorCode.INVALID_PAYLOAD); 53 | } 54 | 55 | return sendRequest; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/send/SendResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.send; 14 | 15 | public class SendResponse { 16 | 17 | private final String key; 18 | 19 | public SendResponse(String key) { 20 | this.key = key; 21 | } 22 | 23 | public String getKey() { 24 | return key; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/sendraw/SendRawHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.sendraw; 14 | 15 | import net.consensys.orion.exception.OrionErrorCode; 16 | import net.consensys.orion.exception.OrionException; 17 | import net.consensys.orion.http.handler.send.SendRequest; 18 | import net.consensys.orion.payload.DistributePayloadManager; 19 | 20 | import io.vertx.core.Handler; 21 | import io.vertx.ext.web.RoutingContext; 22 | 23 | public class SendRawHandler implements Handler { 24 | 25 | private final DistributePayloadManager distributePayloadManager; 26 | 27 | public SendRawHandler(final DistributePayloadManager distributePayloadManager) { 28 | this.distributePayloadManager = distributePayloadManager; 29 | } 30 | 31 | @Override 32 | public void handle(final RoutingContext routingContext) { 33 | final SendRequest sendRequest = parseRequest(routingContext); 34 | 35 | distributePayloadManager.processSendRequest(sendRequest, res -> { 36 | if (res.succeeded()) { 37 | routingContext.response().end(res.result().getKey()); 38 | } else { 39 | routingContext.fail(res.cause()); 40 | } 41 | }); 42 | } 43 | 44 | private SendRequest parseRequest(final RoutingContext routingContext) { 45 | final String from = routingContext.request().getHeader("c11n-from"); 46 | final String toList = routingContext.request().getHeader("c11n-to"); 47 | final String[] to = toList != null ? toList.split(",") : new String[0]; 48 | 49 | final SendRequest sendRequest = new SendRequest(routingContext.getBody().getBytes(), from, to); 50 | 51 | if (!sendRequest.isValid()) { 52 | throw new OrionException(OrionErrorCode.INVALID_PAYLOAD); 53 | } 54 | 55 | return sendRequest; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/upcheck/UpcheckHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.upcheck; 14 | 15 | import io.vertx.core.Handler; 16 | import io.vertx.ext.web.RoutingContext; 17 | 18 | /** 19 | * Simple upcheck/hello check to see if the server is up and running. Returns a 200 response with the body "I'm up!" 20 | */ 21 | public class UpcheckHandler implements Handler { 22 | 23 | @Override 24 | public void handle(final RoutingContext routingContext) { 25 | routingContext.response().end("I'm up!"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/handler/version/VersionHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler.version; 14 | 15 | import net.consensys.orion.utils.OrionInfo; 16 | 17 | import io.vertx.core.Handler; 18 | import io.vertx.ext.web.RoutingContext; 19 | 20 | public class VersionHandler implements Handler { 21 | 22 | @Override 23 | public void handle(final RoutingContext routingContext) { 24 | try { 25 | routingContext.response().setStatusCode(200).end(OrionInfo.version()); 26 | } catch (Exception e) { 27 | routingContext.response().setStatusCode(500).end("Error retrieving Orion version"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/server/HttpContentType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.server; 14 | 15 | import io.netty.handler.codec.http.HttpHeaderValues; 16 | 17 | public enum HttpContentType { 18 | JSON(HttpHeaderValues.APPLICATION_JSON.toString()), 19 | APPLICATION_OCTET_STREAM(HttpHeaderValues.APPLICATION_OCTET_STREAM.toString()), 20 | TEXT(HttpHeaderValues.TEXT_PLAIN.toString() + "; charset=utf-8"), 21 | CBOR("application/cbor"), 22 | ORION("application/vnd.orion.v1+json"); 23 | 24 | public final String httpHeaderValue; 25 | 26 | HttpContentType(final String httpHeaderValue) { 27 | this.httpHeaderValue = httpHeaderValue; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return httpHeaderValue; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/server/HttpError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.server; 14 | 15 | import net.consensys.orion.exception.OrionErrorCode; 16 | 17 | import java.util.Objects; 18 | 19 | import com.fasterxml.jackson.annotation.JsonProperty; 20 | 21 | public class HttpError { 22 | 23 | private final OrionErrorCode error; 24 | 25 | public HttpError(final OrionErrorCode error) { 26 | this.error = error; 27 | } 28 | 29 | @Override 30 | public boolean equals(final Object o) { 31 | if (this == o) { 32 | return true; 33 | } 34 | if (o == null || getClass() != o.getClass()) { 35 | return false; 36 | } 37 | final HttpError httpError = (HttpError) o; 38 | return Objects.equals(error, httpError.error); 39 | } 40 | 41 | @Override 42 | public int hashCode() { 43 | return Objects.hash(error); 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "HttpError{" + "error='" + error.code() + '\'' + '}'; 49 | } 50 | 51 | @JsonProperty("error") 52 | public String error() { 53 | return error.code(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/server/vertx/HttpErrorHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.server.vertx; 14 | 15 | import net.consensys.orion.exception.OrionErrorCode; 16 | import net.consensys.orion.exception.OrionException; 17 | import net.consensys.orion.http.server.HttpContentType; 18 | import net.consensys.orion.http.server.HttpError; 19 | import net.consensys.orion.utils.Serializer; 20 | 21 | import io.netty.handler.codec.http.HttpResponseStatus; 22 | import io.vertx.core.Handler; 23 | import io.vertx.core.buffer.Buffer; 24 | import io.vertx.core.http.HttpHeaders; 25 | import io.vertx.core.http.HttpServerResponse; 26 | import io.vertx.ext.web.RoutingContext; 27 | import org.apache.logging.log4j.LogManager; 28 | import org.apache.logging.log4j.Logger; 29 | 30 | public class HttpErrorHandler implements Handler { 31 | private static final Logger log = LogManager.getLogger(); 32 | 33 | public HttpErrorHandler() {} 34 | 35 | @Override 36 | public void handle(final RoutingContext failureContext) { 37 | final int statusCode = statusCode(failureContext); 38 | final HttpServerResponse response = failureContext.response().setStatusCode(statusCode); 39 | 40 | if (hasError(failureContext)) { 41 | final Buffer buffer = errorJson(failureContext); 42 | response.putHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.JSON.httpHeaderValue).end(buffer); 43 | } else { 44 | response.end(); 45 | } 46 | } 47 | 48 | private Buffer errorJson(final RoutingContext failureContext) { 49 | final OrionErrorCode orionError = orionError(failureContext.failure()); 50 | final HttpError httpError = new HttpError(orionError); 51 | final Buffer buffer = Buffer.buffer(Serializer.serialize(HttpContentType.JSON, httpError)); 52 | 53 | if (failureContext.statusCode() == 404) { 54 | // To reduce noise 404s are only logged as debug. A 404 is returned for the common use case where Besu receives a 55 | // private marker transaction for a privacy group that this Orion is not part of. 56 | log.debug("Not Found Error: \"" + orionError + "\" Body: \"" + failureContext.getBodyAsString() + "\""); 57 | } else { 58 | log.error(failureContext.currentRoute().getPath() + " failed " + httpError, failureContext.failure()); 59 | } 60 | return buffer; 61 | } 62 | 63 | /** 64 | * Status code may not have been set (left as a negative number), in which case assume server side issue. 65 | */ 66 | private int statusCode(final RoutingContext failureContext) { 67 | return failureContext.statusCode() < 0 ? HttpResponseStatus.INTERNAL_SERVER_ERROR.code() 68 | : failureContext.statusCode(); 69 | } 70 | 71 | private boolean hasError(final RoutingContext failureContext) { 72 | return failureContext.failure() != null; 73 | } 74 | 75 | private OrionErrorCode orionError(final Throwable failure) { 76 | 77 | if (failure instanceof OrionException) { 78 | log.debug(failure); 79 | return ((OrionException) failure).code(); 80 | } 81 | 82 | log.warn("Non OrionException, default unmapped code used", failure); 83 | return OrionErrorCode.UNMAPPED; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/http/server/vertx/OrionLoggerHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.server.vertx; 14 | 15 | import io.vertx.core.logging.Logger; 16 | import io.vertx.core.logging.LoggerFactory; 17 | import io.vertx.ext.web.handler.LoggerFormat; 18 | 19 | public class OrionLoggerHandler extends io.vertx.ext.web.handler.impl.LoggerHandlerImpl { 20 | private final Logger logger; 21 | 22 | public OrionLoggerHandler() { 23 | super(LoggerFormat.DEFAULT); 24 | this.logger = LoggerFactory.getLogger(this.getClass()); 25 | } 26 | 27 | @Override 28 | protected void doLog(final int status, final String message) { 29 | if (status >= 500) { 30 | this.logger.error(message); 31 | } else if (status >= 400) { 32 | // To reduce noise 404s are only logged as debug. A 404 is returned for the common use case where Besu 33 | // receives a private marker transaction for a privacy group that this Orion is not part of. 34 | if (status == 404) { 35 | this.logger.debug(message); 36 | } else { 37 | this.logger.warn(message); 38 | } 39 | } else { 40 | this.logger.info(message); 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/network/HttpTlsOptionHelpers.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.network; 14 | 15 | import java.nio.file.Path; 16 | import java.util.List; 17 | import java.util.Optional; 18 | 19 | import io.vertx.core.net.PemTrustOptions; 20 | import io.vertx.core.net.TrustOptions; 21 | import org.apache.tuweni.net.tls.VertxTrustOptions; 22 | 23 | public class HttpTlsOptionHelpers { 24 | 25 | public static Optional createTrustOptions(final String trustMode, final Path knownConnectionFile) { 26 | switch (trustMode) { 27 | case "whitelist": 28 | return Optional.of(VertxTrustOptions.whitelistClients(knownConnectionFile, false)); 29 | case "ca": 30 | return Optional.empty(); 31 | case "tofu": 32 | case "insecure-tofa": 33 | return Optional.of(VertxTrustOptions.trustClientOnFirstAccess(knownConnectionFile, false)); 34 | case "insecure-no-validation": 35 | case "insecure-record": 36 | return Optional.of(VertxTrustOptions.recordClientFingerprints(knownConnectionFile, false)); 37 | case "ca-or-tofu": 38 | case "insecure-ca-or-tofa": 39 | return Optional.of(VertxTrustOptions.trustClientOnFirstAccess(knownConnectionFile, true)); 40 | case "ca-or-whitelist": 41 | return Optional.of(VertxTrustOptions.whitelistClients(knownConnectionFile, true)); 42 | case "insecure-ca-or-record": 43 | return Optional.of(VertxTrustOptions.recordClientFingerprints(knownConnectionFile, true)); 44 | default: 45 | throw new UnsupportedOperationException("\"" + trustMode + "\" option is not supported"); 46 | } 47 | } 48 | 49 | public static PemTrustOptions createPemTrustOptions(final List certChain) { 50 | if (!certChain.isEmpty()) { 51 | final PemTrustOptions pemTrustOptions = new PemTrustOptions(); 52 | for (final Path certPath : certChain) { 53 | pemTrustOptions.addCertPath(certPath.toAbsolutePath().toString()); 54 | } 55 | return pemTrustOptions; 56 | } 57 | return null; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/network/NetworkNodes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.network; 14 | 15 | import net.consensys.orion.enclave.sodium.serialization.PublicKeyURISerializer; 16 | 17 | import java.net.URI; 18 | import java.util.Collection; 19 | import java.util.Map; 20 | import javax.annotation.Nonnull; 21 | 22 | import com.fasterxml.jackson.annotation.JsonProperty; 23 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 24 | import org.apache.tuweni.bytes.Bytes; 25 | import org.apache.tuweni.crypto.sodium.Box; 26 | 27 | /** Details of other nodes on the network */ 28 | public interface NetworkNodes { 29 | 30 | /** 31 | * @return URL of node 32 | */ 33 | @JsonProperty("url") 34 | URI uri(); 35 | 36 | /** 37 | * @return List of URIs of other nodes on the network 38 | */ 39 | @JsonProperty("nodeURLs") 40 | Collection nodeURIs(); 41 | 42 | /** 43 | * Provide the URI associated with a public key. 44 | * 45 | * @param recipient the public key of the recipient of a message 46 | * @return the URI, or null if no recipient exists for the given URI. 47 | */ 48 | default URI uriForRecipient(@Nonnull Box.PublicKey recipient) { 49 | return uriForRecipient(recipient.bytes()); 50 | } 51 | 52 | /** 53 | * Provide the URI associated with a public key. 54 | * 55 | * @param recipient the public key of the recipient of a message 56 | * @return the URI, or null if no recipient exists for the given URI. 57 | */ 58 | URI uriForRecipient(Bytes recipient); 59 | 60 | /** 61 | * @return Map from public key to node for all discovered nodes. 62 | */ 63 | @JsonProperty("nodePKs") 64 | @JsonSerialize(using = PublicKeyURISerializer.class) 65 | Iterable> nodePKs(); 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/network/NodeHttpClientBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.network; 14 | 15 | import net.consensys.orion.config.Config; 16 | 17 | import java.nio.file.Path; 18 | 19 | import io.vertx.core.Vertx; 20 | import io.vertx.core.http.HttpClient; 21 | import io.vertx.core.http.HttpClientOptions; 22 | import io.vertx.core.net.PemKeyCertOptions; 23 | import io.vertx.core.net.PemTrustOptions; 24 | import org.apache.tuweni.net.tls.VertxTrustOptions; 25 | 26 | public class NodeHttpClientBuilder { 27 | 28 | private static final int MAX_WAIT_QUEUE_SIZE = 32; 29 | 30 | private NodeHttpClientBuilder() {} 31 | 32 | public static HttpClient build(final Vertx vertx, final Config config, final int clientTimeoutMs) { 33 | final HttpClientOptions options = 34 | new HttpClientOptions().setConnectTimeout(clientTimeoutMs).setIdleTimeout(clientTimeoutMs).setMaxWaitQueueSize( 35 | MAX_WAIT_QUEUE_SIZE); 36 | 37 | if ("strict".equals(config.tls())) { 38 | final Path workDir = config.workDir(); 39 | final Path tlsClientCert = workDir.resolve(config.tlsClientCert()); 40 | final Path tlsClientKey = workDir.resolve(config.tlsClientKey()); 41 | 42 | final PemKeyCertOptions pemKeyCertOptions = 43 | new PemKeyCertOptions().setKeyPath(tlsClientKey.toString()).setCertPath(tlsClientCert.toString()); 44 | 45 | options.setSsl(true); 46 | options.setPemKeyCertOptions(pemKeyCertOptions); 47 | 48 | if (!config.tlsClientChain().isEmpty()) { 49 | final PemTrustOptions pemTrustOptions = new PemTrustOptions(); 50 | for (final Path chainCert : config.tlsClientChain()) { 51 | pemTrustOptions.addCertPath(chainCert.toAbsolutePath().toString()); 52 | } 53 | options.setPemTrustOptions(pemTrustOptions); 54 | } 55 | 56 | final Path knownServersFile = config.tlsKnownServers(); 57 | final String clientTrustMode = config.tlsClientTrust(); 58 | switch (clientTrustMode) { 59 | case "whitelist": 60 | options.setTrustOptions(VertxTrustOptions.whitelistServers(knownServersFile, false)); 61 | break; 62 | case "ca": 63 | // use default trust options 64 | break; 65 | case "ca-or-whitelist": 66 | options.setTrustOptions(VertxTrustOptions.whitelistServers(knownServersFile, true)); 67 | break; 68 | case "tofu": 69 | options.setTrustOptions(VertxTrustOptions.trustServerOnFirstUse(knownServersFile, false)); 70 | break; 71 | case "ca-or-tofu": 72 | options.setTrustOptions(VertxTrustOptions.trustServerOnFirstUse(knownServersFile, true)); 73 | break; 74 | case "insecure-no-validation": 75 | case "insecure-record": 76 | options.setTrustOptions(VertxTrustOptions.recordServerFingerprints(knownServersFile, false)); 77 | break; 78 | case "insecure-ca-or-record": 79 | options.setTrustOptions(VertxTrustOptions.recordServerFingerprints(knownServersFile, true)); 80 | break; 81 | 82 | default: 83 | throw new UnsupportedOperationException( 84 | "\"" + clientTrustMode + "\" option for tlsclienttrust is not supported"); 85 | } 86 | } 87 | return vertx.createHttpClient(options); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/network/ReadOnlyNetworkNodes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.network; 14 | 15 | import net.consensys.orion.enclave.sodium.serialization.PublicKeyMapKeyDeserializer; 16 | 17 | import java.net.URI; 18 | import java.util.ArrayList; 19 | import java.util.Collection; 20 | import java.util.Collections; 21 | import java.util.HashMap; 22 | import java.util.List; 23 | import java.util.Map; 24 | import java.util.Objects; 25 | 26 | import com.fasterxml.jackson.annotation.JsonCreator; 27 | import com.fasterxml.jackson.annotation.JsonProperty; 28 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 29 | import org.apache.tuweni.bytes.Bytes; 30 | 31 | public class ReadOnlyNetworkNodes implements NetworkNodes { 32 | 33 | private final URI uri; 34 | private final Map nodePKs; 35 | 36 | @JsonCreator 37 | public ReadOnlyNetworkNodes( 38 | @JsonProperty("url") final URI uri, 39 | @JsonProperty("nodeURLs") List nodeURIs, 40 | @JsonProperty("nodePKs") @JsonDeserialize( 41 | keyUsing = PublicKeyMapKeyDeserializer.class) final Map nodePKs) { 42 | this.uri = uri; 43 | this.nodePKs = new HashMap<>(nodePKs); 44 | } 45 | 46 | public ReadOnlyNetworkNodes(URI uri, Map nodePKs) { 47 | this(uri, Collections.emptyList(), nodePKs); 48 | } 49 | 50 | @Override 51 | public URI uri() { 52 | return uri; 53 | } 54 | 55 | @Override 56 | public Collection nodeURIs() { 57 | return new ArrayList<>(nodePKs.values()); 58 | } 59 | 60 | @Override 61 | public Iterable> nodePKs() { 62 | return nodePKs.entrySet(); 63 | } 64 | 65 | @Override 66 | public URI uriForRecipient(final Bytes recipient) { 67 | return nodePKs.get(recipient); 68 | } 69 | 70 | @Override 71 | public boolean equals(Object o) { 72 | if (this == o) 73 | return true; 74 | if (o == null || getClass() != o.getClass()) 75 | return false; 76 | ReadOnlyNetworkNodes that = (ReadOnlyNetworkNodes) o; 77 | return uri.equals(that.uri) && nodePKs.equals(that.nodePKs); 78 | } 79 | 80 | @Override 81 | public int hashCode() { 82 | return Objects.hash(uri, nodePKs); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/storage/EncryptedPayloadStorage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.storage; 14 | 15 | import static java.nio.charset.StandardCharsets.UTF_8; 16 | import static org.apache.tuweni.io.Base64.encodeBytes; 17 | 18 | import net.consensys.orion.enclave.EncryptedPayload; 19 | import net.consensys.orion.exception.OrionErrorCode; 20 | import net.consensys.orion.exception.OrionException; 21 | import net.consensys.orion.http.server.HttpContentType; 22 | import net.consensys.orion.utils.Serializer; 23 | 24 | import java.util.Optional; 25 | 26 | import org.apache.tuweni.bytes.Bytes; 27 | import org.apache.tuweni.concurrent.AsyncResult; 28 | import org.apache.tuweni.kv.KeyValueStore; 29 | 30 | public class EncryptedPayloadStorage implements Storage { 31 | 32 | private final KeyValueStore store; 33 | private final StorageKeyBuilder keyBuilder; 34 | 35 | public EncryptedPayloadStorage(final KeyValueStore store, final StorageKeyBuilder keyBuilder) { 36 | this.store = store; 37 | this.keyBuilder = keyBuilder; 38 | } 39 | 40 | @Override 41 | public AsyncResult put(final EncryptedPayload data) { 42 | final String key = generateDigest(data); 43 | final Bytes keyBytes = Bytes.wrap(key.getBytes(UTF_8)); 44 | final Bytes dataBytes = Bytes.wrap(Serializer.serialize(HttpContentType.CBOR, data)); 45 | return store.putAsync(keyBytes, dataBytes).thenSupply(() -> key); 46 | } 47 | 48 | @Override 49 | public String generateDigest(final EncryptedPayload data) { 50 | return encodeBytes(keyBuilder.build(data.cipherText())); 51 | } 52 | 53 | 54 | @Override 55 | public AsyncResult> get(final String key) { 56 | final Bytes keyBytes = Bytes.wrap(key.getBytes(UTF_8)); 57 | return store.getAsync(keyBytes).thenApply( 58 | maybeBytes -> Optional.ofNullable(maybeBytes).map( 59 | bytes -> Serializer.deserialize(HttpContentType.CBOR, EncryptedPayload.class, bytes.toArrayUnsafe()))); 60 | } 61 | 62 | @Override 63 | public AsyncResult> update(final String key, final EncryptedPayload data) { 64 | throw new OrionException(OrionErrorCode.METHOD_UNIMPLEMENTED); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/storage/JpaEntityManagerProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.storage; 14 | 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | import javax.persistence.EntityManager; 18 | import javax.persistence.EntityManagerFactory; 19 | import javax.persistence.Persistence; 20 | 21 | import com.google.common.collect.ImmutableMap; 22 | 23 | public class JpaEntityManagerProvider { 24 | private static final String JDBC_PREFIX = "jdbc:"; 25 | private final EntityManagerFactory entityManagerFactory; 26 | 27 | private final Map jdbcDrivers = ImmutableMap 28 | .builder() 29 | .put("postgresql", "org.postgresql.Driver") 30 | .put("h2", "org.h2.Driver") 31 | .put("oracle", "oracle.jdbc.OracleDriver") 32 | .build(); 33 | 34 | public JpaEntityManagerProvider(final String jdbcUrl) { 35 | final String databaseDriver = determineDatabaseDriver(jdbcUrl); 36 | this.entityManagerFactory = createEntityManagerFactory(jdbcUrl, databaseDriver); 37 | } 38 | 39 | public EntityManager createEntityManager() { 40 | return entityManagerFactory.createEntityManager(); 41 | } 42 | 43 | private String determineDatabaseDriver(final String jdbcUrl) { 44 | final String dbName = databaseName(jdbcUrl); 45 | final String driverName = jdbcDrivers.get(dbName); 46 | if (driverName == null) { 47 | throw new IllegalStateException("No database driver found for jdbc url " + jdbcUrl); 48 | } 49 | return driverName; 50 | } 51 | 52 | private String databaseName(final String jdbcUrl) { 53 | final int jdbcPrefixOffset = JDBC_PREFIX.length(); 54 | final int dbEndSeparator = jdbcUrl.indexOf(":", jdbcPrefixOffset); 55 | return jdbcUrl.substring(jdbcPrefixOffset, dbEndSeparator); 56 | } 57 | 58 | private EntityManagerFactory createEntityManagerFactory(final String jdbcUrl, final String driverName) { 59 | final Map properties = new HashMap<>(); 60 | properties.put("openjpa.RuntimeUnenhancedClasses", "supported"); 61 | properties.put("openjpa.ConnectionURL", jdbcUrl); 62 | properties.put("openjpa.ConnectionDriverName", driverName); 63 | return Persistence.createEntityManagerFactory("orion", properties); 64 | } 65 | 66 | public void close() { 67 | entityManagerFactory.close(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/storage/PrivacyGroupStorage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.storage; 14 | 15 | import static java.nio.charset.StandardCharsets.UTF_8; 16 | import static org.apache.tuweni.io.Base64.encodeBytes; 17 | 18 | import net.consensys.orion.enclave.Enclave; 19 | import net.consensys.orion.enclave.PrivacyGroupPayload; 20 | import net.consensys.orion.exception.OrionErrorCode; 21 | import net.consensys.orion.exception.OrionException; 22 | import net.consensys.orion.http.server.HttpContentType; 23 | import net.consensys.orion.utils.Serializer; 24 | 25 | import java.util.Arrays; 26 | import java.util.Optional; 27 | 28 | import org.apache.tuweni.bytes.Bytes; 29 | import org.apache.tuweni.concurrent.AsyncResult; 30 | import org.apache.tuweni.crypto.sodium.Box; 31 | import org.apache.tuweni.kv.KeyValueStore; 32 | 33 | 34 | public class PrivacyGroupStorage implements Storage { 35 | 36 | private final KeyValueStore store; 37 | private final Enclave enclave; 38 | 39 | public PrivacyGroupStorage(final KeyValueStore store, final Enclave enclave) { 40 | this.store = store; 41 | this.enclave = enclave; 42 | } 43 | 44 | @Override 45 | public AsyncResult put(final PrivacyGroupPayload data) { 46 | final String key = generateDigest(data); 47 | final Bytes keyBytes = Bytes.wrap(key.getBytes(UTF_8)); 48 | final Bytes dataBytes = Bytes.wrap(Serializer.serialize(HttpContentType.CBOR, data)); 49 | return store.putAsync(keyBytes, dataBytes).thenSupply(() -> key); 50 | } 51 | 52 | @Override 53 | public String generateDigest(final PrivacyGroupPayload data) { 54 | final Box.PublicKey[] addresses = 55 | Arrays.stream(data.addresses()).map(enclave::readKey).toArray(Box.PublicKey[]::new); 56 | return encodeBytes(enclave.generatePrivacyGroupId(addresses, data.randomSeed(), data.type())); 57 | } 58 | 59 | 60 | @Override 61 | public AsyncResult> get(final String key) { 62 | final Bytes keyBytes = Bytes.wrap(key.getBytes(UTF_8)); 63 | return store.getAsync(keyBytes).thenApply( 64 | maybeBytes -> Optional.ofNullable(maybeBytes).map( 65 | bytes -> Serializer.deserialize(HttpContentType.CBOR, PrivacyGroupPayload.class, bytes.toArrayUnsafe()))); 66 | } 67 | 68 | @Override 69 | public AsyncResult> update(String key, PrivacyGroupPayload data) { 70 | throw new OrionException(OrionErrorCode.METHOD_UNIMPLEMENTED); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/storage/Sha512_256StorageKeyBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.storage; 14 | 15 | import org.apache.tuweni.crypto.Hash; 16 | 17 | public class Sha512_256StorageKeyBuilder implements StorageKeyBuilder { 18 | 19 | @Override 20 | public byte[] build(final byte[] data) { 21 | return Hash.sha2_512_256(data); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/storage/Storage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.storage; 14 | 15 | import java.util.Optional; 16 | 17 | import org.apache.tuweni.concurrent.AsyncResult; 18 | 19 | public interface Storage { 20 | 21 | /** 22 | * Stores data in the store. 23 | * 24 | * @param data The data to store. 25 | * @return the base64 encoded key, as an UTF-8 String 26 | */ 27 | AsyncResult put(T data); 28 | 29 | /** 30 | * Generates digest for data without storing it. 31 | * 32 | * @param data the data to generate a digest for 33 | * @return the digest of the data 34 | */ 35 | String generateDigest(T data); 36 | 37 | /** 38 | * Gets data from the store. 39 | * 40 | * @param key should be base64 encoded UTF-8 string 41 | * @return The retrieved data. 42 | */ 43 | AsyncResult> get(String key); 44 | 45 | /** 46 | * Updates the data in the store. 47 | * 48 | * @param key should be base64 encoded UTF-8 string 49 | * @param data the data to update key with 50 | * @return The updated data. 51 | */ 52 | AsyncResult> update(String key, T data); 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/storage/StorageKeyBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.storage; 14 | 15 | public interface StorageKeyBuilder { 16 | byte[] build(byte[] data); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/storage/StorageUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.storage; 14 | 15 | import java.net.URI; 16 | import java.nio.charset.StandardCharsets; 17 | 18 | import org.apache.logging.log4j.LogManager; 19 | import org.apache.logging.log4j.Logger; 20 | import org.apache.tuweni.bytes.Bytes; 21 | import org.apache.tuweni.kv.KeyValueStore; 22 | import org.apache.tuweni.kv.ProxyKeyValueStore; 23 | 24 | /** Utility functions used to manipulate key-value store to expose higher order functions. **/ 25 | public class StorageUtils { 26 | 27 | private static final Logger log = LogManager.getLogger(StorageUtils.class); 28 | 29 | private StorageUtils() {} 30 | 31 | public static KeyValueStore convertToPubKeyStore(KeyValueStore store) { 32 | return ProxyKeyValueStore.open(store, a -> a, b -> b, StorageUtils::bytesToURI, StorageUtils::uriToBytes); 33 | } 34 | 35 | private static Bytes uriToBytes(Bytes key, URI uri) { 36 | return Bytes.wrap(uri.toString().getBytes(StandardCharsets.UTF_8)); 37 | } 38 | 39 | private static URI bytesToURI(Bytes v) { 40 | try { 41 | return URI.create(new String(v.toArray(), StandardCharsets.UTF_8)); 42 | } catch (IllegalArgumentException e) { 43 | log.warn("Error reading URI", e); 44 | } 45 | return null; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/storage/Store.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.storage; 14 | 15 | import javax.persistence.Entity; 16 | import javax.persistence.Id; 17 | 18 | @Entity 19 | public class Store { 20 | private String key; 21 | private byte[] value; 22 | 23 | @Id 24 | public String getKey() { 25 | return key; 26 | } 27 | 28 | public byte[] getValue() { 29 | return value; 30 | } 31 | 32 | public void setKey(final String key) { 33 | this.key = key; 34 | } 35 | 36 | public void setValue(final byte[] value) { 37 | this.value = value; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/consensys/orion/utils/OrionInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.utils; 14 | 15 | public class OrionInfo { 16 | 17 | private static final String CLIENT = "orion"; 18 | private static final String VERSION = OrionInfo.class.getPackage().getImplementationVersion(); 19 | private static final String OS = PlatformDetector.getOS(); 20 | private static final String VM = PlatformDetector.getVM(); 21 | 22 | private OrionInfo() {} 23 | 24 | public static String version() { 25 | return String.format("%s/%s/%s/%s", CLIENT, VERSION != null ? "v" + VERSION : "development", OS, VM); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | org.apache.openjpa.persistence.PersistenceProviderImpl 8 | net.consensys.orion.storage.Store 9 | 10 | -------------------------------------------------------------------------------- /src/main/resources/default.conf: -------------------------------------------------------------------------------- 1 | # Default Orion Configuration File. 2 | nodeurl = "http://127.0.0.1:8080/" 3 | nodeport = 8080 4 | clienturl = "http://127.0.0.1:8888/" 5 | clientport = 8888 6 | tls = "off" -------------------------------------------------------------------------------- /src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/performance-test/resources/bar.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"QmBfzDOxF99iInkXAPBAZpQQfelvPmHqbcO8tNHYtJM="},"type":"unlocked"} 2 | -------------------------------------------------------------------------------- /src/performance-test/resources/bar.pub: -------------------------------------------------------------------------------- 1 | k2zXEin4Ip/qBGlRkJejnGWdP9cjkK+DAvKNW31L2C8= -------------------------------------------------------------------------------- /src/performance-test/resources/config-8081.txt: -------------------------------------------------------------------------------- 1 | # Default Orion Configuration File. 2 | nodeurl = "http://127.0.0.1:8080/" 3 | nodeport = 8080 4 | clienturl = "http://127.0.0.1:8081/" 5 | clientport = 8081 6 | publickeys = ["foo.pub"] 7 | privatekeys = ["foo.key"] 8 | othernodes = ["http://127.0.0.1:8082/", "http://127.0.0.1:8084/"] 9 | storage = "leveldb:orion1" 10 | -------------------------------------------------------------------------------- /src/performance-test/resources/config-8083.txt: -------------------------------------------------------------------------------- 1 | # Default Orion Configuration File. 2 | nodeurl = "http://127.0.0.1:8082/" 3 | nodeport = 8082 4 | clienturl = "http://127.0.0.1:8083/" 5 | clientport = 8083 6 | publickeys = ["bar.pub"] 7 | privatekeys = ["bar.key"] 8 | othernodes = ["http://127.0.0.1:8080/", "http://127.0.0.1:8084/"] 9 | storage = "leveldb:orion2" 10 | -------------------------------------------------------------------------------- /src/performance-test/resources/config-8085.txt: -------------------------------------------------------------------------------- 1 | # Default Orion Configuration File. 2 | nodeurl = "http://127.0.0.1:8084/" 3 | nodeport = 8084 4 | clienturl = "http://127.0.0.1:8085/" 5 | clientport = 8085 6 | publickeys = ["foobar.pub"] 7 | privatekeys = ["foobar.key"] 8 | othernodes = ["http://127.0.0.1:8080/", "http://127.0.0.1:8082/"] 9 | storage = "leveldb:orion3" 10 | -------------------------------------------------------------------------------- /src/performance-test/resources/foo.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"C4OD4BxFXQB7DD2hsH33FumUgTuGnGSVgYd7euPDiDY="},"type":"unlocked"} 2 | -------------------------------------------------------------------------------- /src/performance-test/resources/foo.pub: -------------------------------------------------------------------------------- 1 | zO9rl50icfFDnI5MAQzRgmrQIY8mgYSWEVBKbym2Hho= -------------------------------------------------------------------------------- /src/performance-test/resources/foobar.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"8DDj4Fk6pP6SwGxsdXi6y1VjAcIW+q/vKDPGFx4k7UY="},"type":"unlocked"} 2 | -------------------------------------------------------------------------------- /src/performance-test/resources/foobar.pub: -------------------------------------------------------------------------------- 1 | PCbwySqYvCAC5GpjDaJpiKuPp5qvCX0ADPXcHI47yx0= -------------------------------------------------------------------------------- /src/performance-test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | orion.log 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/performance-test/scala/net/consensys/orion/load/LoadSimulation.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.load 14 | 15 | import java.util.Base64 16 | import collection.JavaConverters._ 17 | 18 | import io.gatling.core.Predef._ 19 | import io.gatling.core.structure._ 20 | import io.gatling.http.Predef._ 21 | import com.fasterxml.jackson.databind.ObjectMapper 22 | import scala.concurrent.duration._ 23 | 24 | class LoadSimulation extends Simulation { 25 | 26 | val mapper = new ObjectMapper() 27 | 28 | val foo = "zO9rl50icfFDnI5MAQzRgmrQIY8mgYSWEVBKbym2Hho=" 29 | 30 | val bar = "k2zXEin4Ip/qBGlRkJejnGWdP9cjkK+DAvKNW31L2C8=" 31 | 32 | val foobar = "PCbwySqYvCAC5GpjDaJpiKuPp5qvCX0ADPXcHI47yx0=" 33 | 34 | val upCheck = scenario("UpCheck") 35 | .exec(http("upcheck") 36 | .get("/upcheck")) 37 | .pause(5) 38 | 39 | val base64payload = new String(Base64.getEncoder.encode("somebyteshere".getBytes)) 40 | 41 | def buildSendRequests(host: String, from : String, to : Seq[String]): ChainBuilder = { 42 | return exec(http("sends") 43 | .post(s"$host/send") 44 | .body(StringBody(mapper.writeValueAsString(Map("payload" -> base64payload, "from" -> from, "to" -> to.toArray).asJava))) 45 | .asJSON.check(jsonPath("$.key").saveAs("sendResponse"))) 46 | } 47 | 48 | def buildReceiveRequests(host: String, to : String): ChainBuilder = { 49 | return exec(http("receives") 50 | .post(s"$host/receive") 51 | .body(StringBody("""{"key":"${sendResponse}","to":"""" + to + "\"}")) 52 | .asJSON.check(jsonPath("$.payload").is(base64payload))) 53 | } 54 | 55 | val fooToFooRequests = buildSendRequests("http://localhost:8081", foo, Seq(foo)) 56 | val receiveFooRequests = buildReceiveRequests("http://localhost:8081", foo) 57 | 58 | val fooToBarRequests = buildSendRequests("http://localhost:8081", foo, Seq(bar)) 59 | 60 | val fooToBarAndFoobarRequests = buildSendRequests("http://localhost:8081", foo, Seq(bar, foobar)) 61 | val receiveBarRequests = buildReceiveRequests("http://localhost:8083", bar) 62 | val receiveFooBarRequests = buildReceiveRequests("http://localhost:8085", foobar) 63 | 64 | 65 | setUp( 66 | upCheck.inject(atOnceUsers(10)), 67 | scenario("SendThenReceiveOneNode").exec(fooToFooRequests).exec(receiveFooRequests).inject(rampUsers(1000) over (2 minutes)), 68 | scenario("SendThenReceiveOtherNode").exec(fooToBarRequests).exec(receiveBarRequests).inject(rampUsers(1000) over (2 minutes)), 69 | scenario("SendThenReceiveTwoOtherNodes").exec(fooToBarAndFoobarRequests).exec(receiveBarRequests). 70 | exec(receiveFooBarRequests).inject(atOnceUsers(10), rampUsers(20000) over (2 minutes)) 71 | ) 72 | } -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/enclave/EnclaveExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | import static org.junit.jupiter.api.Assertions.assertTrue; 17 | 18 | import net.consensys.orion.exception.OrionErrorCode; 19 | 20 | import org.junit.jupiter.api.Test; 21 | 22 | class EnclaveExceptionTest { 23 | 24 | @Test 25 | void implementationOfRuntimeInterface() { 26 | assertTrue(RuntimeException.class.isAssignableFrom(EnclaveException.class)); 27 | } 28 | 29 | @Test 30 | void construction() { 31 | final String message = "This is the cause"; 32 | final EnclaveException exception = new EnclaveException(OrionErrorCode.INVALID_PAYLOAD, message); 33 | assertEquals(message, exception.getMessage()); 34 | assertEquals(OrionErrorCode.INVALID_PAYLOAD, exception.code()); 35 | 36 | final Throwable cause = new Throwable(); 37 | final EnclaveException anotherException = new EnclaveException(OrionErrorCode.INVALID_PAYLOAD, cause); 38 | assertEquals(cause, anotherException.getCause()); 39 | assertEquals(OrionErrorCode.INVALID_PAYLOAD, anotherException.code()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/enclave/PrivacyGroupGenerationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave; 14 | 15 | import static org.apache.tuweni.io.Base64.encodeBytes; 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | 19 | import net.consensys.orion.enclave.sodium.MemoryKeyStore; 20 | import net.consensys.orion.enclave.sodium.SodiumEnclave; 21 | 22 | import java.io.FileNotFoundException; 23 | import java.io.IOException; 24 | import java.io.Reader; 25 | import java.net.URL; 26 | import java.nio.charset.Charset; 27 | import java.nio.file.Files; 28 | import java.nio.file.Paths; 29 | import java.security.Security; 30 | import java.util.Arrays; 31 | import java.util.List; 32 | 33 | import com.fasterxml.jackson.core.type.TypeReference; 34 | import com.fasterxml.jackson.databind.ObjectMapper; 35 | import org.apache.tuweni.crypto.sodium.Box; 36 | import org.junit.Before; 37 | import org.junit.Test; 38 | 39 | public class PrivacyGroupGenerationTest { 40 | 41 | 42 | private final MemoryKeyStore keyStore = new MemoryKeyStore(); 43 | private SodiumEnclave enclave; 44 | 45 | static { 46 | Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 47 | } 48 | 49 | @Before 50 | public void setUp() { 51 | enclave = new SodiumEnclave(keyStore); 52 | } 53 | 54 | @Test 55 | public void expectedPrivacyGroupIsGenerated() throws IOException { 56 | 57 | final URL url = getClass().getClassLoader().getResource("keySets.json"); 58 | if (url == null) { 59 | throw new FileNotFoundException(); 60 | } 61 | try (final Reader reader = Files.newBufferedReader(Paths.get(url.getPath()), Charset.defaultCharset())) { 62 | final ObjectMapper objectMapper = new ObjectMapper(); 63 | 64 | final List privacyGroups = 65 | objectMapper.readValue(reader, new TypeReference>() {}); 66 | 67 | assertTrue(true); 68 | for (final PrivacyGroupTest privacyGroup : privacyGroups) { 69 | final Box.PublicKey[] addresses = 70 | Arrays.stream(privacyGroup.getPrivacyGroup()).map(enclave::readKey).toArray(Box.PublicKey[]::new); 71 | assertEquals( 72 | privacyGroup.getPrivacyGroupId(), 73 | encodeBytes(enclave.generatePrivacyGroupId(addresses, null, PrivacyGroupPayload.Type.LEGACY))); 74 | 75 | } 76 | } catch (final IOException e) { 77 | throw e; 78 | } 79 | } 80 | } 81 | 82 | 83 | class PrivacyGroupTest { 84 | String privacyGroupId; 85 | String[] privacyGroup; 86 | 87 | public String getPrivacyGroupId() { 88 | return privacyGroupId; 89 | } 90 | 91 | public String[] getPrivacyGroup() { 92 | return privacyGroup; 93 | } 94 | 95 | public void setPrivacyGroupId(final String privacyGroupId) { 96 | this.privacyGroupId = privacyGroupId; 97 | } 98 | 99 | public void setPrivacyGroup(final String[] privacyGroup) { 100 | this.privacyGroup = privacyGroup; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/enclave/sodium/SodiumEnclaveStub.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave.sodium; 14 | 15 | import net.consensys.orion.enclave.Enclave; 16 | import net.consensys.orion.enclave.EncryptedKey; 17 | import net.consensys.orion.enclave.EncryptedPayload; 18 | import net.consensys.orion.enclave.PrivacyGroupPayload; 19 | 20 | import java.nio.charset.StandardCharsets; 21 | import java.util.Base64; 22 | 23 | import org.apache.tuweni.crypto.sodium.Box; 24 | 25 | public class SodiumEnclaveStub implements Enclave { 26 | 27 | @Override 28 | public Box.PublicKey[] alwaysSendTo() { 29 | return new Box.PublicKey[0]; 30 | } 31 | 32 | @Override 33 | public Box.PublicKey[] nodeKeys() { 34 | return new Box.PublicKey[0]; 35 | } 36 | 37 | @Override 38 | public byte[] decrypt(final EncryptedPayload ciphertextAndMetadata, final Box.PublicKey publicKey) { 39 | final byte[] cipherText = ciphertextAndMetadata.cipherText(); 40 | final byte[] plainText = new byte[cipherText.length]; 41 | for (int i = 0; i < cipherText.length; i++) { 42 | final byte b = cipherText[i]; 43 | plainText[i] = (byte) (b - 10); 44 | } 45 | return plainText; 46 | } 47 | 48 | @Override 49 | public Box.PublicKey readKey(final String b64) { 50 | return Box.PublicKey.fromBytes(Base64.getDecoder().decode(b64.getBytes(StandardCharsets.UTF_8))); 51 | } 52 | 53 | @Override 54 | public EncryptedPayload encrypt( 55 | final byte[] plaintext, 56 | final Box.PublicKey senderKey, 57 | final Box.PublicKey[] recipients, 58 | final byte[] seed) { 59 | final byte[] cipherText = new byte[plaintext.length]; 60 | for (int i = 0; i < plaintext.length; i++) { 61 | final byte b = plaintext[i]; 62 | cipherText[i] = (byte) (b + 10); 63 | } 64 | return new EncryptedPayload( 65 | senderKey, 66 | new byte[0], 67 | new EncryptedKey[0], 68 | cipherText, 69 | generatePrivacyGroupId(recipients, seed, PrivacyGroupPayload.Type.PANTHEON)); 70 | } 71 | 72 | @Override 73 | public byte[] generatePrivacyGroupId( 74 | final Box.PublicKey[] recipientsAndSender, 75 | final byte[] seed, 76 | final PrivacyGroupPayload.Type type) { 77 | return new byte[0]; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/enclave/sodium/SodiumEnclaveStubTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.enclave.sodium; 14 | 15 | import static java.nio.charset.StandardCharsets.UTF_8; 16 | import static org.junit.jupiter.api.Assertions.assertArrayEquals; 17 | 18 | import net.consensys.orion.enclave.EncryptedPayload; 19 | 20 | import javax.xml.bind.DatatypeConverter; 21 | 22 | import org.junit.jupiter.api.Test; 23 | 24 | class SodiumEnclaveStubTest { 25 | 26 | @Test 27 | void roundTripEncryption() { 28 | final byte[] message = "hello".getBytes(UTF_8); 29 | final SodiumEnclaveStub enclave = new SodiumEnclaveStub(); 30 | final EncryptedPayload encryptedPayload = enclave.encrypt(message, null, null, null); 31 | final byte[] bytes = enclave.decrypt(encryptedPayload, null); 32 | assertArrayEquals(message, bytes); 33 | } 34 | 35 | @Test 36 | void roundTripEncryptionWithFunkyBytes() { 37 | final byte[] message = DatatypeConverter.parseHexBinary("0079FF00FF89"); 38 | final SodiumEnclaveStub enclave = new SodiumEnclaveStub(); 39 | final EncryptedPayload encryptedPayload = enclave.encrypt(message, null, null, null); 40 | final byte[] bytes = enclave.decrypt(encryptedPayload, null); 41 | assertArrayEquals(message, bytes); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/exception/OrionErrorCodeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.exception; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | import static org.junit.jupiter.api.Assertions.assertFalse; 17 | import static org.junit.jupiter.api.Assertions.assertTrue; 18 | 19 | import java.util.Optional; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | /** Verify the Orion Error Codes behave correctly. */ 24 | class OrionErrorCodeTest { 25 | 26 | @Test 27 | void propagationToAllParticipantsFailed() { 28 | final OrionErrorCode expected = OrionErrorCode.NODE_PROPAGATING_TO_ALL_PEERS; 29 | 30 | final Optional actual = OrionErrorCode.get(expected.code()); 31 | 32 | assertTrue(actual.isPresent(), "Expecting an error code to be returned"); 33 | assertEquals(expected, actual.get()); 34 | } 35 | 36 | @Test 37 | void absent() { 38 | final String missingCode = "I don't really exist"; 39 | 40 | final Optional actual = OrionErrorCode.get(missingCode); 41 | 42 | assertFalse(actual.isPresent(), "Expecting no error code to be returned"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/helpers/FakePeer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.helpers; 14 | 15 | import net.consensys.orion.enclave.sodium.MemoryKeyStore; 16 | 17 | import java.io.IOException; 18 | import java.net.URI; 19 | 20 | import okhttp3.mockwebserver.MockResponse; 21 | import okhttp3.mockwebserver.MockWebServer; 22 | import org.apache.tuweni.crypto.sodium.Box; 23 | import org.apache.tuweni.crypto.sodium.Box.PublicKey; 24 | 25 | public class FakePeer { 26 | public final MockWebServer server; 27 | public final Box.PublicKey publicKey; 28 | 29 | public FakePeer(final MockResponse response, final MemoryKeyStore memoryKeyStore) throws IOException { 30 | server = new MockWebServer(); 31 | publicKey = memoryKeyStore.generateKeyPair(); 32 | server.enqueue(response); 33 | server.start(); 34 | } 35 | 36 | public FakePeer(final MockResponse response, final Box.PublicKey publicKey) throws IOException { 37 | server = new MockWebServer(); 38 | this.publicKey = publicKey; 39 | server.enqueue(response); 40 | server.start(); 41 | } 42 | 43 | public FakePeer(final PublicKey publicKey) throws IOException { 44 | this.server = new MockWebServer(); 45 | this.publicKey = publicKey; 46 | server.start(); 47 | } 48 | 49 | public void addResponse(final MockResponse response) { 50 | server.enqueue(response); 51 | } 52 | 53 | public URI getURI() { 54 | return server.url("").uri(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/http/ClientOrionTlsCertificateAutoCreateTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http; 14 | 15 | import static io.vertx.core.Vertx.vertx; 16 | import static net.consensys.orion.TestUtils.generateAndLoadConfiguration; 17 | import static net.consensys.orion.TestUtils.writeClientConnectionServerCertToConfig; 18 | import static net.consensys.orion.TestUtils.writeServerCertToConfig; 19 | import static org.apache.tuweni.net.tls.TLS.readPemFile; 20 | import static org.assertj.core.api.Assertions.assertThat; 21 | import static org.assertj.core.api.Assertions.assertThatCode; 22 | 23 | import net.consensys.orion.cmd.Orion; 24 | import net.consensys.orion.config.Config; 25 | 26 | import java.io.ByteArrayInputStream; 27 | import java.nio.file.Files; 28 | import java.nio.file.Path; 29 | import java.security.cert.CertificateFactory; 30 | import java.security.spec.PKCS8EncodedKeySpec; 31 | 32 | import io.vertx.core.Vertx; 33 | import org.apache.tuweni.junit.TempDirectory; 34 | import org.apache.tuweni.junit.TempDirectoryExtension; 35 | import org.junit.jupiter.api.BeforeEach; 36 | import org.junit.jupiter.api.Test; 37 | import org.junit.jupiter.api.extension.ExtendWith; 38 | 39 | @ExtendWith(TempDirectoryExtension.class) 40 | public class ClientOrionTlsCertificateAutoCreateTest { 41 | private final static Vertx vertx = vertx(); 42 | private Orion orion; 43 | private Config config; 44 | private static final String TRUST_MODE = "tofu"; 45 | private final static String serverCert = "serverCert.pem"; 46 | private final static String serverKey = "serverKey.key"; 47 | private final static String clientConnectionServerCert = "clientConnectionServerCert.pem"; 48 | private final static String clientConnectionServerKey = "clientConnectionServerKey.key"; 49 | 50 | @BeforeEach 51 | void setUpConfig(@TempDirectory final Path tempDir) throws Exception { 52 | config = generateAndLoadConfiguration(tempDir, writer -> { 53 | writer.write("tlsservertrust='" + TRUST_MODE + "'\n"); 54 | writer.write("clientconnectiontls='strict'\n"); 55 | writer.write("clientconnectiontlsservertrust='" + TRUST_MODE + "'\n"); 56 | 57 | writeServerCertToConfig(writer, tempDir.resolve(serverCert).toString(), tempDir.resolve(serverKey).toString()); 58 | 59 | writeClientConnectionServerCertToConfig( 60 | writer, 61 | tempDir.resolve(clientConnectionServerCert).toString(), 62 | tempDir.resolve(clientConnectionServerKey).toString()); 63 | }); 64 | } 65 | 66 | @Test 67 | void clientConnectionTlsKeyCertPairCreatedIfNotExist() { 68 | final Path privateKeyPath = config.clientConnectionTlsServerKey(); 69 | final Path certificatePath = config.clientConnectionTlsServerCert(); 70 | 71 | assertThat(privateKeyPath).doesNotExist(); 72 | assertThat(certificatePath).doesNotExist(); 73 | 74 | try { 75 | // start Orion 76 | orion = new Orion(vertx); 77 | orion.run(config, false); 78 | 79 | // key/certificate created after Orion start and are in valid readable format. 80 | assertThat(privateKeyPath).exists(); 81 | assertThat(certificatePath).exists(); 82 | 83 | assertThatCode(() -> new PKCS8EncodedKeySpec(readPemFile(privateKeyPath))).doesNotThrowAnyException(); 84 | 85 | assertThatCode( 86 | () -> CertificateFactory.getInstance("X.509").generateCertificate( 87 | new ByteArrayInputStream(Files.readAllBytes(certificatePath)))).doesNotThrowAnyException(); 88 | } finally { 89 | if (orion != null) { 90 | orion.stop(); 91 | } 92 | 93 | vertx.close(); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/http/handler/SendRawHandlerWithNodeKeys.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler; 14 | 15 | import static net.consensys.orion.http.server.HttpContentType.APPLICATION_OCTET_STREAM; 16 | import static org.apache.tuweni.crypto.Hash.sha2_512_256; 17 | import static org.apache.tuweni.io.Base64.encodeBytes; 18 | import static org.junit.jupiter.api.Assertions.assertEquals; 19 | 20 | import net.consensys.orion.enclave.Enclave; 21 | import net.consensys.orion.enclave.EncryptedPayload; 22 | import net.consensys.orion.helpers.FakePeer; 23 | import net.consensys.orion.helpers.StubEnclave; 24 | import net.consensys.orion.http.server.HttpContentType; 25 | 26 | import java.nio.file.Path; 27 | import java.util.Collections; 28 | import java.util.Random; 29 | 30 | import okhttp3.MediaType; 31 | import okhttp3.Request; 32 | import okhttp3.RequestBody; 33 | import okhttp3.Response; 34 | import okhttp3.mockwebserver.MockResponse; 35 | import org.apache.tuweni.crypto.sodium.Box; 36 | import org.junit.jupiter.api.Test; 37 | 38 | public class SendRawHandlerWithNodeKeys extends SendRawHandlerTest { 39 | 40 | @Override 41 | protected Enclave buildEnclave(final Path tempDir) { 42 | return new StubEnclave() { 43 | @Override 44 | public Box.PublicKey[] nodeKeys() { 45 | try { 46 | final Box.KeyPair keyPair = Box.KeyPair.random(); 47 | return new Box.PublicKey[] {keyPair.publicKey()}; 48 | } catch (final Throwable t) { 49 | throw new RuntimeException(t); 50 | } 51 | } 52 | }; 53 | } 54 | 55 | @Test 56 | public void sendingWithoutFromHeaderSucceeds() throws Exception { 57 | final byte[] toEncrypt = new byte[342]; 58 | new Random().nextBytes(toEncrypt); 59 | 60 | final RequestBody body = 61 | RequestBody.create(MediaType.parse(HttpContentType.APPLICATION_OCTET_STREAM.httpHeaderValue), toEncrypt); 62 | 63 | final EncryptedPayload encryptedPayload = enclave.encrypt(toEncrypt, null, null, null); 64 | final String digest = encodeBytes(sha2_512_256(encryptedPayload.cipherText())); 65 | 66 | final FakePeer fakePeer = new FakePeer(new MockResponse().setBody(digest), memoryKeyStore); 67 | networkNodes.addNode(Collections.singletonMap(fakePeer.publicKey.bytes(), fakePeer.getURI()).entrySet()); 68 | final String[] to = new String[] {encodeBytes(fakePeer.publicKey.bytesArray())}; 69 | 70 | final Request request = new Request.Builder() 71 | .post(body) 72 | .url(clientBaseUrl + "sendraw") 73 | .addHeader("c11n-to", String.join(",", to)) 74 | .addHeader("Content-Type", APPLICATION_OCTET_STREAM.httpHeaderValue) 75 | .addHeader("Accept", APPLICATION_OCTET_STREAM.httpHeaderValue) 76 | .build(); 77 | 78 | final Response resp = httpClient.newCall(request).execute(); 79 | 80 | assertEquals(200, resp.code()); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/http/handler/SendRequestTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler; 14 | 15 | import static java.nio.charset.StandardCharsets.UTF_8; 16 | import static org.apache.tuweni.io.Base64.encodeBytes; 17 | import static org.assertj.core.api.Assertions.assertThat; 18 | import static org.junit.jupiter.api.Assertions.assertEquals; 19 | import static org.junit.jupiter.api.Assertions.assertFalse; 20 | import static org.junit.jupiter.api.Assertions.assertTrue; 21 | 22 | import net.consensys.orion.http.handler.send.SendRequest; 23 | 24 | import com.fasterxml.jackson.databind.ObjectMapper; 25 | import org.junit.jupiter.api.Test; 26 | 27 | class SendRequestTest { 28 | 29 | @Test 30 | void invalidBase64Payload() { 31 | final SendRequest request = new SendRequest("something", "foo", new String[] {"foo"}); 32 | assertFalse(request.isValid()); 33 | } 34 | 35 | @Test 36 | void noFromValid() { 37 | final SendRequest request = new SendRequest("something".getBytes(UTF_8), null, new String[] {"foo"}); 38 | assertTrue(request.isValid()); 39 | } 40 | 41 | @Test 42 | void emptyFromInvalid() { 43 | final SendRequest request = new SendRequest("something".getBytes(UTF_8), "", new String[] {"foo"}); 44 | assertFalse(request.isValid()); 45 | } 46 | 47 | @Test 48 | void missingPayload() { 49 | final SendRequest request = new SendRequest((byte[]) null, "foo", new String[] {"foo"}); 50 | assertFalse(request.isValid()); 51 | } 52 | 53 | @Test 54 | void emptyPayload() { 55 | final SendRequest request = new SendRequest("".getBytes(UTF_8), "foo", new String[] {"foo"}); 56 | assertFalse(request.isValid()); 57 | } 58 | 59 | @Test 60 | void emptyToAddresses() { 61 | final SendRequest request = new SendRequest("something".getBytes(UTF_8), "foo", new String[0]); 62 | assertThat(request.to()).contains("foo"); 63 | assertTrue(request.isValid()); 64 | } 65 | 66 | @Test 67 | void nullToAddresses() { 68 | final SendRequest request = new SendRequest("something".getBytes(UTF_8), "foo", null); 69 | assertThat(request.to()).contains("foo"); 70 | assertTrue(request.isValid()); 71 | } 72 | 73 | @Test 74 | void toAddressesContainNull() { 75 | final SendRequest request = new SendRequest("something".getBytes(UTF_8), "foo", new String[] {null, "foo"}); 76 | assertFalse(request.isValid()); 77 | } 78 | 79 | @Test 80 | void jsonToObject() throws Exception { 81 | 82 | final String json = 83 | "{\"payload\":\"" + encodeBytes("foo".getBytes(UTF_8)) + "\", \"from\":\"foo\", \"to\":[\"foo\"]}"; 84 | final ObjectMapper mapper = new ObjectMapper(); 85 | final SendRequest req = mapper.readerFor(SendRequest.class).readValue(json); 86 | 87 | assertEquals("foo", req.from().get()); 88 | assertEquals("foo", req.to()[0]); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/http/handler/UpcheckHandlerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | 17 | import okhttp3.Request; 18 | import okhttp3.Response; 19 | import org.junit.jupiter.api.Test; 20 | 21 | class UpcheckHandlerTest extends HandlerTest { 22 | 23 | @Test 24 | void publicUpcheck() throws Exception { 25 | final Request request = new Request.Builder().get().url(nodeBaseUrl + "/upcheck").build(); 26 | 27 | final Response resp = httpClient.newCall(request).execute(); 28 | assertEquals(200, resp.code()); 29 | assertEquals("I'm up!", resp.body().string()); 30 | } 31 | 32 | @Test 33 | void privateUpcheck() throws Exception { 34 | final Request request = new Request.Builder().get().url(clientBaseUrl + "/upcheck").build(); 35 | 36 | final Response resp = httpClient.newCall(request).execute(); 37 | assertEquals(200, resp.code()); 38 | assertEquals("I'm up!", resp.body().string()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/http/handler/VersionHandlerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.http.handler; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | import static org.junit.jupiter.api.Assertions.assertTrue; 17 | 18 | import okhttp3.Request; 19 | import okhttp3.Response; 20 | import org.junit.jupiter.api.Test; 21 | 22 | class VersionHandlerTest extends HandlerTest { 23 | 24 | @Test 25 | void handleVersionRequestSuccessfullyOnClientApi() throws Exception { 26 | final Request request = new Request.Builder().get().url(clientBaseUrl + "/version").build(); 27 | 28 | final Response resp = httpClient.newCall(request).execute(); 29 | assertEquals(200, resp.code()); 30 | assertTrue(resp.body().string().matches("orion/.*?/.*?/.*")); 31 | } 32 | 33 | @Test 34 | void versionCheckNotEnabledForNodeApi() throws Exception { 35 | final Request request = new Request.Builder().get().url(nodeBaseUrl + "/version").build(); 36 | 37 | final Response resp = httpClient.newCall(request).execute(); 38 | assertEquals(404, resp.code()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/network/PersistentNetworkNodesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.network; 14 | 15 | import static org.apache.tuweni.crypto.sodium.Box.KeyPair.random; 16 | import static org.junit.jupiter.api.Assertions.assertEquals; 17 | import static org.junit.jupiter.api.Assertions.assertFalse; 18 | import static org.junit.jupiter.api.Assertions.assertTrue; 19 | 20 | import net.consensys.orion.config.Config; 21 | 22 | import java.net.URI; 23 | import java.util.Collections; 24 | import java.util.Iterator; 25 | import java.util.Map; 26 | import java.util.concurrent.ConcurrentHashMap; 27 | 28 | import org.apache.tuweni.bytes.Bytes; 29 | import org.apache.tuweni.crypto.sodium.Box; 30 | import org.apache.tuweni.kv.MapKeyValueStore; 31 | import org.junit.jupiter.api.Test; 32 | 33 | class PersistentNetworkNodesTest { 34 | 35 | @Test 36 | void testTwoInstancesSameStore() { 37 | Config config = Config.load("tls='off'"); 38 | MapKeyValueStore store = MapKeyValueStore.open(new ConcurrentHashMap<>()); 39 | PersistentNetworkNodes nodes1 = new PersistentNetworkNodes(config, new Box.PublicKey[0], store); 40 | PersistentNetworkNodes nodes2 = new PersistentNetworkNodes(config, new Box.PublicKey[0], store); 41 | 42 | Box.PublicKey pk = random().publicKey(); 43 | boolean changed = 44 | nodes1.addNode(Collections.singletonMap(pk.bytes(), URI.create("http://example:com:56666")).entrySet()); 45 | assertTrue(changed); 46 | 47 | Iterator> iter = nodes2.nodePKs().iterator(); 48 | assertTrue(iter.hasNext()); 49 | Map.Entry entry = iter.next(); 50 | assertEquals(pk.bytes(), entry.getKey()); 51 | assertFalse(iter.hasNext()); 52 | } 53 | 54 | @Test 55 | void testTwoInstancesInSequence() { 56 | Config config = Config.load("tls='off'"); 57 | MapKeyValueStore store = MapKeyValueStore.open(new ConcurrentHashMap<>()); 58 | PersistentNetworkNodes nodes1 = new PersistentNetworkNodes(config, new Box.PublicKey[0], store); 59 | 60 | Box.PublicKey pk = random().publicKey(); 61 | boolean changed = 62 | nodes1.addNode(Collections.singletonMap(pk.bytes(), URI.create("http://example:com:56666")).entrySet()); 63 | assertTrue(changed); 64 | 65 | PersistentNetworkNodes nodes2 = new PersistentNetworkNodes(config, new Box.PublicKey[0], store); 66 | Iterator> iter = nodes2.nodePKs().iterator(); 67 | Map.Entry entry = iter.next(); 68 | assertEquals(pk.bytes(), entry.getKey()); 69 | assertFalse(iter.hasNext()); 70 | } 71 | 72 | @Test 73 | void tryOverridingNodeInfo() { 74 | Config config = Config.load("tls='off'"); 75 | MapKeyValueStore store = MapKeyValueStore.open(new ConcurrentHashMap<>()); 76 | PersistentNetworkNodes nodes = new PersistentNetworkNodes(config, new Box.PublicKey[0], store); 77 | Box.PublicKey pk = random().publicKey(); 78 | boolean changed = 79 | nodes.addNode(Collections.singletonMap(pk.bytes(), URI.create("http://example:com:56666")).entrySet()); 80 | assertTrue(changed); 81 | 82 | changed = nodes.addNode(Collections.singletonMap(pk.bytes(), URI.create("http://evil:com:56666")).entrySet()); 83 | assertFalse(changed); 84 | 85 | assertEquals(URI.create("http://example:com:56666"), nodes.uriForRecipient(pk)); 86 | 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/storage/EncryptedPayloadStorageTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.storage; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | 17 | import net.consensys.orion.enclave.Enclave; 18 | import net.consensys.orion.enclave.EncryptedPayload; 19 | import net.consensys.orion.enclave.sodium.SodiumEnclaveStub; 20 | 21 | import java.security.Security; 22 | import java.util.Optional; 23 | import java.util.Random; 24 | 25 | import org.apache.tuweni.kv.MapKeyValueStore; 26 | import org.junit.jupiter.api.Test; 27 | 28 | class EncryptedPayloadStorageTest { 29 | 30 | static { 31 | Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 32 | } 33 | 34 | private final Enclave enclave = new SodiumEnclaveStub(); 35 | private final StorageKeyBuilder keyBuilder = new Sha512_256StorageKeyBuilder(); 36 | private final Storage payloadStorage = 37 | new EncryptedPayloadStorage(new MapKeyValueStore<>(), keyBuilder); 38 | 39 | @Test 40 | void storeAndRetrieve() throws Exception { 41 | // generate random byte content 42 | final byte[] toEncrypt = new byte[342]; 43 | new Random().nextBytes(toEncrypt); 44 | 45 | final EncryptedPayload toStore = enclave.encrypt(toEncrypt, null, null, null); 46 | 47 | final String key = payloadStorage.put(toStore).get(); 48 | assertEquals(toStore, payloadStorage.get(key).get().get()); 49 | } 50 | 51 | @Test 52 | void retrieveWithoutStore() throws Exception { 53 | assertEquals(Optional.empty(), payloadStorage.get("missing").get()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/net/consensys/orion/utils/SerializerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 ConsenSys AG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | package net.consensys.orion.utils; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | 17 | import net.consensys.orion.enclave.EncryptedKey; 18 | import net.consensys.orion.enclave.EncryptedPayload; 19 | import net.consensys.orion.http.server.HttpContentType; 20 | 21 | import java.io.Serializable; 22 | import java.util.Objects; 23 | import java.util.Random; 24 | 25 | import org.apache.tuweni.crypto.sodium.Box; 26 | import org.junit.jupiter.api.Test; 27 | 28 | class SerializerTest { 29 | 30 | @Test 31 | void jsonSerialization() { 32 | final DummyObject dummyObjectOriginal = new DummyObject(); 33 | final byte[] bytes = Serializer.serialize(HttpContentType.JSON, dummyObjectOriginal); 34 | final DummyObject dummyObject = Serializer.deserialize(HttpContentType.JSON, DummyObject.class, bytes); 35 | assertEquals(dummyObjectOriginal, dummyObject); 36 | } 37 | 38 | @Test 39 | void cborSerialization() { 40 | final DummyObject dummyObjectOriginal = new DummyObject(); 41 | final byte[] bytes = Serializer.serialize(HttpContentType.CBOR, dummyObjectOriginal); 42 | final DummyObject dummyObject = Serializer.deserialize(HttpContentType.CBOR, DummyObject.class, bytes); 43 | assertEquals(dummyObjectOriginal, dummyObject); 44 | } 45 | 46 | @Test 47 | void sodiumEncryptedPayloadSerialization() { 48 | final EncryptedKey[] encryptedKeys = new EncryptedKey[0]; 49 | final byte[] nonce = {}; 50 | final Box.PublicKey sender = Box.KeyPair.random().publicKey(); 51 | 52 | // generate random byte content 53 | final byte[] toEncrypt = new byte[342]; 54 | new Random().nextBytes(toEncrypt); 55 | 56 | final EncryptedPayload original = new EncryptedPayload(sender, nonce, encryptedKeys, toEncrypt, new byte[0]); 57 | 58 | final EncryptedPayload processed = Serializer.deserialize( 59 | HttpContentType.CBOR, 60 | EncryptedPayload.class, 61 | Serializer.serialize(HttpContentType.CBOR, original)); 62 | 63 | assertEquals(original, processed); 64 | } 65 | 66 | static class DummyObject implements Serializable { 67 | public final String name; 68 | public final int age; 69 | 70 | DummyObject() { 71 | this.name = "john"; 72 | this.age = 42; 73 | } 74 | 75 | @Override 76 | public boolean equals(final Object o) { 77 | if (this == o) { 78 | return true; 79 | } 80 | if (o == null || getClass() != o.getClass()) { 81 | return false; 82 | } 83 | final DummyObject that = (DummyObject) o; 84 | return age == that.age && Objects.equals(name, that.name); 85 | } 86 | 87 | @Override 88 | public int hashCode() { 89 | int result = name.hashCode(); 90 | result = 31 * result + age; 91 | return result; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/test/resources/alwaysSendToKeyStoreTest.toml: -------------------------------------------------------------------------------- 1 | # Test file with only mandatory fields for testing default values 2 | nodeurl = "http://127.0.0.1:9001/" 3 | nodeport = 9001 4 | clienturl = "http://127.0.0.1:9002/" 5 | clientport = 9002 6 | alwayssendto = ["tm1.pub", "tm1a.pub"] 7 | workdir= "keys" 8 | -------------------------------------------------------------------------------- /src/test/resources/defaultConfigTest.toml: -------------------------------------------------------------------------------- 1 | # Test file with only mandatory fields for testing default values 2 | workdir = "data" 3 | nodeurl = "http://127.0.0.1:9001/" 4 | nodeport = 9001 5 | clienturl = "http://127.0.0.1:9002/" 6 | clientport = 9002 7 | -------------------------------------------------------------------------------- /src/test/resources/fullConfigMissingStoragePathTest.toml: -------------------------------------------------------------------------------- 1 | # Test file with complete config settings except the Storage, while a valid type, is missing the path 2 | nodeurl = "http://127.0.0.1:9001/" 3 | nodeport = 9001 4 | clienturl = "http://127.0.0.1:9002/" 5 | clientport = 9002 6 | workdir = "data" 7 | othernodes = ["http://127.0.0.1:9000/"] 8 | publickeys = ["foo.pub"] 9 | privatekeys = ["foo.key"] 10 | alwayssendto = ["http://127.0.0.1:9000/"] 11 | passwords = "passwords" 12 | storage = "mapdb:" 13 | tls = "off" 14 | tlsservercert = "server-cert.pem" 15 | tlsserverchain = [] 16 | tlsserverkey = "server-key.pem" 17 | tlsservertrust = "ca-or-tofu" 18 | tlsknownclients = "known-clients" 19 | tlsclientcert = "client-cert.pem" 20 | tlsclientchain = [] 21 | tlsclientkey = "client-key.pem" 22 | tlsclienttrust = "ca" 23 | tlsknownservers = "known-servers" -------------------------------------------------------------------------------- /src/test/resources/fullConfigTest.toml: -------------------------------------------------------------------------------- 1 | # Test file with complete config settings (not defaults) 2 | knownnodesstorage = "mapdb:knownnodesdb" 3 | nodeurl = "http://127.0.0.1:9001/" 4 | nodeport = 9001 5 | nodenetworkinterface = "0.0.0.0" 6 | clienturl = "http://127.0.0.1:9002/" 7 | clientport = 9002 8 | clientnetworkinterface = "127.0.0.1" 9 | workdir = "data" 10 | socket = "orion.ipc" 11 | othernodes = ["http://127.0.0.1:9000/"] 12 | publickeys = ["keys/tm1.pub"] 13 | privatekeys = ["keys/tm1.key"] 14 | alwayssendto = ["keys/tm1.pub"] 15 | passwords = "keys/password.txt" 16 | storage = "memory" 17 | tls = "off" 18 | tlsservercert = "server-cert.pem" 19 | tlsserverchain = [] 20 | tlsserverkey = "server-key.pem" 21 | tlsservertrust = "ca-or-tofu" 22 | tlsknownclients = "known-clients" 23 | tlsclientcert = "client-cert.pem" 24 | tlsclientchain = [] 25 | tlsclientkey = "client-key.pem" 26 | tlsclienttrust = "ca" 27 | tlsknownservers = "known-servers" 28 | libsodiumpath="/somepath" 29 | clientconnectiontls = "off" 30 | clientconnectiontlsservercert = "client-presented-cert.pem" 31 | clientconnectiontlscertchain = [] 32 | clientconnectiontlsservertrust = "ca-or-tofu" 33 | clientconnectiontlsknownclients = "client-connection-known-clients" -------------------------------------------------------------------------------- /src/test/resources/invalidConfigTest.toml: -------------------------------------------------------------------------------- 1 | # Test config with invalid config settings to test validation exception 2 | nodeurl = "htt://127.0.0.1:9001/" 3 | nodeport = 9001 4 | clienturl = "htt://127.0.0.1:9001/" 5 | clientport = 9001 6 | othernodes = ["htt://127.0.0.1:9000/", "10.1.1.1"] 7 | verbosity = 4 8 | tls = "notValid" 9 | tlsservertrust = "invalid-trust-mode" 10 | tlsclienttrust = "invalid-trust-mode" 11 | storage = "invalidStorage" 12 | publickeys = ["foo.pub"] -------------------------------------------------------------------------------- /src/test/resources/keyStoreTest.toml: -------------------------------------------------------------------------------- 1 | # Test file with only mandatory fields for testing default values 2 | nodeurl = "http://127.0.0.1:9001/" 3 | nodeport = 9001 4 | clienturl = "http://127.0.0.1:9002/" 5 | clientport = 9002 6 | publickeys = ["keys/tm1.pub"] 7 | privatekeys = ["keys/tm1.key"] 8 | -------------------------------------------------------------------------------- /src/test/resources/missingMandatoryConfigTest.toml: -------------------------------------------------------------------------------- 1 | # Test file with complete config settings except the mandatory node URL and Port, and client URL and port 2 | #nodeurl = "http://127.0.0.1:9001/" 3 | #nodeport = 9001 4 | #clienturl = "http://127.0.0.1:9002/" 5 | #clientport = 9002 6 | workdir = "data" 7 | socket = "orion.ipc" 8 | othernodes = ["http://127.0.0.1:9000/"] 9 | publickeys = ["foo.pub"] 10 | privatekeys = ["foo.key"] 11 | alwayssendto = ["http://127.0.0.1:9000/"] 12 | passwords = "passwords" 13 | storage = "memory" 14 | tls = "off" 15 | tlsservercert = "server-cert.pem" 16 | tlsserverchain = [] 17 | tlsserverkey = "server-key.pem" 18 | tlsservertrust = "ca-or-tofu" 19 | tlsknownclients = "known-clients" 20 | tlsclientcert = "client-cert.pem" 21 | tlsclientchain = [] 22 | tlsclientkey = "client-key.pem" 23 | tlsclienttrust = "ca" 24 | tlsknownservers = "known-servers" 25 | -------------------------------------------------------------------------------- /src/test/resources/multipleKeyStoreTest.toml: -------------------------------------------------------------------------------- 1 | # Test file with only mandatory fields for testing default values 2 | nodeurl = "http://127.0.0.1:9001/" 3 | nodeport = 9001 4 | clienturl = "http://127.0.0.1:9002/" 5 | clientport = 9002 6 | publickeys = ["keys/tm1.pub", "keys/tm1a.pub"] 7 | privatekeys = ["keys/tm1.key", "keys/tm1a.key"] 8 | --------------------------------------------------------------------------------