package won.cryptography.service;
import org.apache.http.conn.ssl.PrivateKeyStrategy;
import org.apache.http.conn.ssl.TrustStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import won.cryptography.ssl.*;
import won.protocol.rest.LinkedDataRestBridge;
import won.protocol.rest.LinkedDataRestClient;
import won.protocol.rest.LinkedDataRestClientHttps;
import javax.annotation.PostConstruct;
/**
* User: ypanchenko
* Date: 07.10.2015
*/
public class DefaultSecurityWonTransmissionService implements WonTransmissionService
{
private final Logger logger = LoggerFactory.getLogger(getClass());
private LinkedDataRestClient linkedDataClient;
private LinkedDataRestBridge linkedDataRestBridge;
private String registrationQuery;
private RegistrationClient registrationClient;
private RegistrationServer registrationServer;
private MessagingContext clientMessagingContext;
private CryptographyService clientCryptographyService;
// The same trustStoreService is used both when acting as client and as server.
private TrustStoreService trustStoreService;
// For the client we have a key store, that is not updated in case of node and matcher, and is
// updated in case of owner (we add needs' keys)
private KeyStoreService clientKeyStoreService;
// TODO For the server we have a keystore that won't be changed or updated, so it can be used directly. In the
// current implementation, the server's key store is different from the store that server uses when it itself
// serves as client (see client key store).
// It would be more 'pretty' if we wrap the server's key store into storeService as well, but because it can be in
// another format than our clientKeyStore supports, we don't do it at the moment. Instead, the server keystore
// is provided directly - in server.xml and in activemq.xml
// private KeyStoreService serverKeyStoreService;
public void setTrustStoreService(final TrustStoreService trustStoreService) {
this.trustStoreService = trustStoreService;
}
public void setClientKeyStoreService(final KeyStoreService clientKeyStoreService) {
this.clientKeyStoreService = clientKeyStoreService;
}
//TODO can we make this part of the node information service and instead of configuring here, the registration
//client will register using call to e.g. register(won-node, registrationQuery) directly
public void setRegistrationQuery(final String registrationQuery) {
this.registrationQuery = registrationQuery;
}
/**
* Initializes necessary for WON transmission properties according to the default security settings that can be
* described shortly as:
* 1. ssl/tls enabled on http (server authentication) and messaging/activemq (server and client authentication)
* 2. during linked data requests client trusts all the servers
* 3. during linked data requests client can provide his certificate to prove his WebID identity if server requires
* 4. during registration parties exchange certificates after which they trust each other (those certificates)
* 5. during messaging parties only trust each other if they already know each other certificates (according to 4)
*/
@PostConstruct
public void initialize() {
//----------CRYPTOGRAPHY SERVICE--------
// Many components (e.g. Signature checking and Key adding processor) rely on the cryptography service pointing
// to the correct key store (where also the default application certificate is expected to be found) and applying
// the correct (supported in WON) key pair and certificate generation. It has to be initialized as first, because
// it will create the default certificate for the key store if not present.
clientCryptographyService = new CryptographyService(clientKeyStoreService, new KeyPairService(), new CertificateService());
//----------CRYPTOGRAPHY SERVICE--------
//---------------LINKED DATA---------------
// LINKED DATA client-side (for accessing linked data on Node with GET):
TrustStrategy linkedDataClientStrategy = new TrustAnyCertificateStrategy();
//this.linkedDataClientStrategy = new TrustSelfSignedStrategy();
//this.linkedDataClientStrategy = new TrustNooneStrategy();
this.linkedDataClient = new LinkedDataRestClientHttps(clientKeyStoreService,
trustStoreService, linkedDataClientStrategy);
// temporary client to access response of linked data resources of node -
// here uses the same key/trust setting as linkedDataClient
this.linkedDataRestBridge = new LinkedDataRestBridge(clientKeyStoreService,
trustStoreService, linkedDataClientStrategy);
// LINKED DATA server-side:
// Server-side is configured via Filters that do access control and WebID verification in spring/node-context.xml
// at Node (won-node-webapp). Because of such WebID-based access restrictions to some of the linked data resources,
// the linked data client specified above should be HTTPS client able to prove its WebID identity.
//---------------LINKED DATA---------------
//---------------REGISTRATION---------------
// REGISTRATION client-side:
TOFUStrategy registrationClientStrategy = new TOFUStrategy();
registrationClientStrategy.setTrustStoreService(trustStoreService);
registrationClientStrategy.setAliasGenerator(new AliasFromFingerprintGenerator());
PrivateKeyStrategy clientDefaultAliasKeyStrategy = new
PredefinedAliasPrivateKeyStrategy(clientKeyStoreService.getDefaultAlias());
this.registrationClient = new RegistrationRestClientHttps(clientKeyStoreService, clientDefaultAliasKeyStrategy,
trustStoreService,
registrationClientStrategy,
registrationQuery);
// REGISTRATION server-side:
TOFUStrategy registrationServerStrategy = new TOFUStrategy();
registrationServerStrategy.setTrustStoreService(trustStoreService);
registrationServerStrategy.setAliasGenerator(new AliasFromFingerprintGenerator());
this.registrationServer = new RegistrationServerCertificateBased(registrationServerStrategy);
//---------------REGISTRATION---------------
//---------------MESSAGING---------------
// MESSAGING client-side:
//TODO ?TrustFromStoreServiceStrategy
this.clientMessagingContext = new MessagingContext(this.clientKeyStoreService, clientDefaultAliasKeyStrategy,
this.trustStoreService);
// MESSAGING server-side:
// the server's (broker) activemq config is currently configured in <broker> in xml where the keystore to use and
// defined trustmanager to use are located. The web server's (in our case tomcat) config is defined in server.xml
// and defines the key store to use as well as trust configuration - in our case it trusts all self-signed
// certificates. The same server's private key (same keystore) is used for broker and for web-server -
// it is different from the keystore that we use when the server serves as client (i.e. serves as
// producer/consumer/http client).
//---------------MESSAGING---------------
}
@Override
public MessagingContext getClientMessagingContext() {
return clientMessagingContext;
}
@Override
public RegistrationClient getRegistrationClient() {
return registrationClient;
}
@Override
public RegistrationServer getRegistrationServer() {
return registrationServer;
}
@Override
public LinkedDataRestClient getLinkedDataClient() {
return linkedDataClient;
}
@Override
public LinkedDataRestBridge getLinkedDataRestBridge() {
return linkedDataRestBridge;
}
@Override
public CryptographyService getClientCryptographyService() {
return clientCryptographyService;
}
}