View Javadoc
1   /**
2    * Portions of this software was developed by employees of the National Institute
3    * of Standards and Technology (NIST), an agency of the Federal Government and is
4    * being made available as a public service. Pursuant to title 17 United States
5    * Code Section 105, works of NIST employees are not subject to copyright
6    * protection in the United States. This software may be subject to foreign
7    * copyright. Permission in the United States and in foreign countries, to the
8    * extent that NIST may hold copyright, to use, copy, modify, create derivative
9    * works, and distribute this software and its documentation without fee is hereby
10   * granted on a non-exclusive basis, provided that this notice and disclaimer
11   * of warranty appears in all copies.
12   *
13   * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
14   * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
15   * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
17   * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
18   * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE.  IN NO EVENT
19   * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
20   * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
21   * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
22   * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
23   * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
24   * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
25   */
26  
27  package gov.nist.secauto.swid.client.service;
28  
29  import gov.nist.secauto.swid.client.totp.Totp;
30  
31  import org.apache.commons.codec.binary.Base64;
32  import org.apache.http.Consts;
33  import org.apache.http.HttpResponse;
34  import org.apache.http.NameValuePair;
35  import org.apache.http.client.entity.UrlEncodedFormEntity;
36  import org.apache.http.client.methods.HttpPost;
37  import org.apache.http.impl.client.CloseableHttpClient;
38  import org.apache.http.message.BasicNameValuePair;
39  import org.apache.logging.log4j.LogManager;
40  import org.apache.logging.log4j.Logger;
41  import org.json.simple.JSONObject;
42  import org.json.simple.parser.JSONParser;
43  import org.json.simple.parser.ParseException;
44  
45  import java.io.BufferedReader;
46  import java.io.IOException;
47  import java.io.InputStreamReader;
48  import java.security.KeyManagementException;
49  import java.security.KeyStoreException;
50  import java.security.NoSuchAlgorithmException;
51  import java.security.UnrecoverableKeyException;
52  import java.security.cert.CertificateException;
53  import java.util.ArrayList;
54  import java.util.List;
55  
56  public class LoginServiceImpl implements LoginService {
57  
58    private static final Logger LOG = LogManager.getLogger(LoginServiceImpl.class);
59  
60    public static final String LOGIN_ENDPOINT = "/service/rest/external/client/login";
61  
62    /**
63     * 
64     * @param client
65     *          the Http Client
66     * @param passwordSeed
67     *          the password seed for the client
68     * @return the reponse
69     * @throws KeyStoreException
70     *           if there are errors with loading client certificate
71     * @throws NoSuchAlgorithmException
72     *           if there are errors
73     * @throws CertificateException
74     *           if there are errors with loading client certificate
75     * @throws IOException
76     *           if there are errors with read or write
77     * @throws KeyManagementException
78     *           if there are errors with certificate
79     * @throws UnrecoverableKeyException
80     *           if there are errors with loading client certificate
81     */
82    @Override
83    public String login(CloseableHttpClient client, String passwordSeed) throws KeyStoreException,
84        NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException, UnrecoverableKeyException {
85  
86      LOG.info("Submitting authentication request ");
87      String oneTimePassword = generateOneTimePassword(passwordSeed);
88      String response = this.callEndPoint(client, oneTimePassword);
89      JSONParser parser = new JSONParser();
90      JSONObject jsonObject = null;
91      try {
92        jsonObject = (JSONObject) parser.parse(response);
93        LOG.info("User Authenticated:" + response);
94      } catch (ParseException ex) {
95        LOG.error("Failed Authentication Response :" + response);
96      }
97      String token = null;
98      if (jsonObject != null) {
99        token = (String) jsonObject.get("jwt");
100     }
101 
102     return token;
103 
104   }
105 
106   /**
107    * Generate one time password based on password seed
108    * 
109    * @param passwordSeed
110    * @return
111    */
112   private String generateOneTimePassword(String passwordSeed) {
113     Totpwid/client/totp/Totp.html#Totp">Totp totp = new Totp(gov.nist.secauto.swid.client.totp.Hotp.HashAlgorithm.SHA256, 8);
114     Base64 decoder = new Base64();
115     return totp.totp(decoder.decode(passwordSeed));
116 
117   }
118 
119   /**
120    * Set parameters and execute the Client request for login
121    * 
122    * @param aHTTPClient
123    *          the http client
124    * @param aEndPointURL
125    *          the login URL
126    * @param password
127    *          the password
128    * @return the response
129    */
130   private String callEndPoint(CloseableHttpClient aHTTPClient, String password) throws IOException {
131     String response = "";
132     try {
133       String loginEndpoint = getLoginEndpoint();
134       LOG.info("Attempting to authenticate using rest service: " + loginEndpoint);
135       HttpPost post = new HttpPost(loginEndpoint);
136       post.setHeader("Accept", "application/json");
137       post.setHeader("Content-type", "application/x-www-form-urlencoded");
138 
139       List<NameValuePair> nvList = new ArrayList<NameValuePair>();
140       nvList.add(new BasicNameValuePair("password", password));
141       post.setEntity(new UrlEncodedFormEntity(nvList, Consts.UTF_8));
142       HttpResponse httpResponse = aHTTPClient.execute(post);
143       LOG.info("Response Status: " + httpResponse.getStatusLine());
144       BufferedReader rd = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
145       response = rd.readLine();
146 
147     } catch (IOException ex) {
148       LOG.error("Unable to authenticate using login rest service, " + ex.getMessage());
149       throw ex;
150     }
151     return response;
152   }
153 
154   /**
155    * Return the endpoint for login
156    * 
157    * @return the login endpoint
158    */
159   private String getLoginEndpoint() {
160 
161     return "https://" + Action.getHostName() + LOGIN_ENDPOINT;
162   }
163 
164 }