summaryrefslogtreecommitdiffstats
path: root/mobile/android/services/src/main/java/org/mozilla/gecko/browserid/JSONWebTokenUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/services/src/main/java/org/mozilla/gecko/browserid/JSONWebTokenUtils.java')
-rw-r--r--mobile/android/services/src/main/java/org/mozilla/gecko/browserid/JSONWebTokenUtils.java245
1 files changed, 0 insertions, 245 deletions
diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/browserid/JSONWebTokenUtils.java b/mobile/android/services/src/main/java/org/mozilla/gecko/browserid/JSONWebTokenUtils.java
deleted file mode 100644
index 207accc76..000000000
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/browserid/JSONWebTokenUtils.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.browserid;
-
-import org.json.simple.JSONObject;
-import org.mozilla.apache.commons.codec.binary.Base64;
-import org.mozilla.apache.commons.codec.binary.StringUtils;
-import org.mozilla.gecko.sync.ExtendedJSONObject;
-import org.mozilla.gecko.sync.NonObjectJSONException;
-import org.mozilla.gecko.sync.Utils;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.TreeMap;
-
-/**
- * Encode and decode JSON Web Tokens.
- * <p>
- * Reverse-engineered from the Node.js jwcrypto library at
- * <a href="https://github.com/mozilla/jwcrypto">https://github.com/mozilla/jwcrypto</a>
- * and informed by the informal draft standard "JSON Web Token (JWT)" at
- * <a href="http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html">http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html</a>.
- */
-public class JSONWebTokenUtils {
- public static final long DEFAULT_CERTIFICATE_DURATION_IN_MILLISECONDS = 60 * 60 * 1000;
- public static final long DEFAULT_ASSERTION_DURATION_IN_MILLISECONDS = 60 * 60 * 1000;
- public static final long DEFAULT_FUTURE_EXPIRES_AT_IN_MILLISECONDS = 9999999999999L;
- public static final String DEFAULT_CERTIFICATE_ISSUER = "127.0.0.1";
- public static final String DEFAULT_ASSERTION_ISSUER = "127.0.0.1";
-
- public static String encode(String payload, SigningPrivateKey privateKey) throws UnsupportedEncodingException, GeneralSecurityException {
- final ExtendedJSONObject header = new ExtendedJSONObject();
- header.put("alg", privateKey.getAlgorithm());
- String encodedHeader = Base64.encodeBase64URLSafeString(header.toJSONString().getBytes("UTF-8"));
- String encodedPayload = Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8"));
- ArrayList<String> segments = new ArrayList<String>();
- segments.add(encodedHeader);
- segments.add(encodedPayload);
- byte[] message = Utils.toDelimitedString(".", segments).getBytes("UTF-8");
- byte[] signature = privateKey.signMessage(message);
- segments.add(Base64.encodeBase64URLSafeString(signature));
- return Utils.toDelimitedString(".", segments);
- }
-
- public static String decode(String token, VerifyingPublicKey publicKey) throws GeneralSecurityException, UnsupportedEncodingException {
- if (token == null) {
- throw new IllegalArgumentException("token must not be null");
- }
- String[] segments = token.split("\\.");
- if (segments == null || segments.length != 3) {
- throw new GeneralSecurityException("malformed token");
- }
- byte[] message = (segments[0] + "." + segments[1]).getBytes("UTF-8");
- byte[] signature = Base64.decodeBase64(segments[2]);
- boolean verifies = publicKey.verifyMessage(message, signature);
- if (!verifies) {
- throw new GeneralSecurityException("bad signature");
- }
- String payload = StringUtils.newStringUtf8(Base64.decodeBase64(segments[1]));
- return payload;
- }
-
- /**
- * Public for testing.
- */
- @SuppressWarnings("unchecked")
- public static String getPayloadString(String payloadString, String audience, String issuer,
- Long issuedAt, long expiresAt) throws NonObjectJSONException, IOException {
- ExtendedJSONObject payload;
- if (payloadString != null) {
- payload = new ExtendedJSONObject(payloadString);
- } else {
- payload = new ExtendedJSONObject();
- }
- if (audience != null) {
- payload.put("aud", audience);
- }
- payload.put("iss", issuer);
- if (issuedAt != null) {
- payload.put("iat", issuedAt);
- }
- payload.put("exp", expiresAt);
- // TreeMap so that keys are sorted. A small attempt to keep output stable over time.
- return JSONObject.toJSONString(new TreeMap<Object, Object>(payload.object));
- }
-
- protected static String getCertificatePayloadString(VerifyingPublicKey publicKeyToSign, String email) throws NonObjectJSONException, IOException {
- ExtendedJSONObject payload = new ExtendedJSONObject();
- ExtendedJSONObject principal = new ExtendedJSONObject();
- principal.put("email", email);
- payload.put("principal", principal);
- payload.put("public-key", publicKeyToSign.toJSONObject());
- return payload.toJSONString();
- }
-
- public static String createCertificate(VerifyingPublicKey publicKeyToSign, String email,
- String issuer, long issuedAt, long expiresAt, SigningPrivateKey privateKey) throws NonObjectJSONException, IOException, GeneralSecurityException {
- String certificatePayloadString = getCertificatePayloadString(publicKeyToSign, email);
- String payloadString = getPayloadString(certificatePayloadString, null, issuer, issuedAt, expiresAt);
- return JSONWebTokenUtils.encode(payloadString, privateKey);
- }
-
- /**
- * Create a Browser ID assertion.
- *
- * @param privateKeyToSignWith
- * private key to sign assertion with.
- * @param certificate
- * to include in assertion; no attempt is made to ensure the
- * certificate is valid, or corresponds to the private key, or any
- * other condition.
- * @param audience
- * to produce assertion for.
- * @param issuer
- * to produce assertion for.
- * @param issuedAt
- * timestamp for assertion, in milliseconds since the epoch; if null,
- * no timestamp is included.
- * @param expiresAt
- * expiration timestamp for assertion, in milliseconds since the epoch.
- * @return assertion.
- * @throws NonObjectJSONException
- * @throws IOException
- * @throws GeneralSecurityException
- */
- public static String createAssertion(SigningPrivateKey privateKeyToSignWith, String certificate, String audience,
- String issuer, Long issuedAt, long expiresAt) throws NonObjectJSONException, IOException, GeneralSecurityException {
- String emptyAssertionPayloadString = "{}";
- String payloadString = getPayloadString(emptyAssertionPayloadString, audience, issuer, issuedAt, expiresAt);
- String signature = JSONWebTokenUtils.encode(payloadString, privateKeyToSignWith);
- return certificate + "~" + signature;
- }
-
- /**
- * For debugging only!
- *
- * @param input
- * certificate to dump.
- * @return non-null object with keys header, payload, signature if the
- * certificate is well-formed.
- */
- public static ExtendedJSONObject parseCertificate(String input) {
- try {
- String[] parts = input.split("\\.");
- if (parts.length != 3) {
- return null;
- }
- String cHeader = new String(Base64.decodeBase64(parts[0]));
- String cPayload = new String(Base64.decodeBase64(parts[1]));
- String cSignature = Utils.byte2Hex(Base64.decodeBase64(parts[2]));
- ExtendedJSONObject o = new ExtendedJSONObject();
- o.put("header", new ExtendedJSONObject(cHeader));
- o.put("payload", new ExtendedJSONObject(cPayload));
- o.put("signature", cSignature);
- return o;
- } catch (Exception e) {
- return null;
- }
- }
-
- /**
- * For debugging only!
- *
- * @param input certificate to dump.
- * @return true if the certificate is well-formed.
- */
- public static boolean dumpCertificate(String input) {
- ExtendedJSONObject c = parseCertificate(input);
- try {
- if (c == null) {
- System.out.println("Malformed certificate -- got exception trying to dump contents.");
- return false;
- }
- System.out.println("certificate header: " + c.getObject("header").toJSONString());
- System.out.println("certificate payload: " + c.getObject("payload").toJSONString());
- System.out.println("certificate signature: " + c.getString("signature"));
- return true;
- } catch (Exception e) {
- System.out.println("Malformed certificate -- got exception trying to dump contents.");
- return false;
- }
- }
-
- /**
- * For debugging only!
- *
- * @param input assertion to dump.
- * @return true if the assertion is well-formed.
- */
- public static ExtendedJSONObject parseAssertion(String input) {
- try {
- String[] parts = input.split("~");
- if (parts.length != 2) {
- return null;
- }
- String certificate = parts[0];
- String assertion = parts[1];
- parts = assertion.split("\\.");
- if (parts.length != 3) {
- return null;
- }
- String aHeader = new String(Base64.decodeBase64(parts[0]));
- String aPayload = new String(Base64.decodeBase64(parts[1]));
- String aSignature = Utils.byte2Hex(Base64.decodeBase64(parts[2]));
- // We do all the assertion parsing *before* dumping the certificate in
- // case there's a malformed assertion.
- ExtendedJSONObject o = new ExtendedJSONObject();
- o.put("header", new ExtendedJSONObject(aHeader));
- o.put("payload", new ExtendedJSONObject(aPayload));
- o.put("signature", aSignature);
- o.put("certificate", certificate);
- return o;
- } catch (Exception e) {
- return null;
- }
- }
-
- /**
- * For debugging only!
- *
- * @param input assertion to dump.
- * @return true if the assertion is well-formed.
- */
- public static boolean dumpAssertion(String input) {
- ExtendedJSONObject a = parseAssertion(input);
- try {
- if (a == null) {
- System.out.println("Malformed assertion -- got exception trying to dump contents.");
- return false;
- }
- dumpCertificate(a.getString("certificate"));
- System.out.println("assertion header: " + a.getObject("header").toJSONString());
- System.out.println("assertion payload: " + a.getObject("payload").toJSONString());
- System.out.println("assertion signature: " + a.getString("signature"));
- return true;
- } catch (Exception e) {
- System.out.println("Malformed assertion -- got exception trying to dump contents.");
- return false;
- }
- }
-}