Skip to content
Thomas Schwotzer edited this page Jun 9, 2023 · 18 revisions

ASAPCertificateExchange Shark Component

This library follows the Shark component concept.

Have a look at the javadoc of our component interface: SharkPKIComponent. Sourcecode is in the pki package: SharkPKIComponent

More helpful is our UsageTest that illustrates how to set up the component and call a view methods.

This library exchanges certificates during an ASAP peer encounter. This feature is available as soon as you have made this component part of your application.

SharkPeer aliceSharkPeer = new SharkTestPeerFS(ALICE_NAME, ALICE_FOLDER);
// create a component factory
SharkPKIComponentFactory certificateComponentFactory = new SharkPKIComponentFactory();
// register this component with shark peer - note: we use interface SharkPeer
sharkPeer.addComponent(certificateComponentFactory, SharkPKIComponent.class);
// get component instance - example
SharkComponent component = sharkPeer.getComponent(SharkPKIComponent.class);
// project "clean code" :) better use interfaces - unfortunately casting is unavoidable
SharkPKIComponent sharkPKIComponent = (SharkPKIComponent) component;

// add you component here
...

// launch shark peer when ready
aliceSharkPeer.start();

We are going to discuss the component interface in some more details.

Access certificates

Our understanding of a certificate is explained in chapter concepts. This library stores and exchanges ASAP certificates. A certificate is issued by a peer (more precisely: by a person owing this hardware / software combination). This issuer claims that a public key belongs to another peer (subject). There are getter-methods for all those parts. Peers can have a name beside their id. Have a look in the javadoc.

This library allows looking for a specific isser/subject combination. It also allows to find all certificates issued by or for a peer. Assumed, that Bob has signed (issued) a certificate for Alice. Alice would be subject and Bob _issuer. All methods below would produce the same certificate:

// get specific certificate issued by Bob for Alice
ASAPCertificate oneCertificate = aliceComponent.getCertificateByIssuerAndSubject(BOB_ID, ALICE_ID);

// get all certificates issued by Bob
Collection<ASAPCertificate> collectionOfCerts = aliceComponent.getCertificatesByIssuer(BOB_ID);

// get all certificates issued for Alice
collectionOfCerts = aliceComponent.getCertificatesBySubject(ALICE_ID);

Your applications do not necessarily create certificates even if they include this PKI component. Those applications would expect that another component (which is part of this application or not) already provided certificates. Can be a good assumption.

In that case, the PKI component would still disseminate certificates during an peer encounter. It capability to issue certificates would not be used, though. You can ignore the following sections.

Certificate creation

Certificate creation does not require a lot of code. It is not even a very complex algorithm. Even more, our PKI components provides all required methods to create and verify certificates.

Nevertheless, is must be implement with great care. Lets go into details.

A certificate is a statement. A person, not a machine of any kind, certifies that a given public key belongs to another person or device. Shark assumes a highly dynamic mobile environment. Applications developers can decide to offer a function that their user can certify each other. That would support the very idea of Shark - being a fully decentralized mobile P2P platform. You are strongly encouraged to allow users issuing certificates for each other.

Creating a certificates is performed in a few steps.

step 1 - send a credential message

A peer (let's call it Alice) sends must send at least its id and its subject to to another peer (let's call it Bob). We call this data structure a CredentialMessage. Alice wants Bob to certify their data by sending their information.

Peers send such a credential message during their first encounter. This behaviour can be switch off and on (default is on):

// switch on: Peer Alice sends a credential message during each first encounter
aliceComponent.setBehaviour(BEHAVIOUR_SEND_CREDENTIAL_FIRST_ENCOUNTER, true);

Nevertheless, developers can force the PKI component to send a credential message anyway.

// switch on: Peer Alice sends a credential message during each first encounter
aliceComponent.sendOnlineCredentialMessage();

A credential message is sent to all peers which are connected in that moment.

step 2 - receive credential messages

We have to implement a few lines of code to receive credential messages. The following lines are copied from a test scenario

private class CredentialListenerExample implements SharkCredentialReceivedListener {
    private SharkPKIComponent sharkPKIComponent;
    public CredentialListenerExample(SharkPKIComponent sharkPKIComponent) {
        this.sharkPKIComponent = sharkPKIComponent;
    }

    public void credentialReceived(CredentialMessage credentialMessage) {
        Log.writeLog(this, "credentialReceived called");
        // TODO - let user decide what to do - create certificate or not
    }
}

We need to implement a class which instance will handle incomming credential messages. This example does nothing but writing a log that a message was received. That's not sufficient but a template. This template suggest a constructor requiring a reference to our PKI component. That's necessary in most cases - we will see a few lines later.

An instance needs to be created and linked with our PKI component.

SharkCredentialReceivedListener aliceCMListener = new CredentialListenerExample(aliceComponent);
aliceComponent.setSharkCredentialReceivedListener(aliceCMListener);

Now, credentialReceived() of aliceCMListener is called whenever a credential messages is received by peer Alice. What to do with that message?

step 3: Ensure identity

That is the most critical part. Unfortunately, we cannot provide any help by implementing that behaviour. The implementation of that process will decide whether your application is considered to be safe or not.

What has to be done:

  1. Credential message content is to be presented to applications user.
  2. Our application user must must ensure if the other person is actually really who s/he claims to be. This can be done by presenting an ID when we issue certificates for persons.

We need to make it crystal clear to our users that they have to take this part seriously. We all know what difficult task it is to make our users to focus. Anyway, we have to do implement that miracle in some way. (More background)

  1. Finally, our users make a decision: accept or deny.

step 4: Issue a certificate

Actually creating a certificate is a single line of code; we add that line to our listener example:

private class CredentialListenerExample implements SharkCredentialReceivedListener {
    private SharkPKIComponent sharkPKIComponent;
    public CredentialListenerExample(SharkPKIComponent sharkPKIComponent) {
        this.sharkPKIComponent = sharkPKIComponent;
    }

    public void credentialReceived(CredentialMessage credentialMessage) {
        Log.writeLog(this, "credentialReceived called");
        // here is your code that nudges your users to check others peer identity.
        
        // create certificate
        this.sharkPKIComponent.acceptAndSignCredential(credentialMessage);
    }
}

That's it. A new certificate is created and signed with your Shark peer. It is immediately transmitted to all peer to which a connection is established. It is also transmitted during upcomming encounters.

Certificates are automatically removed when they become invalid (default: one year).

Certificate management

[TODO]