diff --git a/at_login_verify_service/.gitignore b/at_login_verify_service/.gitignore
new file mode 100644
index 0000000..f68d109
--- /dev/null
+++ b/at_login_verify_service/.gitignore
@@ -0,0 +1,29 @@
+### IntelliJ IDEA ###
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/at_login_verify_service/CONTRIBUTING.md b/at_login_verify_service/CONTRIBUTING.md
new file mode 100644
index 0000000..5ceaed0
--- /dev/null
+++ b/at_login_verify_service/CONTRIBUTING.md
@@ -0,0 +1,170 @@
+
+
+# Contributing guidelines
+
+We đź’™ [Pull Requests](https://help.github.com/articles/about-pull-requests/)
+for fixing issues or adding features. Thanks for your contribution!
+
+Please read our [code of conduct](code_of_conduct.md), which is based on
+[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](code_of_conduct.md)
+
+
+For small changes, especially documentation, you can simply use the "Edit" button
+to update the Markdown file, and start the
+[pull request](https://help.github.com/articles/about-pull-requests/) process.
+Use the preview tab in GitHub to make sure that it is properly
+formatted before committing. Please use conventional commits and follow the semantic PR format as documented
+[here](https://github.com/atsign-foundation/.github/blob/trunk/atGitHub.md#semantic-prs).
+A pull request will cause integration tests to run automatically, so please review
+the results of the pipeline and correct any mistakes that are reported.
+
+If you plan to contribute often or have a larger change to make, it is best to
+setup an environment for contribution, which is what the rest of these guidelines
+describe. The atsign-foundation GitHub organization's conventions and configurations are documented
+[here](https://github.com/atsign-foundation/.github/blob/trunk/atGitHub.md).
+
+## Development Environment Setup
+
+
+### Prerequisites
+
+ ``` sh
+ # show how to install the tools needed to work with the code here
+ ```
+
+
+### GitHub Repository Clone
+
+To prepare your dedicated GitHub repository:
+
+1. Fork in GitHub https://github.com/atsign-foundation/at_libraries
+2. Clone *your forked repository* (e.g., `git clone git@github.com:yourname/at_libraries`)
+3. Set your remotes as follows:
+
+ ```sh
+ cd at_libraries
+ git remote add upstream git@github.com:atsign-foundation/at_libraries.git
+ git remote set-url upstream --push DISABLED
+ ```
+
+ Running `git remote -v` should give something similar to:
+
+ ```text
+ origin git@github.com:yourname/at_libraries.git (fetch)
+ origin git@github.com:yourname/at_libraries.git (push)
+ upstream git@github.com:atsign-foundation/at_libraries.git (fetch)
+ upstream DISABLED (push)
+ ```
+
+ The use of `upstream --push DISABLED` is to prevent those
+ with `write` access to the main repository from accidentally pushing changes
+ directly.
+
+### Development Process
+
+1. Fetch latest changes from main repository:
+
+ ```sh
+ git fetch upstream
+ ```
+
+1. Reset your fork's `trunk` branch to exactly match upstream `trunk`:
+
+ ```sh
+ git checkout trunk
+ git reset --hard upstream/trunk
+ git push --force
+ ```
+
+ **IMPORTANT**: Do this only once, when you start working on new feature as
+ the commands above will completely overwrite any local changes in `trunk` content.
+1. Edit, edit, edit, and commit your changes to Git:
+
+ ```sh
+ # edit, edit, edit
+ git add *
+ git commit -m 'A useful commit message'
+ git push
+ ```
+
+1. How to run tests:
+
+ ``` sh
+ # explain tests here
+ ```
+
+1. Open a new Pull Request to the main repository using your `trunk` branch
+
+
+## @‎library release process
+
+The Atsign Foundation produces several widgets and libraries that the app developer
+can make use of to develop apps on @‎protocol. These libraries are developed in
+Dart & Flutter and published to [pub.dev](https://pub.dev/publishers/atsign.org/packages).
+
+![alt_text](images/image1.png "Version flow")
+
+## Following the changes
+
+The Atsign Foundation publishes libraries and widgets to
+[https://pub.dev/publishers/atsign.org/packages](https://pub.dev/publishers/atsign.org/packages).
+Each of these libraries contains a tab called “Changelog” that shows various
+published versions and a short description of what changes that went in.
+
+![alt_text](images/image2.png "Changelog screenshot")
+
+Also the “Versions” tab shows the versions published in the reverse
+chronological order.
+
+![alt_text](images/image3.png "Versions screenshot")
+
+## Reporting a bug
+
+The best place to start reporting bugs on the libraries published by
+@‎protocol would be the “View/report issues” link available on
+[pub.dev](https://pub.dev/publishers/atsign.org/packages).
+
+![alt_text](images/image4.png "View/report issues highlight")
+
+Once the link is clicked, one should be redirected to GitHub repo where the
+issue can be reported by clicking on the “New issue” button.
+
+![alt_text](images/image5.png "Issues list")
+
+Clicking on the “New issue” button should take you to the screen to choose
+where the issue is a Bug or an Enhancement.
+
+![alt_text](images/image6.png "Choose Bug report")
+
+Upon clicking on the “Get started” button against the “Bug Report” you should
+be directed to a page with a bug template provided by Atsign. Filling
+out all of the fields in the template gives Atsign a better chance to
+reproduce and fix the bug.
+
+![alt_text](images/image7.png "Filling a Bug report")
+
+## Bug fix and delivery process
+
+* Bugs will initially be placed into the Sprint Planning Board so that they
+can be triaged, estimated and scheduled.
+* Once work on a bug is scheduled one or more engineers will be assigned to
+fixing the bug, and story points will be allocated to match the time estimated
+to fix the bug.
+* Progress on fixing the bug will be updated in the associated GitHub issue,
+and reviewed during subsequent sprint planning meetings where necessary.
+* Once a fix is created we will work with the reporter to ensure that the fix
+is appropriate to their needs, and where possible this should happen prior to
+release to pub.dev
+
+## Closure of the bug
+
+* Where possible the issue associated with the bug should be closed by mutual
+consent with the reporter. This could be:
+ * The reporter closing the issue because they have found a workaround.
+ * The reporter closing the issue because they are satisfied with a fix
+ provided.
+ * A team member closes the issue after the reporter leaves a comment
+ indicating that they are happy for it to be closed.
+* If the reporter does not respond within 14 calendar days then we must assume
+that they no longer have an interest in fixing the bug and work in progress can
+be closed out at the team’s discretion.
diff --git a/at_login_verify_service/LICENSE b/at_login_verify_service/LICENSE
new file mode 100644
index 0000000..caf63d7
--- /dev/null
+++ b/at_login_verify_service/LICENSE
@@ -0,0 +1,29 @@
+BSD 3-Clause License
+
+Copyright (c) 2020, The @ Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/at_login_verify_service/README.md b/at_login_verify_service/README.md
new file mode 100644
index 0000000..2c168ab
--- /dev/null
+++ b/at_login_verify_service/README.md
@@ -0,0 +1,96 @@
+
+
+# at_login key_verification
+
+## Overview:
+
+A simple library to verify if a key exists in an atPlatform Secondary Server. This library can start REST-service for information exchange/.
+## Get started:
+
+### Pre-requisites
+Java needs to be installed
+
+### Clone it from github
+
+Feel free to fork a copy of the source from the [GitHub Repo](https://github.com/atsign-foundation/at_login)
+
+### Installation:
+
+This library is built with maven. Run the following in PROJECT_ROOT command to build the project
+
+```shell
+mvn install
+```
+### Output
+The jar executable will be generated in PROJECT_ROOT/target with the following name
+```
+atlogin-verify-service-1.0-jar-with-dependencies
+```
+
+## Usage
+
+### Staring the REST Service
+
+```shell
+java -jar target/atlogin-verify-service-1.0-jar-with-dependencies startRest
+```
+The REST Server has now been started on your localhost in port=4567
+
+### Using the REST Service
+All the end-points only accept POST Requests. Make sure to send a body with the request
+
+#### 1) Generate
+To generate a KeyValue pair of a random UUID that can be used as a verification token.
+This end-point accepts a request with a jsonBody containing an entry atsign
+
+The following shell command can be used to send a POST request to the REST end-point:
+
+```shell
+curl -i localhost:4567/generate -X POST -H 'Content-Type: application/json' -d '{"atsign":"@alice"}'
+
+```
+Response:
+```
+{"key":"public:_4d5afb79-7d0f-4b0a-b7c0-cf732d66b501.atlogin@alice","value":"e3def62c-f583-4747-a777-95091b361464"}
+```
+
+#### 2) Verify
+This end-point can to used to verify if a Key with given Value exists in an atSign's secondary. This end-point accepts a request with a jsonEncoded body that has the following fields - atsign, key, value.
+
+The following shell command can be used to send a POST request to the REST end-point:
+
+```shell
+curl -i localhost:4567/verify -X POST -H 'Content-Type: application/json' -d '{"atsign":"@libra98extended", "key":"public:_159e24c1-66b8-4889-8840-4601b489c115.atlogin@alice", "value":"b45fcf00-b89f-4ce9-8001-6bca575dd5f2"}'
+
+```
+Response Case-success:
+```
+{
+"responseType" : "success",
+"verificationStatus" : "true"
+}
+```
+Response Case-failure:
+```
+{
+"responseType" : "failure",
+"error" : "Error while verifying",
+"cause" : "java.lang.ClassCastException",
+"verificationStatus" : "false"
+}
+```
+#### 3) Stop
+This end-point STOPS the REST service. This request does not need a body
+
+The following shell command can be used to send a POST request to the REST end-point:
+```shell
+curl -i localhost:4567/stop -X POST
+```
+Response:
+```
+true
+```
+## Open source usage and contributions
+
+This is freely licensed open source code, so feel free to use it as is, suggest changes or enhancements or create your
+own version. See CONTRIBUTING.md for detailed guidance on how to setup tools, tests and make a pull request.
\ No newline at end of file
diff --git a/at_login_verify_service/SECURITY.md b/at_login_verify_service/SECURITY.md
new file mode 100644
index 0000000..6d5607a
--- /dev/null
+++ b/at_login_verify_service/SECURITY.md
@@ -0,0 +1,41 @@
+
+
+# Atsign Foundation Open Source Security Policies and Procedures
+
+This document outlines security procedures and general policies for the
+Atsign Foundation Open Source projects as found on
+https://github.com/atsign-foundation.
+
+ * [Reporting a Vulnerability](#reporting-a-vulnerability)
+ * [Disclosure Policy](#disclosure-policy)
+
+## Reporting a Vulnerability
+
+The Atsign Foundation team and community take all security vulnerabilities
+seriously. Thank you for improving the security of our open source
+software. We appreciate your efforts and responsible disclosure and will
+make every effort to acknowledge your contributions.
+
+Report security vulnerabilities by emailing the Atsign security team at:
+
+ security@atsign.com
+
+The lead maintainer will acknowledge your email within 24 hours, and will
+send a more detailed response within 48 hours indicating the next steps in
+handling your report. After the initial reply to your report, the security
+team will endeavor to keep you informed of the progress towards a fix and
+full announcement, and may ask for additional information or guidance.
+
+Please report security vulnerabilities in third-party modules to the person
+or team maintaining the module.
+
+## Disclosure Policy
+
+When the security team receives a security bug report, they will assign it
+to a primary handler. This person will coordinate the fix and release
+process, involving the following steps:
+
+ * Confirm the problem and determine the affected versions.
+ * Audit code to find any potential similar problems.
+ * Prepare fixes for all releases still under maintenance. These fixes
+ will be released as fast as possible to pub.dev where applicable.
\ No newline at end of file
diff --git a/at_login_verify_service/code_of_conduct.md b/at_login_verify_service/code_of_conduct.md
new file mode 100644
index 0000000..072d50a
--- /dev/null
+++ b/at_login_verify_service/code_of_conduct.md
@@ -0,0 +1,137 @@
+
+
+# The Atsign Foundation Code of Conduct
+
+Based on
+[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](code_of_conduct.md)
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, caste, color, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+conduct@atsign.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
+
+Community Impact Guidelines were inspired by
+[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
+
+For answers to common questions about this code of conduct, see the FAQ at
+[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
+at [https://www.contributor-covenant.org/translations][translations].
+
+[homepage]: https://www.contributor-covenant.org
+[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
+[Mozilla CoC]: https://github.com/mozilla/diversity
+[FAQ]: https://www.contributor-covenant.org/faq
+[translations]: https://www.contributor-covenant.org/translations
diff --git a/at_login_verify_service/pom.xml b/at_login_verify_service/pom.xml
new file mode 100644
index 0000000..a64c2cc
--- /dev/null
+++ b/at_login_verify_service/pom.xml
@@ -0,0 +1,108 @@
+
+ 4.0.0
+ org.atsign
+ atlogin-verify-service
+ 1.0
+
+ Archetype - main
+ https://maven.apache.org
+
+ 11
+ 11
+
+
+
+
+
+
+ maven-assembly-plugin
+
+
+ package
+
+ single
+
+
+
+
+
+
+ true
+ org.atsign.atlogin.Main
+
+
+
+ jar-with-dependencies
+
+
+
+
+
+
+ src/main/resources
+
+
+
+
+
+
+
+
+ com.sparkjava
+ spark-core
+ 2.7.2
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.14.0
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ 2.14.0
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.14.0
+
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.36
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.7.36
+
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-yaml
+ 2.14.0
+
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+
+ org.mockito
+ mockito-all
+ 1.9.5
+ test
+
+
+
+
+
diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/Main.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/Main.java
new file mode 100644
index 0000000..cf0a9d0
--- /dev/null
+++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/Main.java
@@ -0,0 +1,34 @@
+package org.atsign.atlogin;
+
+import org.atsign.atlogin.rest.AtLoginRestImpl;
+import org.atsign.atlogin.rest.AtLoginRestWrapper;
+import org.atsign.atlogin.service.AtLoginService;
+import org.atsign.atlogin.service.AtLoginServiceImpl;
+import org.atsign.atlogin.util.ConfigReader;
+import org.atsign.atlogin.util.KeyPair;
+
+import java.io.IOException;
+
+public class Main {
+
+ public static void main(String[] args) throws IOException {
+ String rootHost = ConfigReader.getProperty("rootServer", "domain");
+ String rootPort = ConfigReader.getProperty("rootServer", "port");
+ AtLoginRestWrapper restWrapper = new AtLoginRestImpl(rootHost, rootPort);
+ if ("startRest".equals(args[0])) {
+ restWrapper.start();
+ } else if ("generateAuthKeyValue".equals(args[0])) {
+ AtLoginService atLogin = new AtLoginServiceImpl(rootHost, rootPort);
+ KeyPair keyPair = atLogin.generateAuthenticationKeyAndValue(args[1]);
+ System.out.println(keyPair.toJson());
+ } else if ("verify".equals(args[0])) {
+ AtLoginService atLogin = new AtLoginServiceImpl(rootHost, rootPort);
+ if (atLogin.verifyKey(args[0], args[1], args[2])) {
+ System.out.println("Verified");
+ } else {
+ System.out.println("Verification Failed");
+ }
+ }
+
+ }
+}
diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestImpl.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestImpl.java
new file mode 100644
index 0000000..198bffb
--- /dev/null
+++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestImpl.java
@@ -0,0 +1,74 @@
+package org.atsign.atlogin.rest;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.log4j.BasicConfigurator;
+import org.atsign.atlogin.service.AtLoginServiceImpl;
+import org.atsign.atlogin.util.ErrorResponse;
+import org.atsign.atlogin.util.KeyPair;
+import org.atsign.atlogin.util.SuccessResponse;
+import spark.Spark;
+
+import java.util.Map;
+
+@SuppressWarnings("unchecked")
+public class AtLoginRestImpl implements AtLoginRestWrapper {
+ static final ObjectMapper mapper = new ObjectMapper();
+ String rootHost;
+ String rootPort;
+
+ public AtLoginRestImpl(String rootHost, String rootPort) {
+ this.rootHost = rootHost;
+ this.rootPort = rootPort;
+ }
+
+ public void start() {
+ BasicConfigurator.configure();
+ Spark.init();
+ Spark.awaitInitialization();
+
+ Spark.post("/generate", ((request, response) -> generateUuidKeypair(String.valueOf(request.body()))));
+ Spark.post("/verify", ((request, response) -> verify(request.body())));
+ Spark.post("/stop", (request, response) -> stop());
+ }
+
+ private boolean stop() {
+ Spark.stop();
+ return true;
+ }
+
+ private String verify(String body) throws JsonProcessingException {
+ Map postParams;
+ boolean isVerified;
+ try {
+ postParams = processRequestBody(body);
+ } catch (Exception e) {
+ return new ErrorResponse("Failed processing request body", e.toString()).toJson();
+ }
+
+ AtLoginServiceImpl loginService = new AtLoginServiceImpl(rootHost, rootPort);
+ try {
+ isVerified = loginService.verifyKey(postParams.get("atsign"), postParams.get("key"), postParams.get("value"));
+ } catch (Exception e) {
+ return new ErrorResponse("Error while verifying", e.toString()).toJson();
+ }
+
+ return new SuccessResponse(isVerified).toJson();
+ }
+
+ private String generateUuidKeypair(String jsonBody) throws JsonProcessingException {
+ AtLoginServiceImpl loginService = new AtLoginServiceImpl(rootHost, rootPort);
+ Map postBody = processRequestBody(jsonBody);
+ System.out.println("Generating UUID Keypair for " + postBody.get("atsign"));
+ KeyPair keyPair = loginService.generateAuthenticationKeyAndValue(postBody.get("atsign"));
+ return keyPair.toJson();
+ }
+
+ private Map processRequestBody(String jsonBody) throws JsonProcessingException {
+ Map parmsMap;
+ parmsMap = mapper.readValue(jsonBody, Map.class);
+ System.out.println("[AtVerify REST Wrapper] Request Params are: " + parmsMap);
+
+ return parmsMap;
+ }
+}
diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestWrapper.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestWrapper.java
new file mode 100644
index 0000000..e2ac803
--- /dev/null
+++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestWrapper.java
@@ -0,0 +1,11 @@
+package org.atsign.atlogin.rest;
+
+public interface AtLoginRestWrapper {
+
+ /**
+ * Starts the REST-Service for AtKey verification.
+ * Service runs on port=4567 by default.
+ * To stop this service call host:4567/stop
+ */
+ void start();
+}
diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginService.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginService.java
new file mode 100644
index 0000000..8f2a675
--- /dev/null
+++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginService.java
@@ -0,0 +1,42 @@
+package org.atsign.atlogin.service;
+
+import org.atsign.atlogin.util.AtLoginUtil;
+import org.atsign.atlogin.util.KeyPair;
+
+import java.io.IOException;
+import java.util.UUID;
+
+/**
+ * Contains methods to help login with an atSign
+ */
+public interface AtLoginService {
+
+ /**
+ * Verifies if the given key is present with the given value value for the atSign
+ *
+ * @param atSign
+ * @param key
+ * @param value
+ * @return true if the value is present in the secondary, else returns false
+ * @throws Exception the value cannot be looked up due to any network related issues
+ */
+ boolean verifyKey(String atSign, String key, String value) throws IOException;
+
+ /**
+ * Creates a KeyPair for the given atsign that can be used as authentication token.
+ * Generates a random UUID that is later formatted into an AtKey format
+ *
+ * @param atSign
+ * @return A KeyPair class with Key and Value that are ready to be put into an atSign secondary
+ */
+ default KeyPair generateAuthenticationKeyAndValue(String atSign) {
+ // Create a key in the format . format
+ // UUID is the entity and .atLogin is the namespace
+ String partKey = UUID.randomUUID() + ".atlogin";
+ KeyPair keyValue = new KeyPair();
+ keyValue.key = AtLoginUtil.formatAsHiddenPublicKey(partKey, atSign);
+ keyValue.value = UUID.randomUUID().toString();
+ return keyValue;
+ }
+
+}
diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginServiceImpl.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginServiceImpl.java
new file mode 100644
index 0000000..00328c4
--- /dev/null
+++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginServiceImpl.java
@@ -0,0 +1,101 @@
+package org.atsign.atlogin.service;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.Scanner;
+
+import static org.atsign.atlogin.util.AtLoginUtil.*;
+
+public class AtLoginServiceImpl implements AtLoginService {
+ String rootHost;
+ String rootPort;
+
+ public AtLoginServiceImpl(String rootHost, String rootPort) {
+ this.rootHost = rootHost;
+ this.rootPort = rootPort;
+ }
+
+ public boolean verifyKey(String atsign, String key, String value) throws IOException {
+ validateParameter(atsign, "atsign");
+ validateParameter(key, "key");
+ validateParameter(value, "value");
+
+ Socket secondarySocket = getSecondarySocket(atsign);
+ // lookup for key
+ String response;
+ try {
+ response = executeCommand("lookup:" + formatKey(key, atsign),
+ new PrintWriter(secondarySocket.getOutputStream()),
+ new Scanner(secondarySocket.getInputStream()));
+ response = response.replaceFirst("@data:", "");
+ } catch (Exception e){
+ System.out.println("[Verify Service] Caught Exception: " + e);
+ throw new SocketException("Unable to lookup key" + key + "on secondary");
+ }
+ System.out.println("[Verify Service] Created socket to secondary server successfully");
+ return response.equals(value);
+ }
+
+ private Socket getSecondarySocket(String atsign) throws SocketException {
+ // create socket to RootServer
+ Socket rootSocket;
+ try {
+ rootSocket = createSocket(rootHost, rootPort);
+ } catch (Exception e){
+ System.out.println("[Verify Service] Caught Exception: " + e);
+ throw new SocketException("Unable to connect to root secondary");
+ }
+ System.out.println("[Verify Service] Opened a socket to RootServer successfully");
+ // get secondary address
+ String response;
+ try {
+ response = executeCommand(formatAtsign(atsign, false),
+ new PrintWriter(rootSocket.getOutputStream()),
+ new Scanner(rootSocket.getInputStream()));
+ } catch (Exception e){
+ System.out.println("[Verify Service] Caught Exception: " + e);
+ throw new SocketException("Unable to find address for atsign: " + atsign);
+ }
+ response = response.replace("@", "");
+ String secondaryHost = response.split(":")[0];
+ String secondaryPort = response.split(":")[1];
+
+ // create socket for SecondaryServer
+ Socket secondarySocket;
+ try {
+ secondarySocket = createSocket(secondaryHost, secondaryPort);
+ } catch (Exception e){
+ System.out.println("[Verify Service] Caught Exception: " + e);
+ throw new SocketException("Unable to connect to secondary server for: " + atsign);
+ }
+ return secondarySocket;
+ }
+
+ private Socket createSocket(String host, String port) throws SocketException {
+ SocketFactory socketFactory = SSLSocketFactory.getDefault();
+ Socket socket;
+ try {
+ socket = socketFactory.createSocket(host, Integer.parseInt(port));
+ } catch (Exception e){
+ System.out.println("[Verify Service] Caught exception: " + e);
+ throw new SocketException("Unable to create socket for: host=" + host + "port=" + port);
+ }
+ return socket;
+ }
+
+ private String executeCommand(String command, PrintWriter socketWriter, Scanner socketScanner) {
+ // input atsign into the rootServer
+ String command1 = command + "\n";
+ System.out.println("[Verify Service] Executing command :" + command1);
+ socketWriter.write(command1);
+ socketWriter.flush();
+ // fetch secondary address from root server
+ String response = socketScanner.nextLine();
+ System.out.println("[Verify Service] Got response: " + response);
+ return response;
+ }
+}
\ No newline at end of file
diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/util/AtLoginUtil.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/AtLoginUtil.java
new file mode 100644
index 0000000..506b66d
--- /dev/null
+++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/AtLoginUtil.java
@@ -0,0 +1,50 @@
+package org.atsign.atlogin.util;
+
+public class AtLoginUtil {
+
+ public static String formatAsHiddenPublicKey(String key, String atSign) {
+ return "__" + key + formatAtsign(atSign, true);
+ }
+
+ /**
+ * Formats the atsign as per the requirement of the caller
+ *
+ * @param atsign the atsign that is to be formatted
+ * @param keepAtSymbol specifies the format requirement of the caller.
+ * When true: ensures atsign starts with an "@".
+ * When false: ensures atsign does not start with "@".
+ */
+ public static String formatAtsign(String atsign, boolean keepAtSymbol) {
+ if (keepAtSymbol && !atsign.startsWith("@")) {
+ return '@' + atsign;
+ } else if (!keepAtSymbol && atsign.startsWith("@")) {
+ return atsign.replaceAll("@", "");
+ }
+ return atsign;
+ }
+
+ /**
+ * Ensure that the parameter is not null or does not contain an empty value
+ *
+ * @param parameter is the parameter that is to be validated
+ * @param paramName is the name of the parameter
+ *