diff --git a/bbb-lti/grails-app/conf/BuildConfig.groovy b/bbb-lti/grails-app/conf/BuildConfig.groovy index 4a84c2785ab79613b455443f1f6ee09cdabe83cd..fa0612b02d1393ee3081ec0c79b7ba4c8636ec0a 100644 --- a/bbb-lti/grails-app/conf/BuildConfig.groovy +++ b/bbb-lti/grails-app/conf/BuildConfig.groovy @@ -59,6 +59,7 @@ grails.project.dependency.resolution = { grailsCentral() mavenCentral() // uncomment these (or add new ones) to enable remote dependency resolution from public Maven repositories + mavenRepo "https://jitpack.io" mavenRepo "http://repository.codehaus.org" mavenRepo "http://download.java.net/maven/2/" mavenRepo "http://repository.jboss.com/maven2/" @@ -66,6 +67,7 @@ grails.project.dependency.resolution = { dependencies { compile 'org.json:json:20171018' + compile 'com.github.blindsidenetworks:oauth:master-SNAPSHOT' // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes e.g. // runtime 'mysql:mysql-connector-java:5.1.29' // runtime 'org.postgresql:postgresql:9.3-1101-jdbc41' diff --git a/bbb-lti/grails-app/controllers/org/bigbluebutton/ToolController.groovy b/bbb-lti/grails-app/controllers/org/bigbluebutton/ToolController.groovy index 60c8c4dd53eee8d97aa011c0975bfec48acd5fb4..e9e50780405d60db373a11e1487977e863a6c3e4 100644 --- a/bbb-lti/grails-app/controllers/org/bigbluebutton/ToolController.groovy +++ b/bbb-lti/grails-app/controllers/org/bigbluebutton/ToolController.groovy @@ -30,6 +30,7 @@ import org.apache.commons.codec.digest.DigestUtils import net.oauth.OAuthMessage import net.oauth.signature.OAuthSignatureMethod import net.oauth.signature.HMAC_SHA1 +import net.oauth.signature.HMAC_SHA256 import org.bigbluebutton.lti.Parameter class ToolController { @@ -265,12 +266,13 @@ class ToolController { /** * Check if the passed signature is valid. + * Checks both SHA1 and SHA256 signatures. * @param method - POST or GET method used to make the request * @param URL - The target URL for the Basic LTI tool * @param conSecret - The consumer secret key * @param postProp - the parameters passed in from the tool * @param signature - the passed in signature calculated from the client - * @return - TRUE if the signatures matches the calculated signature + * @return - TRUE if the SHA1 or the SHA256 signatures match the calculated signature */ private boolean checkValidSignature(String method, String url, String conSecret, Properties postProp, String signature) { if (!ltiService.hasRestrictedAccess()) { @@ -278,14 +280,22 @@ class ToolController { } try { OAuthMessage oam = new OAuthMessage(method, url, postProp.entrySet()) - //log.debug "OAuthMessage oam = " + oam.toString() + HMAC_SHA1 hmac = new HMAC_SHA1() - //log.debug "HMAC_SHA1 hmac = " + hmac.toString() + HMAC_SHA256 hmac256 = new HMAC_SHA256() + hmac.setConsumerSecret(conSecret) - log.debug "Base Message String = [ " + hmac.getBaseString(oam) + " ]\n" + hmac256.setConsumerSecret(conSecret) + + log.debug "SHA1 Base Message String = [ " + hmac.getBaseString(oam) + " ]\n" String calculatedSignature = hmac.getSignature(hmac.getBaseString(oam)) log.debug "Calculated: " + calculatedSignature + " Received: " + signature - return calculatedSignature.equals(signature) + + log.debug "SHA256 Base Message String = [ " + hmac256.getBaseString(oam) + " ]\n" + String calculatedSignature256 = hmac256.getSignature(hmac256.getBaseString(oam)) + log.debug "Calculated: " + calculatedSignature256 + " Received: " + signature + + return calculatedSignature.equals(signature) || calculatedSignature256.equals(signature) } catch( Exception e ) { log.debug "Exception error: " + e.message return false diff --git a/bbb-lti/src/java/net/oauth/ConsumerProperties.java b/bbb-lti/src/java/net/oauth/ConsumerProperties.java deleted file mode 100644 index 7da36daa8a82f0402f21af58c5ead568c250bb5c..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/ConsumerProperties.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2007 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -/** - * A pool of OAuthConsumers that are constructed from Properties. Each consumer - * has a name, which is a property of the OAuthConsumer. Other properties come - * from Properties whose names are prefixed with the consumer's name. For - * example, a consumer's credentials come from properties named - * [name].consumerKey and [name].consumerSecret. - * - * @author John Kristian - */ -public class ConsumerProperties { - - public static URL getResource(String name, ClassLoader loader) - throws IOException { - URL resource = loader.getResource(name); - if (resource == null) { - throw new IOException("resource not found: " + name); - } - return resource; - } - - public static Properties getProperties(URL source) throws IOException { - InputStream input = source.openStream(); - try { - Properties p = new Properties(); - p.load(input); - return p; - } finally { - input.close(); - } - } - - public ConsumerProperties(String resourceName, ClassLoader loader) - throws IOException { - this(getProperties(getResource(resourceName, loader))); - } - - public ConsumerProperties(Properties consumerProperties) { - this.consumerProperties = consumerProperties; - } - - private final Properties consumerProperties; - - private final Map<String, OAuthConsumer> pool = new HashMap<String, OAuthConsumer>(); - - /** Get the consumer with the given name. */ - public OAuthConsumer getConsumer(String name) throws MalformedURLException { - OAuthConsumer consumer; - synchronized (pool) { - consumer = pool.get(name); - } - if (consumer == null) { - consumer = newConsumer(name); - } - synchronized (pool) { - OAuthConsumer first = pool.get(name); - if (first == null) { - pool.put(name, consumer); - } else { - /* - * Another thread just constructed an identical OAuthConsumer. - * Use that one (and discard the one we just constructed). - */ - consumer = first; - } - } - return consumer; - } - - protected OAuthConsumer newConsumer(String name) - throws MalformedURLException { - String base = consumerProperties.getProperty(name - + ".serviceProvider.baseURL"); - URL baseURL = (base == null) ? null : new URL(base); - OAuthServiceProvider serviceProvider = new OAuthServiceProvider(getURL( - baseURL, name + ".serviceProvider.requestTokenURL"), getURL( - baseURL, name + ".serviceProvider.userAuthorizationURL"), - getURL(baseURL, name + ".serviceProvider.accessTokenURL")); - OAuthConsumer consumer = new OAuthConsumer(consumerProperties - .getProperty(name + ".callbackURL"), consumerProperties - .getProperty(name + ".consumerKey"), consumerProperties - .getProperty(name + ".consumerSecret"), serviceProvider); - consumer.setProperty("name", name); - if (baseURL != null) { - consumer.setProperty("serviceProvider.baseURL", baseURL); - } - for (Map.Entry prop : consumerProperties.entrySet()) { - String propName = (String) prop.getKey(); - if (propName.startsWith(name + ".consumer.")) { - String c = propName.substring(name.length() + 10); - consumer.setProperty(c, prop.getValue()); - } - } - return consumer; - } - - private String getURL(URL base, String name) throws MalformedURLException { - String url = consumerProperties.getProperty(name); - if (base != null) { - url = (new URL(base, url)).toExternalForm(); - } - return url; - } - -} diff --git a/bbb-lti/src/java/net/oauth/MessageWithBody.java b/bbb-lti/src/java/net/oauth/MessageWithBody.java deleted file mode 100644 index fc12f94131b9e51ad2cccdd951ad6a9eef38bea2..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/MessageWithBody.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.oauth; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.Collection; -import java.util.Map; - -import net.oauth.http.HttpMessage; -import net.oauth.http.HttpMessageDecoder; - -public class MessageWithBody extends OAuthMessage { - private final byte[] body; - - public MessageWithBody(String method, String URL, Collection<OAuth.Parameter> parameters, - String contentType, byte[] body) { - super(method, URL, parameters); - this.body = body; - Collection<Map.Entry<String, String>> headers = getHeaders(); - headers.add(new OAuth.Parameter(HttpMessage.ACCEPT_ENCODING, HttpMessageDecoder.ACCEPTED)); - - if (body != null) { - headers.add(new OAuth.Parameter(HttpMessage.CONTENT_LENGTH, String.valueOf(body.length))); - } - if (contentType != null) { - headers.add(new OAuth.Parameter(HttpMessage.CONTENT_TYPE, contentType)); - } - } - - public InputStream getBodyAsStream() { - return (body == null) ? null : new ByteArrayInputStream(body); - } -} diff --git a/bbb-lti/src/java/net/oauth/OAuth.java b/bbb-lti/src/java/net/oauth/OAuth.java deleted file mode 100644 index e042aa331932e22a8eb32b136899410c24ac0668..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/OAuth.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2007 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author John Kristian - */ -public class OAuth { - - public static final String VERSION_1_0 = "1.0"; - - /** The encoding used to represent characters as bytes. */ - public static final String ENCODING = "UTF-8"; - - /** The MIME type for a sequence of OAuth parameters. */ - public static final String FORM_ENCODED = "application/x-www-form-urlencoded"; - - public static final String OAUTH_CONSUMER_KEY = "oauth_consumer_key"; - public static final String OAUTH_TOKEN = "oauth_token"; - public static final String OAUTH_TOKEN_SECRET = "oauth_token_secret"; - public static final String OAUTH_SIGNATURE_METHOD = "oauth_signature_method"; - public static final String OAUTH_SIGNATURE = "oauth_signature"; - public static final String OAUTH_TIMESTAMP = "oauth_timestamp"; - public static final String OAUTH_NONCE = "oauth_nonce"; - public static final String OAUTH_VERSION = "oauth_version"; - public static final String OAUTH_CALLBACK = "oauth_callback"; - public static final String OAUTH_BODY_HASH = "oauth_body_hash"; - - public static final String HMAC_SHA1 = "HMAC-SHA1"; - public static final String RSA_SHA1 = "RSA-SHA1"; - - /** - * Strings used for <a href="http://wiki.oauth.net/ProblemReporting">problem - * reporting</a>. - */ - public static class Problems { - public static final String VERSION_REJECTED = "version_rejected"; - public static final String PARAMETER_ABSENT = "parameter_absent"; - public static final String PARAMETER_REJECTED = "parameter_rejected"; - public static final String TIMESTAMP_REFUSED = "timestamp_refused"; - public static final String NONCE_USED = "nonce_used"; - public static final String SIGNATURE_METHOD_REJECTED = "signature_method_rejected"; - public static final String SIGNATURE_INVALID = "signature_invalid"; - public static final String CONSUMER_KEY_UNKNOWN = "consumer_key_unknown"; - public static final String CONSUMER_KEY_REJECTED = "consumer_key_rejected"; - public static final String CONSUMER_KEY_REFUSED = "consumer_key_refused"; - public static final String TOKEN_USED = "token_used"; - public static final String TOKEN_EXPIRED = "token_expired"; - public static final String TOKEN_REVOKED = "token_revoked"; - public static final String TOKEN_REJECTED = "token_rejected"; - public static final String ADDITIONAL_AUTHORIZATION_REQUIRED = "additional_authorization_required"; - public static final String PERMISSION_UNKNOWN = "permission_unknown"; - public static final String PERMISSION_DENIED = "permission_denied"; - public static final String USER_REFUSED = "user_refused"; - - public static final String OAUTH_ACCEPTABLE_VERSIONS = "oauth_acceptable_versions"; - public static final String OAUTH_ACCEPTABLE_TIMESTAMPS = "oauth_acceptable_timestamps"; - public static final String OAUTH_PARAMETERS_ABSENT = "oauth_parameters_absent"; - public static final String OAUTH_PARAMETERS_REJECTED = "oauth_parameters_rejected"; - public static final String OAUTH_PROBLEM_ADVICE = "oauth_problem_advice"; - - /** - * A map from an <a - * href="http://wiki.oauth.net/ProblemReporting">oauth_problem</a> value to - * the appropriate HTTP response code. - */ - public static final Map<String, Integer> TO_HTTP_CODE = mapToHttpCode(); - - private static Map<String, Integer> mapToHttpCode() { - Integer badRequest = new Integer(400); - Integer unauthorized = new Integer(401); - Integer serviceUnavailable = new Integer(503); - Map<String, Integer> map = new HashMap<String, Integer>(); - - map.put(Problems.VERSION_REJECTED, badRequest); - map.put(Problems.PARAMETER_ABSENT, badRequest); - map.put(Problems.PARAMETER_REJECTED, badRequest); - map.put(Problems.TIMESTAMP_REFUSED, badRequest); - map.put(Problems.SIGNATURE_METHOD_REJECTED, badRequest); - - map.put(Problems.NONCE_USED, unauthorized); - map.put(Problems.TOKEN_USED, unauthorized); - map.put(Problems.TOKEN_EXPIRED, unauthorized); - map.put(Problems.TOKEN_REVOKED, unauthorized); - map.put(Problems.TOKEN_REJECTED, unauthorized); - map.put("token_not_authorized", unauthorized); - map.put(Problems.SIGNATURE_INVALID, unauthorized); - map.put(Problems.CONSUMER_KEY_UNKNOWN, unauthorized); - map.put(Problems.CONSUMER_KEY_REJECTED, unauthorized); - map.put(Problems.ADDITIONAL_AUTHORIZATION_REQUIRED, unauthorized); - map.put(Problems.PERMISSION_UNKNOWN, unauthorized); - map.put(Problems.PERMISSION_DENIED, unauthorized); - - map.put(Problems.USER_REFUSED, serviceUnavailable); - map.put(Problems.CONSUMER_KEY_REFUSED, serviceUnavailable); - return Collections.unmodifiableMap(map); - } - - } - - /** Return true if the given Content-Type header means FORM_ENCODED. */ - public static boolean isFormEncoded(String contentType) { - if (contentType == null) { - return false; - } - int semi = contentType.indexOf(";"); - if (semi >= 0) { - contentType = contentType.substring(0, semi); - } - return FORM_ENCODED.equalsIgnoreCase(contentType.trim()); - } - - /** - * Construct a form-urlencoded document containing the given sequence of - * name/value pairs. Use OAuth percent encoding (not exactly the encoding - * mandated by HTTP). - */ - public static String formEncode(Iterable<? extends Map.Entry> parameters) - throws IOException { - ByteArrayOutputStream b = new ByteArrayOutputStream(); - formEncode(parameters, b); - return new String(b.toByteArray()); - } - - /** - * Write a form-urlencoded document into the given stream, containing the - * given sequence of name/value pairs. - */ - public static void formEncode(Iterable<? extends Map.Entry> parameters, - OutputStream into) throws IOException { - if (parameters != null) { - boolean first = true; - for (Map.Entry parameter : parameters) { - if (first) { - first = false; - } else { - into.write('&'); - } - into.write(percentEncode(toString(parameter.getKey())) - .getBytes()); - into.write('='); - into.write(percentEncode(toString(parameter.getValue())) - .getBytes()); - } - } - } - - /** Parse a form-urlencoded document. */ - public static List<Parameter> decodeForm(String form) { - List<Parameter> list = new ArrayList<Parameter>(); - if (!isEmpty(form)) { - for (String nvp : form.split("\\&")) { - int equals = nvp.indexOf('='); - String name; - String value; - if (equals < 0) { - name = decodePercent(nvp); - value = null; - } else { - name = decodePercent(nvp.substring(0, equals)); - value = decodePercent(nvp.substring(equals + 1)); - } - list.add(new Parameter(name, value)); - } - } - return list; - } - - /** Construct a &-separated list of the given values, percentEncoded. */ - public static String percentEncode(Iterable values) { - StringBuilder p = new StringBuilder(); - for (Object v : values) { - if (p.length() > 0) { - p.append("&"); - } - p.append(OAuth.percentEncode(toString(v))); - } - return p.toString(); - } - - public static String percentEncode(String s) { - if (s == null) { - return ""; - } - try { - return URLEncoder.encode(s, ENCODING) - // OAuth encodes some characters differently: - .replace("+", "%20").replace("*", "%2A") - .replace("%7E", "~"); - // This could be done faster with more hand-crafted code. - } catch (UnsupportedEncodingException wow) { - throw new RuntimeException(wow.getMessage(), wow); - } - } - - public static String decodePercent(String s) { - try { - return URLDecoder.decode(s, ENCODING); - // This implements http://oauth.pbwiki.com/FlexibleDecoding - } catch (java.io.UnsupportedEncodingException wow) { - throw new RuntimeException(wow.getMessage(), wow); - } - } - - /** - * Construct a Map containing a copy of the given parameters. If several - * parameters have the same name, the Map will contain the first value, - * only. - */ - public static Map<String, String> newMap(Iterable<? extends Map.Entry> from) { - Map<String, String> map = new HashMap<String, String>(); - if (from != null) { - for (Map.Entry f : from) { - String key = toString(f.getKey()); - if (!map.containsKey(key)) { - map.put(key, toString(f.getValue())); - } - } - } - return map; - } - - /** Construct a list of Parameters from name, value, name, value... */ - public static List<Parameter> newList(String... parameters) { - List<Parameter> list = new ArrayList<Parameter>(parameters.length / 2); - for (int p = 0; p + 1 < parameters.length; p += 2) { - list.add(new Parameter(parameters[p], parameters[p + 1])); - } - return list; - } - - /** A name/value pair. */ - public static class Parameter implements Map.Entry<String, String> { - - public Parameter(String key, String value) { - this.key = key; - this.value = value; - } - - private final String key; - - private String value; - - public String getKey() { - return key; - } - - public String getValue() { - return value; - } - - public String setValue(String value) { - try { - return this.value; - } finally { - this.value = value; - } - } - - @Override - public String toString() { - return percentEncode(getKey()) + '=' + percentEncode(getValue()); - } - - @Override - public int hashCode() - { - final int prime = 31; - int result = 1; - result = prime * result + ((key == null) ? 0 : key.hashCode()); - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final Parameter that = (Parameter) obj; - if (key == null) { - if (that.key != null) - return false; - } else if (!key.equals(that.key)) - return false; - if (value == null) { - if (that.value != null) - return false; - } else if (!value.equals(that.value)) - return false; - return true; - } - } - - private static final String toString(Object from) { - return (from == null) ? null : from.toString(); - } - - /** - * Construct a URL like the given one, but with the given parameters added - * to its query string. - */ - public static String addParameters(String url, String... parameters) - throws IOException { - return addParameters(url, newList(parameters)); - } - - public static String addParameters(String url, - Iterable<? extends Map.Entry<String, String>> parameters) - throws IOException { - String form = formEncode(parameters); - if (form == null || form.length() <= 0) { - return url; - } else { - return url + ((url.indexOf("?") < 0) ? '?' : '&') + form; - } - } - - public static boolean isEmpty(String str) { - return (str == null) || (str.length() == 0); - } -} diff --git a/bbb-lti/src/java/net/oauth/OAuthAccessor.java b/bbb-lti/src/java/net/oauth/OAuthAccessor.java deleted file mode 100644 index 198fc84f13bae9ff956853ee7f7facc726627ca2..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/OAuthAccessor.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2007 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.net.URISyntaxException; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * Properties of one User of an OAuthConsumer. Properties may be added freely, - * e.g. to support extensions. - * - * @author John Kristian - */ -public class OAuthAccessor implements Cloneable, Serializable { - - private static final long serialVersionUID = 5590788443138352999L; - - public final OAuthConsumer consumer; - public String requestToken; - public String accessToken; - public String tokenSecret; - - public OAuthAccessor(OAuthConsumer consumer) { - this.consumer = consumer; - this.requestToken = null; - this.accessToken = null; - this.tokenSecret = null; - } - - private final Map<String, Object> properties = new HashMap<String, Object>(); - - @Override - public OAuthAccessor clone() { - try { - return (OAuthAccessor) super.clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } - - public Object getProperty(String name) { - return properties.get(name); - } - - public void setProperty(String name, Object value) { - properties.put(name, value); - } - - /** - * Construct a request message containing the given parameters but no body. - * Don't send the message, merely construct it. The caller will ordinarily - * send it, for example by calling OAuthClient.invoke or access. - * - * @param method - * the HTTP request method. If this is null, use the default - * method; that is getProperty("httpMethod") or (if that's null) - * consumer.getProperty("httpMethod") or (if that's null) - * OAuthMessage.GET. - */ - public OAuthMessage newRequestMessage(String method, String url, Collection<? extends Map.Entry> parameters, - InputStream body) throws OAuthException, IOException, URISyntaxException { - if (method == null) { - method = (String) this.getProperty("httpMethod"); - if (method == null) { - method = (String) this.consumer.getProperty("httpMethod"); - if (method == null) { - method = OAuthMessage.GET; - } - } - } - OAuthMessage message = new OAuthMessage(method, url, parameters, body); - message.addRequiredParameters(this); - return message; - } - - public OAuthMessage newRequestMessage(String method, String url, Collection<? extends Map.Entry> parameters) - throws OAuthException, IOException, URISyntaxException { - return newRequestMessage(method, url, parameters, null); - } - -} diff --git a/bbb-lti/src/java/net/oauth/OAuthConsumer.java b/bbb-lti/src/java/net/oauth/OAuthConsumer.java deleted file mode 100644 index d79a2d418ae938e6f9641ee2b4f4afe163b687cc..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/OAuthConsumer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2007 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; -import net.oauth.http.HttpMessage; - -/** - * Properties of an OAuth Consumer. Properties may be added freely, e.g. to - * support extensions. - * - * @author John Kristian - */ -public class OAuthConsumer implements Serializable { - - private static final long serialVersionUID = -2258581186977818580L; - - public final String callbackURL; - public final String consumerKey; - public final String consumerSecret; - public final OAuthServiceProvider serviceProvider; - - public OAuthConsumer(String callbackURL, String consumerKey, - String consumerSecret, OAuthServiceProvider serviceProvider) { - this.callbackURL = callbackURL; - this.consumerKey = consumerKey; - this.consumerSecret = consumerSecret; - this.serviceProvider = serviceProvider; - } - - private final Map<String, Object> properties = new HashMap<String, Object>(); - - public Object getProperty(String name) { - return properties.get(name); - } - - public void setProperty(String name, Object value) { - properties.put(name, value); - } - - /** - * The name of the property whose value is the Accept-Encoding header in - * HTTP requests. - */ - public static final String ACCEPT_ENCODING = "HTTP.header." + HttpMessage.ACCEPT_ENCODING; - - /** - * The name of the property whose value is the <a - * href="http://oauth.pbwiki.com/AccessorSecret">Accessor Secret</a>. - */ - public static final String ACCESSOR_SECRET = "oauth_accessor_secret"; - -} diff --git a/bbb-lti/src/java/net/oauth/OAuthException.java b/bbb-lti/src/java/net/oauth/OAuthException.java deleted file mode 100644 index eca9e4571514617dba17a09b45c644c357f9ab18..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/OAuthException.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2008 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package net.oauth; - -/** - * Superclass for extensions thrown by the OAuth library. - */ -public class OAuthException extends Exception { - - /** - * For subclasses only. - */ - protected OAuthException() { - } - - /** - * @param message - */ - public OAuthException(String message) { - super(message); - } - - /** - * @param cause - */ - public OAuthException(Throwable cause) { - super(cause); - } - - /** - * @param message - * @param cause - */ - public OAuthException(String message, Throwable cause) { - super(message, cause); - } - - private static final long serialVersionUID = 1L; - -} diff --git a/bbb-lti/src/java/net/oauth/OAuthMessage.java b/bbb-lti/src/java/net/oauth/OAuthMessage.java deleted file mode 100644 index 6c9fc299557bb2165d2e62bd2ac1f8f81f1e1973..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/OAuthMessage.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright 2007, 2008 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URISyntaxException; -import java.security.MessageDigest; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.oauth.client.OAuthClient; -import net.oauth.http.HttpMessage; -import net.oauth.http.HttpMessageDecoder; -import net.oauth.signature.OAuthSignatureMethod; - -/** - * A request or response message used in the OAuth protocol. - * <p> - * The parameters in this class are not percent-encoded. Methods like - * OAuthClient.invoke and OAuthResponseMessage.completeParameters are - * responsible for percent-encoding parameters before transmission and decoding - * them after reception. - * - * @author John Kristian - */ -public class OAuthMessage { - - public OAuthMessage(String method, String URL, Collection<? extends Map.Entry> parameters) { - this(method, URL, parameters, null); - } - - public OAuthMessage(String method, String URL, Collection<? extends Map.Entry> parameters, - InputStream bodyAsStream) { - this(method, URL, parameters, bodyAsStream, null); - } - - public OAuthMessage(String method, String URL, Collection<? extends Map.Entry> parameters, - InputStream bodyAsStream, String contentType) { - this.method = method; - this.URL = URL; - if (parameters == null) { - this.parameters = new ArrayList<Map.Entry<String, String>>(); - } else { - this.parameters = new ArrayList<Map.Entry<String, String>>(parameters.size()); - for (Map.Entry p : parameters) { - this.parameters.add(new OAuth.Parameter( - toString(p.getKey()), toString(p.getValue()))); - } - } - - ByteArrayInputStream bais = null; - byte[] body = null; - if( bodyAsStream != null ) { - try{ - body = getBodyAsByteArray(bodyAsStream); - - Collection<Map.Entry<String, String>> headers = getHeaders(); - headers.add(new OAuth.Parameter(HttpMessage.CONTENT_LENGTH, String.valueOf(body.length))); - headers.add(new OAuth.Parameter(HttpMessage.CONTENT_TYPE, contentType != null? contentType: "null")); - - bais = new ByteArrayInputStream(body); - }catch(Exception e){ - } - } - this.bodyAsStream = bais; - this.bodyAsByteArray = body; - - } - - private byte[] getBodyAsByteArray(InputStream bodyAsStream) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int reads; - - try { - reads = bodyAsStream.read(); - while(reads != -1){ - baos.write(reads); - reads = bodyAsStream.read(); - } - } finally { - bodyAsStream.close(); - } - return baos.toByteArray(); - } - - public String method; - public String URL; - - private final List<Map.Entry<String, String>> parameters; - private Map<String, String> parameterMap; - private boolean parametersAreComplete = false; - private final List<Map.Entry<String, String>> headers = new ArrayList<Map.Entry<String, String>>(); - private final InputStream bodyAsStream; - private final byte[] bodyAsByteArray; - - public String toString() { - return "OAuthMessage(" + method + ", " + URL + ", " + parameters + ")"; - } - - /** A caller is about to get a parameter. */ - private void beforeGetParameter() throws IOException { - if (!parametersAreComplete) { - completeParameters(); - parametersAreComplete = true; - } - } - - /** - * Finish adding parameters; for example read an HTTP response body and - * parse parameters from it. - */ - protected void completeParameters() throws IOException { - } - - public List<Map.Entry<String, String>> getParameters() throws IOException { - beforeGetParameter(); - return Collections.unmodifiableList(parameters); - } - - public void addParameter(String key, String value) { - addParameter(new OAuth.Parameter(key, value)); - } - - public void addParameter(Map.Entry<String, String> parameter) { - parameters.add(parameter); - parameterMap = null; - } - - public void addParameters( - Collection<? extends Map.Entry<String, String>> parameters) { - this.parameters.addAll(parameters); - parameterMap = null; - } - - public String getParameter(String name) throws IOException { - return getParameterMap().get(name); - } - - public String getConsumerKey() throws IOException { - return getParameter(OAuth.OAUTH_CONSUMER_KEY); - } - - public String getToken() throws IOException { - return getParameter(OAuth.OAUTH_TOKEN); - } - - public String getSignatureMethod() throws IOException { - return getParameter(OAuth.OAUTH_SIGNATURE_METHOD); - } - - public String getSignature() throws IOException { - return getParameter(OAuth.OAUTH_SIGNATURE); - } - - protected Map<String, String> getParameterMap() throws IOException { - beforeGetParameter(); - if (parameterMap == null) { - parameterMap = OAuth.newMap(parameters); - } - return parameterMap; - } - - /** - * The MIME type of the body of this message. - * - * @return the MIME type, or null to indicate the type is unknown. - */ - public String getBodyType() { - return getHeader(HttpMessage.CONTENT_TYPE); - } - - /** - * The character encoding of the body of this message. - * - * @return the name of an encoding, or "ISO-8859-1" if no charset has been - * specified. - */ - public String getBodyEncoding() { - return HttpMessage.DEFAULT_CHARSET; - } - - /** - * The value of the last HTTP header with the given name. The name is case - * insensitive. - * - * @return the value of the last header, or null to indicate that there is - * no such header in this message. - */ - public final String getHeader(String name) { - String value = null; // no such header - for (Map.Entry<String, String> header : getHeaders()) { - if (name.equalsIgnoreCase(header.getKey())) { - value = header.getValue(); - } - } - return value; - } - - /** All HTTP headers. You can add headers to this list. */ - public final List<Map.Entry<String, String>> getHeaders() { - return headers; - } - - /** - * Read the body of the HTTP request or response and convert it to a String. - * - * @return the body, or null to indicate there is no body. - */ - public final String readBodyAsString() throws IOException - { - return getBodyAsString(); - } - - /** - * Get a stream from which to read the body of the HTTP request or response. - * This is designed to support efficient streaming of a large message. - * The caller must close the returned stream, to release the underlying - * resources such as the TCP connection for an HTTP response. - * - * @return a stream from which to read the body, or null to indicate there - * is no body. - */ - public InputStream getBodyAsStream() throws IOException { - return bodyAsStream; - } - - /** - * @return the body, or null to indicate there is no body. - */ - public byte[] getBodyAsByteArray(){ - return bodyAsByteArray; - } - - /** - * @return the body, or null to indicate there is no body. - */ - public String getBodyAsString(){ - return new String(bodyAsByteArray); - } - - /** Construct a verbose description of this message and its origins. */ - public Map<String, Object> getDump() throws IOException { - Map<String, Object> into = new HashMap<String, Object>(); - dump(into); - return into; - } - - protected void dump(Map<String, Object> into) throws IOException { - into.put("URL", URL); - if (parametersAreComplete) { - try { - into.putAll(getParameterMap()); - } catch (Exception ignored) { - } - } - } - - /** - * Verify that the required parameter names are contained in the actual - * collection. - * - * @throws OAuthProblemException - * one or more parameters are absent. - * @throws IOException - */ - public void requireParameters(String... names) - throws OAuthProblemException, IOException { - Set<String> present = getParameterMap().keySet(); - List<String> absent = new ArrayList<String>(); - for (String required : names) { - if (!present.contains(required)) { - absent.add(required); - } - } - if (!absent.isEmpty()) { - OAuthProblemException problem = new OAuthProblemException(OAuth.Problems.PARAMETER_ABSENT); - problem.setParameter(OAuth.Problems.OAUTH_PARAMETERS_ABSENT, OAuth.percentEncode(absent)); - throw problem; - } - } - - /** - * Add some of the parameters needed to request access to a protected - * resource, if they aren't already in the message. - * - * @throws IOException - * @throws URISyntaxException - */ - public void addRequiredParameters(OAuthAccessor accessor) - throws OAuthException, IOException, URISyntaxException { - final Map<String, String> pMap = OAuth.newMap(parameters); - if (pMap.get(OAuth.OAUTH_TOKEN) == null && accessor.accessToken != null) { - addParameter(OAuth.OAUTH_TOKEN, accessor.accessToken); - } - final OAuthConsumer consumer = accessor.consumer; - if (pMap.get(OAuth.OAUTH_CONSUMER_KEY) == null) { - addParameter(OAuth.OAUTH_CONSUMER_KEY, consumer.consumerKey); - } - String signatureMethod = pMap.get(OAuth.OAUTH_SIGNATURE_METHOD); - if (signatureMethod == null) { - signatureMethod = (String) consumer.getProperty(OAuth.OAUTH_SIGNATURE_METHOD); - if (signatureMethod == null) { - signatureMethod = OAuth.HMAC_SHA1; - } - addParameter(OAuth.OAUTH_SIGNATURE_METHOD, signatureMethod); - } - if (pMap.get(OAuth.OAUTH_TIMESTAMP) == null) { - addParameter(OAuth.OAUTH_TIMESTAMP, (System.currentTimeMillis() / 1000) + ""); - } - if (pMap.get(OAuth.OAUTH_NONCE) == null) { - addParameter(OAuth.OAUTH_NONCE, System.nanoTime() + ""); - } - if (pMap.get(OAuth.OAUTH_VERSION) == null) { - addParameter(OAuth.OAUTH_VERSION, OAuth.VERSION_1_0); - } - if (pMap.get(OAuth.OAUTH_BODY_HASH) == null && bodyAsStream != null) { - addParameter(OAuth.OAUTH_BODY_HASH, getBodyHash() ); - } - this.sign(accessor); - } - - public String getBodyHash() - throws OAuthException{ - byte[] output; - try{ - MessageDigest md = MessageDigest.getInstance("SHA1"); - md.update(bodyAsByteArray); - output = OAuthSignatureMethod.base64Encode(md.digest()).getBytes(); - }catch(Exception e){ - throw new OAuthException("Could not compute body hash: " + e.getMessage()); - } - - return new String(output); - } - - /** - * Add a signature to the message. - * - * @throws URISyntaxException - */ - public void sign(OAuthAccessor accessor) throws IOException, - OAuthException, URISyntaxException { - OAuthSignatureMethod.newSigner(this, accessor).sign(this); - } - - /** - * Construct an HTTP request from this OAuth message. - * - * @param style - * where to put the OAuth parameters, within the HTTP request - * @deprecated use HttpMessage.newRequest - */ - public HttpMessage toHttpRequest(OAuthClient.ParameterStyle style) throws IOException { - return HttpMessage.newRequest(this, style.getReplacement()); - } - - /** - * Check that the message is valid. - * - * @throws IOException - * @throws URISyntaxException - * - * @throws OAuthProblemException - * the message is invalid - */ - public void validateMessage(OAuthAccessor accessor, OAuthValidator validator) - throws OAuthException, IOException, URISyntaxException { - validator.validateMessage(this, accessor); - } - - /** - * Construct a WWW-Authenticate or Authentication header value, containing - * the given realm plus all the parameters whose names begin with "oauth_". - */ - public String getAuthorizationHeader(String realm) throws IOException { - StringBuilder into = new StringBuilder(); - if (realm != null) { - into.append(" realm=\"").append(OAuth.percentEncode(realm)).append('"'); - } else { - into.append(" realm=\"\""); - } - beforeGetParameter(); - if (parameters != null) { - for (Map.Entry parameter : parameters) { - String name = toString(parameter.getKey()); - if (name.startsWith("oauth_")) { - if (into.length() > 0) into.append(","); - into.append(OAuth.percentEncode(name)).append("=\""); - into.append(OAuth.percentEncode(toString(parameter.getValue()))).append('"'); - } - } - } - return AUTH_SCHEME + into.toString(); - } - - /** - * Read all the data from the given stream, and close it. - * - * @return null if from is null, or the data from the stream converted to a - * String - */ - public static String readAll(InputStream from, String encoding) throws IOException - { - if (from == null) { - return null; - } - try { - StringBuilder into = new StringBuilder(); - Reader r = new InputStreamReader(from, encoding); - char[] s = new char[512]; - for (int n; 0 < (n = r.read(s));) { - into.append(s, 0, n); - } - return into.toString(); - } finally { - from.close(); - } - } - - /** - * Parse the parameters from an OAuth Authorization or WWW-Authenticate - * header. The realm is included as a parameter. If the given header doesn't - * start with "OAuth ", return an empty list. - */ - public static List<OAuth.Parameter> decodeAuthorization(String authorization) { - List<OAuth.Parameter> into = new ArrayList<OAuth.Parameter>(); - if (authorization != null) { - Matcher m = AUTHORIZATION.matcher(authorization); - if (m.matches()) { - if (AUTH_SCHEME.equalsIgnoreCase(m.group(1))) { - for (String nvp : m.group(2).split("\\s*,\\s*")) { - m = NVP.matcher(nvp); - if (m.matches()) { - String name = OAuth.decodePercent(m.group(1)); - String value = OAuth.decodePercent(m.group(2)); - into.add(new OAuth.Parameter(name, value)); - } - } - } - } - } - return into; - } - - public static final String AUTH_SCHEME = "OAuth"; - - public static final String GET = "GET"; - public static final String POST = "POST"; - public static final String PUT = "PUT"; - public static final String DELETE = "DELETE"; - - private static final Pattern AUTHORIZATION = Pattern.compile("\\s*(\\w*)\\s+(.*)"); - private static final Pattern NVP = Pattern.compile("(\\S*)\\s*\\=\\s*\"([^\"]*)\""); - - private static final String toString(Object from) { - return (from == null) ? null : from.toString(); - } - -} diff --git a/bbb-lti/src/java/net/oauth/OAuthProblemException.java b/bbb-lti/src/java/net/oauth/OAuthProblemException.java deleted file mode 100644 index a9850313299a318d0a7b5b8c5a10ac4f100a0de0..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/OAuthProblemException.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2007 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth; - -import java.util.HashMap; -import java.util.Map; -import net.oauth.http.HttpMessage; - -/** - * Describes an OAuth-related problem, using a set of named parameters. One - * parameter identifies the basic problem, and the others provide supplementary - * diagnostic information. This can be used to capture information from a - * response that conforms to the OAuth <a - * href="http://wiki.oauth.net/ProblemReporting">Problem Reporting - * extension</a>. - * - * @author John Kristian - */ -public class OAuthProblemException extends OAuthException { - - public static final String OAUTH_PROBLEM = "oauth_problem"; - - public OAuthProblemException() { - } - - public OAuthProblemException(String problem) { - super(problem); - if (problem != null) { - parameters.put(OAUTH_PROBLEM, problem); - } - } - - private final Map<String, Object> parameters = new HashMap<String, Object>(); - - @Override - public String getMessage() { - String msg = super.getMessage(); - if (msg != null) - return msg; - msg = getProblem(); - if (msg != null) - return msg; - Object response = getParameters().get(HttpMessage.RESPONSE); - if (response != null) { - msg = response.toString(); - int eol = msg.indexOf("\n"); - if (eol < 0) { - eol = msg.indexOf("\r"); - } - if (eol >= 0) { - msg = msg.substring(0, eol); - } - msg = msg.trim(); - if (msg.length() > 0) { - return msg; - } - } - response = getHttpStatusCode(); - if (response != null) { - return HttpMessage.STATUS_CODE + " " + response; - } - return null; - } - - public void setParameter(String name, Object value) { - getParameters().put(name, value); - } - - public Map<String, Object> getParameters() { - return parameters; - } - - public String getProblem() { - return (String) getParameters().get(OAUTH_PROBLEM); - } - - public int getHttpStatusCode() { - Object code = getParameters().get(HttpMessage.STATUS_CODE); - if (code == null) { - return 200; - } else if (code instanceof Number) { // the usual case - return ((Number) code).intValue(); - } else { - return Integer.parseInt(code.toString()); - } - } - - private static final long serialVersionUID = 1L; - -} diff --git a/bbb-lti/src/java/net/oauth/OAuthServiceProvider.java b/bbb-lti/src/java/net/oauth/OAuthServiceProvider.java deleted file mode 100644 index 82d5f7c28c079efca56e0c7bef4a6e6e22922390..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/OAuthServiceProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2007 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth; - -import java.io.Serializable; - -/** - * Properties of an OAuth Service Provider. - * - * @author John Kristian - */ -public class OAuthServiceProvider implements Serializable { - - private static final long serialVersionUID = 3306534392621038574L; - - public final String requestTokenURL; - public final String userAuthorizationURL; - public final String accessTokenURL; - - public OAuthServiceProvider(String requestTokenURL, - String userAuthorizationURL, String accessTokenURL) { - this.requestTokenURL = requestTokenURL; - this.userAuthorizationURL = userAuthorizationURL; - this.accessTokenURL = accessTokenURL; - } - -} diff --git a/bbb-lti/src/java/net/oauth/OAuthValidator.java b/bbb-lti/src/java/net/oauth/OAuthValidator.java deleted file mode 100644 index b7a554b8562d281b846f21cb60239084fc34cab4..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/OAuthValidator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2008 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package net.oauth; - -import java.io.IOException; -import java.net.URISyntaxException; - -/** - * An algorithm to determine whether a message has a valid signature, a correct - * version number, a fresh timestamp, etc. - * - * @author Dirk Balfanz - * @author John Kristian - */ -public interface OAuthValidator { - - /** - * Check that the given message from the given accessor is valid. - * @throws OAuthException TODO - * @throws IOException TODO - * @throws URISyntaxException - * @throws OAuthProblemException the message is invalid. - * The implementation should throw exceptions that conform to the OAuth - * <a href="http://wiki.oauth.net/ProblemReporting">Problem Reporting extension</a>. - */ - public void validateMessage(OAuthMessage message, OAuthAccessor accessor) - throws OAuthException, IOException, URISyntaxException; - -} diff --git a/bbb-lti/src/java/net/oauth/ParameterStyle.java b/bbb-lti/src/java/net/oauth/ParameterStyle.java deleted file mode 100644 index 30e2862171c617f45be3163c31702e5b4a86450c..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/ParameterStyle.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2009 John Kristian - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth; - -/** - * Where to place OAuth parameters in an HTTP message. The alternatives are - * summarized in OAuth Core section 5.2. - */ -public enum ParameterStyle { - /** - * Send parameters whose names begin with "oauth_" in an HTTP header, and - * other parameters (whose names don't begin with "oauth_") in either the - * message body or URL query string. The header formats are specified by - * OAuth Core section 5.4. - */ - AUTHORIZATION_HEADER, - - /** - * Send all parameters in the message body, with a Content-Type of - * application/x-www-form-urlencoded. - */ - BODY, - - /** Send all parameters in the query string part of the URL. */ - QUERY_STRING; -} diff --git a/bbb-lti/src/java/net/oauth/SimpleOAuthValidator.java b/bbb-lti/src/java/net/oauth/SimpleOAuthValidator.java deleted file mode 100644 index d23f53a6a849131a96249e834937f581e4807bf4..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/SimpleOAuthValidator.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2008 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package net.oauth; - -import java.util.HashSet; - -import java.util.Collections; - -import java.util.Set; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import net.oauth.signature.OAuthSignatureMethod; - -/** - * A simple OAuthValidator, which checks the version, whether the timestamp - * is close to now and the signature is valid. Each check may be overridden. - * - * @author Dirk Balfanz - * @author John Kristian - */ -public class SimpleOAuthValidator implements OAuthValidator { - - /** The default window for timestamps is 5 minutes. */ - public static final long DEFAULT_TIMESTAMP_WINDOW = 5 * 60 * 1000L; - - /** - * Names of parameters that may not appear twice in a valid message. - * This limitation is specified by OAuth Core <a - * href="http://oauth.net/core/1.0#anchor7">section 5</a>. - */ - public static final Set<String> SINGLE_PARAMETERS = constructSingleParameters(); - - private static Set<String> constructSingleParameters() { - Set<String> s = new HashSet<String>(); - for (String p : new String[] { OAuth.OAUTH_CONSUMER_KEY, OAuth.OAUTH_TOKEN, OAuth.OAUTH_TOKEN_SECRET, - OAuth.OAUTH_CALLBACK, OAuth.OAUTH_SIGNATURE_METHOD, OAuth.OAUTH_SIGNATURE, OAuth.OAUTH_TIMESTAMP, - OAuth.OAUTH_NONCE, OAuth.OAUTH_VERSION }) { - s.add(p); - } - return Collections.unmodifiableSet(s); - } - - /** - * Construct a validator that rejects messages more than five minutes out - * of date, or with a OAuth version other than 1.0, or with an invalid - * signature. - */ - public SimpleOAuthValidator() { - this(DEFAULT_TIMESTAMP_WINDOW, Double.parseDouble(OAuth.VERSION_1_0)); - } - - /** - * Public constructor. - * - * @param timestampWindowSec - * specifies, in seconds, the windows (into the past and - * into the future) in which we'll accept timestamps. - * @param maxVersion - * the maximum acceptable oauth_version - */ - public SimpleOAuthValidator(long timestampWindowMsec, double maxVersion) { - this.timestampWindow = timestampWindowMsec; - this.maxVersion = maxVersion; - } - - protected final double minVersion = 1.0; - protected final double maxVersion; - protected final long timestampWindow; - - /** {@inherit} - * @throws URISyntaxException */ - public void validateMessage(OAuthMessage message, OAuthAccessor accessor) - throws OAuthException, IOException, URISyntaxException { - checkSingleParameters(message); - validateVersion(message); - validateTimestampAndNonce(message); - validateSignature(message, accessor); - } - - /** Throw an exception if any SINGLE_PARAMETERS occur repeatedly. */ - protected void checkSingleParameters(OAuthMessage message) throws IOException, OAuthException { - // Check for repeated oauth_ parameters: - boolean repeated = false; - Map<String, Collection<String>> nameToValues = new HashMap<String, Collection<String>>(); - for (Map.Entry<String, String> parameter : message.getParameters()) { - String name = parameter.getKey(); - if (SINGLE_PARAMETERS.contains(name)) { - Collection<String> values = nameToValues.get(name); - if (values == null) { - values = new ArrayList<String>(); - nameToValues.put(name, values); - } else { - repeated = true; - } - values.add(parameter.getValue()); - } - } - if (repeated) { - Collection<OAuth.Parameter> rejected = new ArrayList<OAuth.Parameter>(); - for (Map.Entry<String, Collection<String>> p : nameToValues.entrySet()) { - String name = p.getKey(); - Collection<String> values = p.getValue(); - if (values.size() > 1) { - for (String value : values) { - rejected.add(new OAuth.Parameter(name, value)); - } - } - } - OAuthProblemException problem = new OAuthProblemException(OAuth.Problems.PARAMETER_REJECTED); - problem.setParameter(OAuth.Problems.OAUTH_PARAMETERS_REJECTED, OAuth.formEncode(rejected)); - throw problem; - } - } - - protected void validateVersion(OAuthMessage message) - throws OAuthException, IOException { - String versionString = message.getParameter(OAuth.OAUTH_VERSION); - if (versionString != null) { - double version = Double.parseDouble(versionString); - if (version < minVersion || maxVersion < version) { - OAuthProblemException problem = new OAuthProblemException(OAuth.Problems.VERSION_REJECTED); - problem.setParameter(OAuth.Problems.OAUTH_ACCEPTABLE_VERSIONS, minVersion + "-" + maxVersion); - throw problem; - } - } - } - - /** This implementation doesn't check the nonce value. */ - protected void validateTimestampAndNonce(OAuthMessage message) - throws IOException, OAuthProblemException { - message.requireParameters(OAuth.OAUTH_TIMESTAMP, OAuth.OAUTH_NONCE); - long timestamp = Long.parseLong(message.getParameter(OAuth.OAUTH_TIMESTAMP)) * 1000L; - long now = currentTimeMsec(); - long min = now - timestampWindow; - long max = now + timestampWindow; - if (timestamp < min || max < timestamp) { - OAuthProblemException problem = new OAuthProblemException(OAuth.Problems.TIMESTAMP_REFUSED); - problem.setParameter(OAuth.Problems.OAUTH_ACCEPTABLE_TIMESTAMPS, min + "-" + max); - throw problem; - } - } - - protected void validateSignature(OAuthMessage message, OAuthAccessor accessor) - throws OAuthException, IOException, URISyntaxException { - message.requireParameters(OAuth.OAUTH_CONSUMER_KEY, - OAuth.OAUTH_SIGNATURE_METHOD, OAuth.OAUTH_SIGNATURE); - OAuthSignatureMethod.newSigner(message, accessor).validate(message); - } - - protected long currentTimeMsec() { - return System.currentTimeMillis(); - } - -} diff --git a/bbb-lti/src/java/net/oauth/client/ExcerptInputStream.java b/bbb-lti/src/java/net/oauth/client/ExcerptInputStream.java deleted file mode 100644 index 480b0d2debb7eb1438462e5ff506477b0ca9c4b3..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/client/ExcerptInputStream.java +++ /dev/null @@ -1,124 +0,0 @@ -package net.oauth.client; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** A decorator that retains a copy of the first few bytes of data. */ -public class ExcerptInputStream extends FilterInputStream -{ - /** - * A marker that's appended to the excerpt if it's less than the complete - * stream. - */ - public static final byte[] ELLIPSIS = " ...".getBytes(); - - public ExcerptInputStream(InputStream in) - { - super(in); - } - - private static final int LIMIT = 1024; - - private byte[] excerpt = new byte[LIMIT + ELLIPSIS.length]; - - private int taken = 0; // bytes received from in - - private int given = Integer.MAX_VALUE; // bytes delivered to callers - - @Override - public void close() throws IOException - { - super.close(); - byte[] complete = new byte[taken]; - System.arraycopy(excerpt, 0, complete, 0, taken); - excerpt = complete; - } - - /** The first few bytes of data, plus ELLIPSIS if there are more bytes. */ - public byte[] getExcerpt() throws IOException - { - if (taken < excerpt.length) { - final int mark = Math.min(given, taken); - given = Integer.MAX_VALUE; - while (taken < excerpt.length) { - read(excerpt, taken, LIMIT - taken); - } - given = mark; - } - return excerpt; - } - - @Override - public int read(byte[] b, int offset, int length) throws IOException - { - int total = 0; - if (given < taken) { - final int e = Math.min(length, taken - given); - System.arraycopy(excerpt, given, b, offset, e); - total += e; - given += e; - if (given < taken) { - return total; - } - given = Integer.MAX_VALUE; - offset += e; - length -= e; - } - final int r = super.read(b, offset, length); - if (r > 0) { - total += r; - final int e = Math.min(r, LIMIT - taken); - if (e >= 0) { - System.arraycopy(b, offset, excerpt, taken, e); - taken += e; - if (taken >= LIMIT) { - System.arraycopy(ELLIPSIS, 0, excerpt, LIMIT, ELLIPSIS.length); - taken = excerpt.length; - } - } - } else if (taken < excerpt.length) { - byte[] complete = new byte[taken]; - System.arraycopy(excerpt, 0, complete, 0, taken); - excerpt = complete; - } - return (total > 0) ? total : r; - } - - @Override - public int read(byte[] b) throws IOException - { - return read(b, 0, b.length); - } - - @Override - public int read() throws IOException - { - byte[] b = new byte[1]; - return (read(b) <= 0) ? -1 : unsigned(b[0]); - } - - /** @return an excerpt from the data copied. */ - public static byte[] copyAll(InputStream from, OutputStream into) throws IOException - { - final ExcerptInputStream ex = new ExcerptInputStream(from); - ex.copyAll(into); - return ex.getExcerpt(); - } - - /** Copy all the data from this stream to the given output stream. */ - private void copyAll(OutputStream into) throws IOException - { - byte[] b = new byte[1024]; - for (int n; 0 < (n = read(b));) { - into.write(b, 0, n); - } - } - - private static int unsigned(byte b) - { - return (b >= 0) ? b : ((int) b) + 256; - } - -} diff --git a/bbb-lti/src/java/net/oauth/client/OAuthClient.java b/bbb-lti/src/java/net/oauth/client/OAuthClient.java deleted file mode 100644 index d470d766b46a80daaa60b77c91cc1bb6ea3a3b62..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/client/OAuthClient.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright 2007, 2008 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.client; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import net.oauth.OAuth; -import net.oauth.OAuthAccessor; -import net.oauth.OAuthConsumer; -import net.oauth.OAuthException; -import net.oauth.OAuthMessage; -import net.oauth.OAuthProblemException; -import net.oauth.http.HttpClient; -import net.oauth.http.HttpMessage; -import net.oauth.http.HttpMessageDecoder; -import net.oauth.http.HttpResponseMessage; - -/** - * Methods for an OAuth consumer to request tokens from a service provider. - * <p> - * This class can also be used to request access to protected resources, in some - * cases. But not in all cases. For example, this class can't handle arbitrary - * HTTP headers. - * <p> - * Methods of this class return a response as an OAuthMessage, from which you - * can get a body or parameters but not both. Calling a getParameter method will - * read and close the body (like readBodyAsString), so you can't read it later. - * If you read or close the body first, then getParameter can't read it. The - * response headers should tell you whether the response contains encoded - * parameters, that is whether you should call getParameter or not. - * <p> - * Methods of this class don't follow redirects. When they receive a redirect - * response, they throw an OAuthProblemException, with properties - * HttpResponseMessage.STATUS_CODE = the redirect code - * HttpResponseMessage.LOCATION = the redirect URL. Such a redirect can't be - * handled at the HTTP level, if the second request must carry another OAuth - * signature (with different parameters). For example, Google's Service Provider - * routinely redirects requests for access to protected resources, and requires - * the redirected request to be signed. - * - * @author John Kristian - */ -public class OAuthClient { - - public OAuthClient(HttpClient http) - { - this.http = http; - httpParameters.put(HttpClient.FOLLOW_REDIRECTS, Boolean.FALSE); - } - - private HttpClient http; - protected final Map<String, Object> httpParameters = new HashMap<String, Object>(); - - public void setHttpClient(HttpClient http) { - this.http = http; - } - - public HttpClient getHttpClient() { - return http; - } - - /** - * HTTP client parameters, as a map from parameter name to value. - * - * @see HttpClient for parameter names. - */ - public Map<String, Object> getHttpParameters() { - return httpParameters; - } - - /** - * Get a fresh request token from the service provider. - * - * @param accessor - * should contain a consumer that contains a non-null consumerKey - * and consumerSecret. Also, - * accessor.consumer.serviceProvider.requestTokenURL should be - * the URL (determined by the service provider) for getting a - * request token. - * @throws OAuthProblemException - * the HTTP response status code was not 200 (OK) - */ - public void getRequestToken(OAuthAccessor accessor) throws IOException, - OAuthException, URISyntaxException { - getRequestToken(accessor, null); - } - - /** - * Get a fresh request token from the service provider. - * - * @param accessor - * should contain a consumer that contains a non-null consumerKey - * and consumerSecret. Also, - * accessor.consumer.serviceProvider.requestTokenURL should be - * the URL (determined by the service provider) for getting a - * request token. - * @param httpMethod - * typically OAuthMessage.POST or OAuthMessage.GET, or null to - * use the default method. - * @throws OAuthProblemException - * the HTTP response status code was not 200 (OK) - */ - public void getRequestToken(OAuthAccessor accessor, String httpMethod) - throws IOException, OAuthException, URISyntaxException { - getRequestToken(accessor, httpMethod, null); - } - - /** Get a fresh request token from the service provider. - * - * @param accessor - * should contain a consumer that contains a non-null consumerKey - * and consumerSecret. Also, - * accessor.consumer.serviceProvider.requestTokenURL should be - * the URL (determined by the service provider) for getting a - * request token. - * @param httpMethod - * typically OAuthMessage.POST or OAuthMessage.GET, or null to - * use the default method. - * @param parameters - * additional parameters for this request, or null to indicate - * that there are no additional parameters. - * @throws OAuthProblemException - * the HTTP response status code was not 200 (OK) - */ - public void getRequestToken(OAuthAccessor accessor, String httpMethod, - Collection<? extends Map.Entry> parameters) throws IOException, - OAuthException, URISyntaxException { - accessor.accessToken = null; - accessor.tokenSecret = null; - { - // This code supports the 'Variable Accessor Secret' extension - // described in http://oauth.pbwiki.com/AccessorSecret - Object accessorSecret = accessor - .getProperty(OAuthConsumer.ACCESSOR_SECRET); - if (accessorSecret != null) { - List<Map.Entry> p = (parameters == null) ? new ArrayList<Map.Entry>( - 1) - : new ArrayList<Map.Entry>(parameters); - p.add(new OAuth.Parameter("oauth_accessor_secret", - accessorSecret.toString())); - parameters = p; - // But don't modify the caller's parameters. - } - } - OAuthMessage response = invoke(accessor, httpMethod, - accessor.consumer.serviceProvider.requestTokenURL, parameters); - accessor.requestToken = response.getParameter(OAuth.OAUTH_TOKEN); - accessor.tokenSecret = response.getParameter(OAuth.OAUTH_TOKEN_SECRET); - response.requireParameters(OAuth.OAUTH_TOKEN, OAuth.OAUTH_TOKEN_SECRET); - } - - /** - * Get an access token from the service provider, in exchange for an - * authorized request token. - * - * @param accessor - * should contain a non-null requestToken and tokenSecret, and a - * consumer that contains a consumerKey and consumerSecret. Also, - * accessor.consumer.serviceProvider.accessTokenURL should be the - * URL (determined by the service provider) for getting an access - * token. - * @param httpMethod - * typically OAuthMessage.POST or OAuthMessage.GET, or null to - * use the default method. - * @param parameters - * additional parameters for this request, or null to indicate - * that there are no additional parameters. - * @throws OAuthProblemException - * the HTTP response status code was not 200 (OK) - */ - public OAuthMessage getAccessToken(OAuthAccessor accessor, String httpMethod, - Collection<? extends Map.Entry> parameters) throws IOException, OAuthException, URISyntaxException { - if (accessor.requestToken != null) { - if (parameters == null) { - parameters = OAuth.newList(OAuth.OAUTH_TOKEN, accessor.requestToken); - } else if (!OAuth.newMap(parameters).containsKey(OAuth.OAUTH_TOKEN)) { - List<Map.Entry> p = new ArrayList<Map.Entry>(parameters); - p.add(new OAuth.Parameter(OAuth.OAUTH_TOKEN, accessor.requestToken)); - parameters = p; - } - } - OAuthMessage response = invoke(accessor, httpMethod, - accessor.consumer.serviceProvider.accessTokenURL, parameters); - response.requireParameters(OAuth.OAUTH_TOKEN, OAuth.OAUTH_TOKEN_SECRET); - accessor.accessToken = response.getParameter(OAuth.OAUTH_TOKEN); - accessor.tokenSecret = response.getParameter(OAuth.OAUTH_TOKEN_SECRET); - return response; - } - - /** - * Construct a request message, send it to the service provider and get the - * response. - * - * @param httpMethod - * the HTTP request method, or null to use the default method - * @return the response - * @throws URISyntaxException - * the given url isn't valid syntactically - * @throws OAuthProblemException - * the HTTP response status code was not 200 (OK) - */ - public OAuthMessage invoke(OAuthAccessor accessor, String httpMethod, - String url, Collection<? extends Map.Entry> parameters) - throws IOException, OAuthException, URISyntaxException { - OAuthMessage request = accessor.newRequestMessage(httpMethod, url, parameters); - Object accepted = accessor.consumer.getProperty(OAuthConsumer.ACCEPT_ENCODING); - if (accepted != null) { - request.getHeaders().add(new OAuth.Parameter(HttpMessage.ACCEPT_ENCODING, accepted.toString())); - } - Object ps = accessor.consumer.getProperty(PARAMETER_STYLE); - net.oauth.ParameterStyle style = (ps == null) ? net.oauth.ParameterStyle.BODY - : Enum.valueOf(net.oauth.ParameterStyle.class, ps.toString()); - return invoke(request, style); - } - - /** - * The name of the OAuthConsumer property whose value is the ParameterStyle - * to be used by invoke. - */ - public static final String PARAMETER_STYLE = "parameterStyle"; - - /** - * The name of the OAuthConsumer property whose value is the Accept-Encoding - * header in HTTP requests. - * @deprecated use {@link OAuthConsumer#ACCEPT_ENCODING} instead - */ - @Deprecated - public static final String ACCEPT_ENCODING = OAuthConsumer.ACCEPT_ENCODING; - - /** - * Construct a request message, send it to the service provider and get the - * response. - * - * @return the response - * @throws URISyntaxException - * the given url isn't valid syntactically - * @throws OAuthProblemException - * the HTTP response status code was not 200 (OK) - */ - public OAuthMessage invoke(OAuthAccessor accessor, String url, - Collection<? extends Map.Entry> parameters) throws IOException, - OAuthException, URISyntaxException { - return invoke(accessor, null, url, parameters); - } - - /** - * Send a request message to the service provider and get the response. - * - * @return the response - * @throws IOException - * failed to communicate with the service provider - * @throws OAuthProblemException - * the HTTP response status code was not 200 (OK) - */ - public OAuthMessage invoke(OAuthMessage request, net.oauth.ParameterStyle style) - throws IOException, OAuthException { - OAuthResponseMessage response = access(request, style); - if ((response.getHttpResponse().getStatusCode() / 100) != 2) { - throw response.toOAuthProblemException(); - } - return response; - } - - /** - * Send a request and return the response. Don't try to decide whether the - * response indicates success; merely return it. - */ - public OAuthResponseMessage access(OAuthMessage request, net.oauth.ParameterStyle style) throws IOException { - HttpMessage httpRequest = HttpMessage.newRequest(request, style); - HttpResponseMessage httpResponse = http.execute(httpRequest, httpParameters); - httpResponse = HttpMessageDecoder.decode(httpResponse); - return new OAuthResponseMessage(httpResponse); - } - - /** - * Where to place parameters in an HTTP message. - * - * @deprecated use net.oauth.ParameterStyle. - */ - public static enum ParameterStyle { - AUTHORIZATION_HEADER(net.oauth.ParameterStyle.AUTHORIZATION_HEADER), - BODY (net.oauth.ParameterStyle.BODY), - QUERY_STRING (net.oauth.ParameterStyle.QUERY_STRING); - - public net.oauth.ParameterStyle getReplacement() { - return replacement; - } - - private ParameterStyle(net.oauth.ParameterStyle replacement) { - this.replacement = replacement; - } - - private final net.oauth.ParameterStyle replacement; - } - - /** @deprecated */ - public OAuthMessage invoke(OAuthMessage request, ParameterStyle style) - throws IOException, OAuthException { - return invoke(request, style.getReplacement()); - } - - /** @deprecated */ - public OAuthResponseMessage access(OAuthMessage request, ParameterStyle style) - throws IOException { - return access(request, style.getReplacement()); - } - - protected static final String PUT = OAuthMessage.PUT; - protected static final String POST = OAuthMessage.POST; - protected static final String DELETE = OAuthMessage.DELETE; - protected static final String CONTENT_LENGTH = HttpMessage.CONTENT_LENGTH; - -} diff --git a/bbb-lti/src/java/net/oauth/client/OAuthResponseMessage.java b/bbb-lti/src/java/net/oauth/client/OAuthResponseMessage.java deleted file mode 100644 index 4adc431f8a569d857c191c82125cd7941ca7658b..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/client/OAuthResponseMessage.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2008 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.client; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import net.oauth.OAuth; -import net.oauth.OAuthMessage; -import net.oauth.OAuthProblemException; -import net.oauth.http.HttpResponseMessage; - -/** - * An HTTP response, encapsulated as an OAuthMessage. - * - * @author John Kristian - */ -public class OAuthResponseMessage extends OAuthMessage -{ - OAuthResponseMessage(HttpResponseMessage http) throws IOException - { - super(http.method, http.url.toExternalForm(), null); - this.http = http; - getHeaders().addAll(http.headers); - for (Map.Entry<String, String> header : http.headers) { - if ("WWW-Authenticate".equalsIgnoreCase(header.getKey())) { - for (OAuth.Parameter parameter : decodeAuthorization(header.getValue())) { - if (!"realm".equalsIgnoreCase(parameter.getKey())) { - addParameter(parameter); - } - } - } - } - } - - private final HttpResponseMessage http; - - public HttpResponseMessage getHttpResponse() { - return http; - } - - @Override - public InputStream getBodyAsStream() throws IOException - { - return http.getBody(); - } - - @Override - public String getBodyEncoding() - { - return http.getContentCharset(); - } - - @Override - public void requireParameters(String... names) throws OAuthProblemException, IOException { - try { - super.requireParameters(names); - } catch (OAuthProblemException problem) { - problem.getParameters().putAll(getDump()); - throw problem; - } - } - - /** - * Encapsulate this message as an exception. Read and close the body of this - * message. - */ - public OAuthProblemException toOAuthProblemException() throws IOException { - OAuthProblemException problem = new OAuthProblemException(); - try { - getParameters(); // decode the response body - } catch (IOException ignored) { - } - problem.getParameters().putAll(getDump()); - try { - InputStream b = getBodyAsStream(); - if (b != null) { - b.close(); // release resources - } - } catch (IOException ignored) { - } - return problem; - } - - @Override - protected void completeParameters() throws IOException - { - super.completeParameters(); - String body = readBodyAsString(); - if (body != null) { - addParameters(OAuth.decodeForm(body.trim())); - } - } - - @Override - protected void dump(Map<String, Object> into) throws IOException - { - super.dump(into); - http.dump(into); - } - -} diff --git a/bbb-lti/src/java/net/oauth/client/URLConnectionClient.java b/bbb-lti/src/java/net/oauth/client/URLConnectionClient.java deleted file mode 100644 index e06c7544e93f16d2e26d042fbf0088ec00229008..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/client/URLConnectionClient.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2008 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.client; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import net.oauth.http.HttpClient; -import net.oauth.http.HttpMessage; -import net.oauth.http.HttpResponseMessage; - -/** - * An HttpClient based on HttpURLConnection. - * <p> - * HttpClient3 or HttpClient4 perform better than this class, as a rule; since - * they do things like connection pooling. They also support reading the body - * of an HTTP response whose status code isn't 200 (OK), which can enable your - * application to handle problems better. - * - * @author John Kristian - */ -public class URLConnectionClient implements HttpClient { - - /** Send a message to the service provider and get the response. */ - public HttpResponseMessage execute(HttpMessage request, Map<String, Object> parameters) throws IOException { - final String httpMethod = request.method; - final Collection<Map.Entry<String, String>> addHeaders = request.headers; - final URL url = request.url; - final URLConnection connection = url.openConnection(); - connection.setDoInput(true); - if (connection instanceof HttpURLConnection) { - HttpURLConnection http = (HttpURLConnection) connection; - http.setRequestMethod(httpMethod); - for (Map.Entry<String, Object> p : parameters.entrySet()) { - String name = p.getKey(); - String value = p.getValue().toString(); - if (FOLLOW_REDIRECTS.equals(name)) { - http.setInstanceFollowRedirects(Boolean.parseBoolean(value)); - } else if (CONNECT_TIMEOUT.equals(name)) { - http.setConnectTimeout(Integer.parseInt(value)); - } else if (READ_TIMEOUT.equals(name)) { - http.setReadTimeout(Integer.parseInt(value)); - } - } - } - StringBuilder headers = new StringBuilder(httpMethod); - { - headers.append(" ").append(url.getPath()); - String query = url.getQuery(); - if (query != null && query.length() > 0) { - headers.append("?").append(query); - } - headers.append(EOL); - for (Map.Entry<String, List<String>> header : connection - .getRequestProperties().entrySet()) { - String key = header.getKey(); - for (String value : header.getValue()) { - headers.append(key).append(": ").append(value).append(EOL); - } - } - } - String contentLength = null; - for (Map.Entry<String, String> header : addHeaders) { - String key = header.getKey(); - if (HttpMessage.CONTENT_LENGTH.equalsIgnoreCase(key) - && connection instanceof HttpURLConnection) { - contentLength = header.getValue(); - } else { - connection.setRequestProperty(key, header.getValue()); - } - headers.append(key).append(": ").append(header.getValue()).append(EOL); - } - byte[] excerpt = null; - final InputStream body = request.getBody(); - if (body != null) { - try { - if (contentLength != null) { - ((HttpURLConnection) connection) - .setFixedLengthStreamingMode(Integer.parseInt(contentLength)); - } - connection.setDoOutput(true); - OutputStream output = connection.getOutputStream(); - try { - final ExcerptInputStream ex = new ExcerptInputStream(body); - byte[] b = new byte[1024]; - for (int n; 0 < (n = ex.read(b));) { - output.write(b, 0, n); - } - excerpt = ex.getExcerpt(); - } finally { - output.close(); - } - } finally { - body.close(); - } - } - return new URLConnectionResponse(request, headers.toString(), excerpt, connection); - } - - private static final String EOL = HttpResponseMessage.EOL; - -} diff --git a/bbb-lti/src/java/net/oauth/client/URLConnectionResponse.java b/bbb-lti/src/java/net/oauth/client/URLConnectionResponse.java deleted file mode 100644 index b0c989ffd73e823dcd39315e38a2000726842799..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/client/URLConnectionResponse.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2008 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.client; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import net.oauth.OAuth; -import net.oauth.http.HttpMessage; -import net.oauth.http.HttpResponseMessage; - -/** - * The response part of a URLConnection, encapsulated as an HttpMessage. - * - * @author John Kristian - */ -public class URLConnectionResponse extends HttpResponseMessage { - - /** - * Construct an OAuthMessage from the HTTP response, including parameters - * from OAuth WWW-Authenticate headers and the body. The header parameters - * come first, followed by the ones from the response body. - */ - public URLConnectionResponse(HttpMessage request, String requestHeaders, - byte[] requestExcerpt, URLConnection connection) throws IOException { - super(request.method, request.url); - this.requestHeaders = requestHeaders; - this.requestExcerpt = requestExcerpt; - this.requestEncoding = request.getContentCharset(); - this.connection = connection; - this.headers.addAll(getHeaders()); - } - - private final String requestHeaders; - private final byte[] requestExcerpt; - private final String requestEncoding; - private final URLConnection connection; - - @Override - public int getStatusCode() throws IOException { - if (connection instanceof HttpURLConnection) { - return ((HttpURLConnection) connection).getResponseCode(); - } - return STATUS_OK; - } - - @Override - public InputStream openBody() { - try { - return connection.getInputStream(); - } catch (IOException ohWell) { - } - return null; - } - - private List<Map.Entry<String, String>> getHeaders() { - List<Map.Entry<String, String>> headers = new ArrayList<Map.Entry<String, String>>(); - boolean foundContentType = false; - String value; - for (int i = 0; (value = connection.getHeaderField(i)) != null; ++i) { - String name = connection.getHeaderFieldKey(i); - if (name != null) { - headers.add(new OAuth.Parameter(name, value)); - if (CONTENT_TYPE.equalsIgnoreCase(name)) { - foundContentType = true; - } - } - } - if (!foundContentType) { - headers.add(new OAuth.Parameter(CONTENT_TYPE, connection - .getContentType())); - } - return headers; - } - /** Return a complete description of the HTTP exchange. */ - @Override - public void dump(Map<String, Object> into) throws IOException { - super.dump(into); - { - StringBuilder request = new StringBuilder(requestHeaders); - request.append(EOL); - if (requestExcerpt != null) { - request.append(new String(requestExcerpt, requestEncoding)); - } - into.put(REQUEST, request.toString()); - } - { - HttpURLConnection http = (connection instanceof HttpURLConnection) ? (HttpURLConnection) connection - : null; - StringBuilder response = new StringBuilder(); - String value; - for (int i = 0; (value = connection.getHeaderField(i)) != null; ++i) { - String name = connection.getHeaderFieldKey(i); - if (i == 0 && name != null && http != null) { - String firstLine = "HTTP " + getStatusCode(); - String message = http.getResponseMessage(); - if (message != null) { - firstLine += (" " + message); - } - response.append(firstLine).append(EOL); - } - if (name != null) { - response.append(name).append(": "); - name = name.toLowerCase(); - } - response.append(value).append(EOL); - } - response.append(EOL); - if (body != null) { - response.append(new String(((ExcerptInputStream) body) - .getExcerpt(), getContentCharset())); - } - into.put(HttpMessage.RESPONSE, response.toString()); - } - } - -} diff --git a/bbb-lti/src/java/net/oauth/consumer.properties.sample b/bbb-lti/src/java/net/oauth/consumer.properties.sample deleted file mode 100644 index ea26c9012a86663a4e96862cfc267d30ef82bbb0..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/consumer.properties.sample +++ /dev/null @@ -1,16 +0,0 @@ -# NamedConsumerPool can gets consumer configuration parameters from a file like this. - -ma.gnolia.consumerKey: - Your key here - -ma.gnolia.consumerSecret: - Your secret here - -ma.gnolia.serviceProvider.requestTokenURL: http://ma.gnolia.com/oauth/get_request_token -ma.gnolia.serviceProvider.userAuthorizationURL: http://ma.gnolia.com/oauth/authorize -ma.gnolia.serviceProvider.accessTokenURL: http://ma.gnolia.com/oauth/get_access_token - -twitter.consumerKey: - Your key here - -twitter.consumerSecret: - Your secret here - -twitter.callbackURL: - Your URL here - -twitter.consumer.oauth_signature_method: PLAINTEXT -# There can be more consumer properties. -twitter.serviceProvider.requestTokenURL: http://twitter.com/oauth/request_token -twitter.serviceProvider.userAuthorizationURL: http://twitter.com/oauth/authorize -twitter.serviceProvider.accessTokenURL: http://twitter.com/oauth/access_token diff --git a/bbb-lti/src/java/net/oauth/http/HttpClient.java b/bbb-lti/src/java/net/oauth/http/HttpClient.java deleted file mode 100644 index afd393da0ebaa199e89fb16e057bac6d6ad7675f..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/http/HttpClient.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2008 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.http; - -import java.io.IOException; -import java.util.Map; -import net.oauth.OAuthMessage; - -// TODO: move this class into oauth-core-consumer, together with HttpMessage. -// The sticky part is deleting the method OAuthMessage.toHttpRequest. -public interface HttpClient { - - /** - * Send an HTTP request and return the response. - * - * @param httpParameters - * HTTP client parameters, as a map from parameter name to value. - * Parameter names are defined as constants below. - */ - HttpResponseMessage execute(HttpMessage request, Map<String, Object> httpParameters) throws IOException; - - /** - * The name of the parameter that is the maximum time to wait to connect to - * the server. (Integer msec) - */ - static final String CONNECT_TIMEOUT = "connectTimeout"; - - /** - * The name of the parameter that is the maximum time to wait for response - * data. (Integer msec) - */ - static final String READ_TIMEOUT = "readTimeout"; - - /** The name of the parameter to automatically follow redirects. (Boolean) */ - static final String FOLLOW_REDIRECTS = "followRedirects"; - - static final String GET = OAuthMessage.GET; - static final String POST = OAuthMessage.POST; - static final String PUT = OAuthMessage.PUT; - static final String DELETE = OAuthMessage.DELETE; - -} diff --git a/bbb-lti/src/java/net/oauth/http/HttpMessage.java b/bbb-lti/src/java/net/oauth/http/HttpMessage.java deleted file mode 100644 index 749dbca18d486df8f9d21a154075fc1bfc17e0f3..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/http/HttpMessage.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2008 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.http; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import net.oauth.client.ExcerptInputStream; -import net.oauth.OAuth; -import net.oauth.OAuthMessage; -import net.oauth.ParameterStyle; - -// TODO: move this class into oauth-core-consumer, together with ExcerptInputStream. -// The sticky part is deleting the method OAuthMessage.toHttpRequest. -/** - * An HTTP request or response. - * - * @author John Kristian - */ -public class HttpMessage -{ - - public HttpMessage() - { - this(null, null); - } - - public HttpMessage(String method, URL url) - { - this(method, url, null); - } - - public HttpMessage(String method, URL url, InputStream body) - { - this.method = method; - this.url = url; - this.body = body; - } - - public String method; - public URL url; - public final List<Map.Entry<String, String>> headers = new ArrayList<Map.Entry<String, String>>(); - protected InputStream body = null; - - /** - * Get the value of the last header of the given name. The name is - * case-insensitive. - */ - public final String getHeader(String name) - { - String value = null; - for (Map.Entry<String, String> header : headers) { - if (equalsIgnoreCase(name, header.getKey())) { - value = header.getValue(); - } - } - return value; - } - - /** - * Remove all headers of the given name. The name is case insensitive. - * - * @return the value of the last header with that name, or null to indicate - * there was no such header - */ - public String removeHeaders(String name) - { - String value = null; - for (Iterator<Map.Entry<String, String>> i = headers.iterator(); i.hasNext();) { - Map.Entry<String, String> header = i.next(); - if (equalsIgnoreCase(name, header.getKey())) { - value = header.getValue(); - i.remove(); - } - } - return value; - } - - public final String getContentCharset() - { - return getCharset(getHeader(CONTENT_TYPE)); - } - - public final InputStream getBody() throws IOException - { - if (body == null) { - InputStream raw = openBody(); - if (raw != null) { - body = new ExcerptInputStream(raw); - } - } - return body; - } - - protected InputStream openBody() throws IOException - { - return null; - } - - /** Put a description of this message and its origins into the given Map. */ - public void dump(Map<String, Object> into) throws IOException - { - } - - /** - * Construct an HTTP request from this OAuth message. - * - * @param style - * where to put the OAuth parameters, within the HTTP request - */ - public static HttpMessage newRequest(OAuthMessage from, ParameterStyle style) throws IOException { - final boolean isPost = OAuthMessage.POST.equalsIgnoreCase(from.method); - InputStream body = from.getBodyAsStream(); - if (style == ParameterStyle.BODY && !(isPost && body == null)) { - style = ParameterStyle.QUERY_STRING; - } - String url = from.URL; - final List<Map.Entry<String, String>> headers = new ArrayList<Map.Entry<String, String>>(from.getHeaders()); - switch (style) { - case QUERY_STRING: - url = OAuth.addParameters(url, from.getParameters()); - break; - case BODY: { - byte[] form = OAuth.formEncode(from.getParameters()).getBytes(from.getBodyEncoding()); - headers.add(new OAuth.Parameter(CONTENT_TYPE, OAuth.FORM_ENCODED)); - headers.add(new OAuth.Parameter(CONTENT_LENGTH, form.length + "")); - body = new ByteArrayInputStream(form); - break; - } - case AUTHORIZATION_HEADER: - headers.add(new OAuth.Parameter("Authorization", from.getAuthorizationHeader(null))); - // Find the non-OAuth parameters: - List<Map.Entry<String, String>> others = from.getParameters(); - if (others != null && !others.isEmpty()) { - others = new ArrayList<Map.Entry<String, String>>(others); - for (Iterator<Map.Entry<String, String>> p = others.iterator(); p.hasNext();) { - if (p.next().getKey().startsWith("oauth_")) { - p.remove(); - } - } - // Place the non-OAuth parameters elsewhere in the request: - if (isPost && body == null) { - byte[] form = OAuth.formEncode(others).getBytes(from.getBodyEncoding()); - headers.add(new OAuth.Parameter(CONTENT_TYPE, OAuth.FORM_ENCODED)); - headers.add(new OAuth.Parameter(CONTENT_LENGTH, form.length + "")); - body = new ByteArrayInputStream(form); - } else { - url = OAuth.addParameters(url, others); - } - } - break; - } - HttpMessage httpRequest = new HttpMessage(from.method, new URL(url), body); - httpRequest.headers.addAll(headers); - return httpRequest; - } - - private static boolean equalsIgnoreCase(String x, String y) - { - if (x == null) - return y == null; - else - return x.equalsIgnoreCase(y); - } - - private static final String getCharset(String mimeType) - { - if (mimeType != null) { - Matcher m = CHARSET.matcher(mimeType); - if (m.find()) { - String charset = m.group(1); - if (charset.length() >= 2 && charset.charAt(0) == '"' - && charset.charAt(charset.length() - 1) == '"') { - charset = charset.substring(1, charset.length() - 1); - charset = charset.replace("\\\"", "\""); - } - return charset; - } - } - return DEFAULT_CHARSET; - } - - /** The name of a dump entry whose value is the HTTP request. */ - public static final String REQUEST = "HTTP request"; - - /** The name of a dump entry whose value is the HTTP response. */ - public static final String RESPONSE = "HTTP response"; - - /** The name of a dump entry whose value is the HTTP status code. */ - public static final String STATUS_CODE = "HTTP status"; - - public static final String ACCEPT_ENCODING = "Accept-Encoding"; - public static final String CONTENT_ENCODING = "Content-Encoding"; - public static final String CONTENT_LENGTH = "Content-Length"; - public static final String CONTENT_TYPE = "Content-Type"; - public static final String DEFAULT_CHARSET = "ISO-8859-1"; - - private static final Pattern CHARSET = Pattern - .compile("; *charset *= *([^;\"]*|\"([^\"]|\\\\\")*\")(;|$)"); - -} diff --git a/bbb-lti/src/java/net/oauth/http/HttpMessageDecoder.java b/bbb-lti/src/java/net/oauth/http/HttpMessageDecoder.java deleted file mode 100644 index c40d424419acee645babee31c67bf9e7739d32eb..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/http/HttpMessageDecoder.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2008 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.http; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import java.util.zip.GZIPInputStream; -import java.util.zip.InflaterInputStream; - -// TODO: move this class into oauth-core-consumer, together with HttpMessage. -// The sticky part is deleting the method OAuthMessage.toHttpRequest. -/** A decorator that handles Content-Encoding. */ -public class HttpMessageDecoder extends HttpResponseMessage { - - /** - * Decode the given message if necessary and possible. - * - * @return a decorator that decodes the body of the given message; or the - * given message if this class can't decode it. - */ - public static HttpResponseMessage decode(HttpResponseMessage message) - throws IOException { - if (message != null) { - String encoding = getEncoding(message); - if (encoding != null) { - return new HttpMessageDecoder(message, encoding); - } - } - return message; - } - - public static final String GZIP = "gzip"; - public static final String DEFLATE = "deflate"; - public static final String ACCEPTED = GZIP + "," + DEFLATE; - - private static String getEncoding(HttpMessage message) { - String encoding = message.getHeader(CONTENT_ENCODING); - if (encoding == null) { - // That's easy. - } else if (GZIP.equalsIgnoreCase(encoding) - || ("x-" + GZIP).equalsIgnoreCase(encoding)) { - return GZIP; - } else if (DEFLATE.equalsIgnoreCase(encoding)) { - return DEFLATE; - } - return null; - } - - private HttpMessageDecoder(HttpResponseMessage in, String encoding) - throws IOException { - super(in.method, in.url); - this.headers.addAll(in.headers); - removeHeaders(CONTENT_ENCODING); // handled here - removeHeaders(CONTENT_LENGTH); // unpredictable - InputStream body = in.getBody(); - if (body != null) { - if (encoding == GZIP) { - body = new GZIPInputStream(body); - } else if (encoding == DEFLATE) { - body = new InflaterInputStream(body); - } else { - assert false; - } - } - this.body = body; - this.in = in; - } - - private final HttpResponseMessage in; - - @Override - public void dump(Map<String, Object> into) throws IOException { - in.dump(into); - } - - @Override - public int getStatusCode() throws IOException { - return in.getStatusCode(); - } - -} diff --git a/bbb-lti/src/java/net/oauth/http/HttpResponseMessage.java b/bbb-lti/src/java/net/oauth/http/HttpResponseMessage.java deleted file mode 100644 index 491252fa9792e88c6ad3f55e3a117f2d54fc0382..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/http/HttpResponseMessage.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2008 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.http; - -import java.io.IOException; -import java.net.URL; -import java.util.Map; - -// TODO: move this class into oauth-core-consumer, together with HttpMessage. -// The sticky part is deleting the method OAuthMessage.toHttpRequest. -/** - * An HTTP response. - * - * @author John Kristian - */ -public abstract class HttpResponseMessage extends HttpMessage { - - protected HttpResponseMessage(String method, URL url) { - super(method, url); - } - - @Override - public void dump(Map<String, Object> into) throws IOException { - super.dump(into); - into.put(STATUS_CODE, Integer.valueOf(getStatusCode())); - String location = getHeader(LOCATION); - if (location != null) { - into.put(LOCATION, location); - } - } - - public abstract int getStatusCode() throws IOException; - - /** The name of a dump entry whose value is the response Location header. */ - public static final String LOCATION = "Location"; - - /** The name of a dump entry whose value is the HTTP status code. */ - public static final String STATUS_CODE = "HTTP status"; - - /** The statusCode that indicates a normal outcome. */ - public static final int STATUS_OK = 200; - - /** The standard end-of-line marker in an HTTP message. */ - public static final String EOL = "\r\n"; - -} diff --git a/bbb-lti/src/java/net/oauth/server/HttpRequestMessage.java b/bbb-lti/src/java/net/oauth/server/HttpRequestMessage.java deleted file mode 100644 index 2eb5195c2ac068a079c9110977b8f2d48de9b9eb..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/server/HttpRequestMessage.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2008 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.server; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import net.oauth.OAuth; -import net.oauth.OAuthMessage; - -/** - * An HttpServletRequest, encapsulated as an OAuthMessage. - * - * @author John Kristian - */ -public class HttpRequestMessage extends OAuthMessage { - - public HttpRequestMessage(HttpServletRequest request, String URL) { - super(request.getMethod(), URL, getParameters(request)); - this.request = request; - copyHeaders(request, getHeaders()); - } - - private final HttpServletRequest request; - - @Override - public InputStream getBodyAsStream() throws IOException { - return request.getInputStream(); - } - - @Override - public String getBodyEncoding() { - return request.getCharacterEncoding(); - } - - private static void copyHeaders(HttpServletRequest request, Collection<Map.Entry<String, String>> into) { - Enumeration<String> names = request.getHeaderNames(); - if (names != null) { - while (names.hasMoreElements()) { - String name = names.nextElement(); - Enumeration<String> values = request.getHeaders(name); - if (values != null) { - while (values.hasMoreElements()) { - into.add(new OAuth.Parameter(name, values.nextElement())); - } - } - } - } - } - - public static List<OAuth.Parameter> getParameters(HttpServletRequest request) { - List<OAuth.Parameter> list = new ArrayList<OAuth.Parameter>(); - for (Enumeration<String> headers = request.getHeaders("Authorization"); headers != null - && headers.hasMoreElements();) { - String header = headers.nextElement(); - for (OAuth.Parameter parameter : OAuthMessage - .decodeAuthorization(header)) { - if (!"realm".equalsIgnoreCase(parameter.getKey())) { - list.add(parameter); - } - } - } - for (Object e : request.getParameterMap().entrySet()) { - Map.Entry<String, String[]> entry = (Map.Entry<String, String[]>) e; - String name = entry.getKey(); - for (String value : entry.getValue()) { - list.add(new OAuth.Parameter(name, value)); - } - } - return list; - } - -} diff --git a/bbb-lti/src/java/net/oauth/server/OAuthServlet.java b/bbb-lti/src/java/net/oauth/server/OAuthServlet.java deleted file mode 100644 index 2ae266a7d52f0a0e5f87f575edd1c3d6cf81c474..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/server/OAuthServlet.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2007 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.server; - -import net.oauth.http.HttpMessage; - -import java.io.IOException; -import java.util.Map; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import net.oauth.OAuth; -import net.oauth.OAuthMessage; -import net.oauth.OAuthProblemException; - -/** - * Utility methods for servlets that implement OAuth. - * - * @author John Kristian - */ -public class OAuthServlet { - - /** - * Extract the parts of the given request that are relevant to OAuth. - * Parameters include OAuth Authorization headers and the usual request - * parameters in the query string and/or form encoded body. The header - * parameters come first, followed by the rest in the order they came from - * request.getParameterMap(). - * - * @param URL - * the official URL of this service; that is the URL a legitimate - * client would use to compute the digital signature. If this - * parameter is null, this method will try to reconstruct the URL - * from the HTTP request; which may be wrong in some cases. - */ - public static OAuthMessage getMessage(HttpServletRequest request, String URL) { - if (URL == null) { - URL = request.getRequestURL().toString(); - } - int q = URL.indexOf('?'); - if (q >= 0) { - URL = URL.substring(0, q); - // The query string parameters will be included in - // the result from getParameters(request). - } - return new HttpRequestMessage(request, URL); - } - - /** Reconstruct the requested URL, complete with query string (if any). */ - public static String getRequestURL(HttpServletRequest request) { - StringBuffer url = request.getRequestURL(); - String queryString = request.getQueryString(); - if (queryString != null) { - url.append("?").append(queryString); - } - return url.toString(); - } - - public static void handleException(HttpServletResponse response, - Exception e, String realm) throws IOException, ServletException { - handleException(response, e, realm, true); - } - - public static void handleException(HttpServletResponse response, - Exception e, String realm, boolean sendBody) throws IOException, - ServletException { - if (e instanceof OAuthProblemException) { - OAuthProblemException problem = (OAuthProblemException) e; - Object httpCode = problem.getParameters().get(HttpMessage.STATUS_CODE); - if (httpCode == null) { - httpCode = PROBLEM_TO_HTTP_CODE.get(problem.getProblem()); - } - if (httpCode == null) { - httpCode = SC_FORBIDDEN; - } - response.reset(); - response.setStatus(Integer.parseInt(httpCode.toString())); - OAuthMessage message = new OAuthMessage(null, null, problem - .getParameters().entrySet()); - response.addHeader("WWW-Authenticate", message - .getAuthorizationHeader(realm)); - if (sendBody) { - sendForm(response, message.getParameters()); - } - } else if (e instanceof IOException) { - throw (IOException) e; - } else if (e instanceof ServletException) { - throw (ServletException) e; - } else if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new ServletException(e); - } - } - - private static final Integer SC_FORBIDDEN = new Integer( - HttpServletResponse.SC_FORBIDDEN); - - private static final Map<String, Integer> PROBLEM_TO_HTTP_CODE = OAuth.Problems.TO_HTTP_CODE; - - /** Send the given parameters as a form-encoded response body. */ - public static void sendForm(HttpServletResponse response, - Iterable<? extends Map.Entry> parameters) throws IOException { - response.resetBuffer(); - response.setContentType(OAuth.FORM_ENCODED + ";charset=" - + OAuth.ENCODING); - OAuth.formEncode(parameters, response.getOutputStream()); - } - - /** - * Return the HTML representation of the given plain text. Characters that - * would have special significance in HTML are replaced by <a - * href="http://www.w3.org/TR/html401/sgml/entities.html">character entity - * references</a>. Whitespace is not converted. - */ - public static String htmlEncode(String s) { - if (s == null) { - return null; - } - StringBuilder html = new StringBuilder(s.length()); - for (char c : s.toCharArray()) { - switch (c) { - case '<': - html.append("<"); - break; - case '>': - html.append(">"); - break; - case '&': - html.append("&"); - // This also takes care of numeric character references; - // for example © becomes &#169. - break; - case '"': - html.append("""); - break; - default: - html.append(c); - break; - } - } - return html.toString(); - } - -} diff --git a/bbb-lti/src/java/net/oauth/signature/Base64.java b/bbb-lti/src/java/net/oauth/signature/Base64.java deleted file mode 100644 index fd5ea5fa9576bdfb29924aca54df5b1427d858f3..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/signature/Base64.java +++ /dev/null @@ -1,714 +0,0 @@ -/* - * Copyright 2001-2008 The Apache Software Foundation. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.signature; - -import java.io.UnsupportedEncodingException; -import java.math.BigInteger; - -/** - * Provides Base64 encoding and decoding as defined by RFC 2045. - * - * <p> - * This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite> from RFC 2045 <cite>Multipurpose - * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by Freed and Borenstein. - * </p> - * - * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a> - * @author Apache Software Foundation - * @author John Kristian - */ -class Base64 { - /** - * Chunk size per RFC 2045 section 6.8. - * - * <p> - * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any - * equal signs. - * </p> - * - * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 6.8</a> - */ - static final int CHUNK_SIZE = 76; - - /** - * Chunk separator per RFC 2045 section 2.1. - * - * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a> - */ - static final byte[] CHUNK_SEPARATOR = {'\r','\n'}; - - /** - * This array is a lookup table that translates 6-bit positive integer - * index values into their "Base64 Alphabet" equivalents as specified - * in Table 1 of RFC 2045. - * - * Thanks to "commons" project in ws.apache.org for this code. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - */ - private static final byte[] intToBase64 = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' - }; - - /** - * Byte used to pad output. - */ - private static final byte PAD = '='; - - /** - * This array is a lookup table that translates unicode characters - * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) - * into their 6-bit positive integer equivalents. Characters that - * are not in the Base64 alphabet but fall within the bounds of the - * array are translated to -1. - * - * Thanks to "commons" project in ws.apache.org for this code. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - */ - private static final byte[] base64ToInt = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 - }; - - /** Mask used to extract 6 bits, used when encoding */ - private static final int MASK_6BITS = 0x3f; - - /** Mask used to extract 8 bits, used in decoding base64 bytes */ - private static final int MASK_8BITS = 0xff; - - // The static final fields above are used for the original static byte[] methods on Base64. - // The private member fields below are used with the new streaming approach, which requires - // some state be preserved between calls of encode() and decode(). - - - /** - * Line length for encoding. Not used when decoding. A value of zero or less implies - * no chunking of the base64 encoded data. - */ - private final int lineLength; - - /** - * Line separator for encoding. Not used when decoding. Only used if lineLength > 0. - */ - private final byte[] lineSeparator; - - /** - * Convenience variable to help us determine when our buffer is going to run out of - * room and needs resizing. <code>decodeSize = 3 + lineSeparator.length;</code> - */ - private final int decodeSize; - - /** - * Convenience variable to help us determine when our buffer is going to run out of - * room and needs resizing. <code>encodeSize = 4 + lineSeparator.length;</code> - */ - private final int encodeSize; - - /** - * Buffer for streaming. - */ - private byte[] buf; - - /** - * Position where next character should be written in the buffer. - */ - private int pos; - - /** - * Position where next character should be read from the buffer. - */ - private int readPos; - - /** - * Variable tracks how many characters have been written to the current line. - * Only used when encoding. We use it to make sure each encoded line never - * goes beyond lineLength (if lineLength > 0). - */ - private int currentLinePos; - - /** - * Writes to the buffer only occur after every 3 reads when encoding, an - * every 4 reads when decoding. This variable helps track that. - */ - private int modulus; - - /** - * Boolean flag to indicate the EOF has been reached. Once EOF has been - * reached, this Base64 object becomes useless, and must be thrown away. - */ - private boolean eof; - - /** - * Place holder for the 3 bytes we're dealing with for our base64 logic. - * Bitwise operations store and extract the base64 encoding or decoding from - * this variable. - */ - private int x; - - /** - * Default constructor: lineLength is 76, and the lineSeparator is CRLF - * when encoding, and all forms can be decoded. - */ - public Base64() { - this(CHUNK_SIZE, CHUNK_SEPARATOR); - } - - /** - * <p> - * Consumer can use this constructor to choose a different lineLength - * when encoding (lineSeparator is still CRLF). All forms of data can - * be decoded. - * </p><p> - * Note: lineLengths that aren't multiples of 4 will still essentially - * end up being multiples of 4 in the encoded data. - * </p> - * - * @param lineLength each line of encoded data will be at most this long - * (rounded up to nearest multiple of 4). - * If lineLength <= 0, then the output will not be divided into lines (chunks). - * Ignored when decoding. - */ - public Base64(int lineLength) { - this(lineLength, CHUNK_SEPARATOR); - } - - /** - * <p> - * Consumer can use this constructor to choose a different lineLength - * and lineSeparator when encoding. All forms of data can - * be decoded. - * </p><p> - * Note: lineLengths that aren't multiples of 4 will still essentially - * end up being multiples of 4 in the encoded data. - * </p> - * @param lineLength Each line of encoded data will be at most this long - * (rounded up to nearest multiple of 4). Ignored when decoding. - * If <= 0, then output will not be divided into lines (chunks). - * @param lineSeparator Each line of encoded data will end with this - * sequence of bytes. - * If lineLength <= 0, then the lineSeparator is not used. - * @throws IllegalArgumentException The provided lineSeparator included - * some base64 characters. That's not going to work! - */ - public Base64(int lineLength, byte[] lineSeparator) { - this.lineLength = lineLength; - this.lineSeparator = new byte[lineSeparator.length]; - System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length); - if (lineLength > 0) { - this.encodeSize = 4 + lineSeparator.length; - } else { - this.encodeSize = 4; - } - this.decodeSize = encodeSize - 1; - if (containsBase64Byte(lineSeparator)) { - String sep; - try { - sep = new String(lineSeparator, "UTF-8"); - } catch (UnsupportedEncodingException uee) { - sep = new String(lineSeparator); - } - throw new IllegalArgumentException("lineSeperator must not contain base64 characters: [" + sep + "]"); - } - } - - /** - * Returns true if this Base64 object has buffered data for reading. - * - * @return true if there is Base64 object still available for reading. - */ - boolean hasData() { return buf != null; } - - /** - * Returns the amount of buffered data available for reading. - * - * @return The amount of buffered data available for reading. - */ - int avail() { return buf != null ? pos - readPos : 0; } - - /** Doubles our buffer. */ - private void resizeBuf() { - if (buf == null) { - buf = new byte[8192]; - pos = 0; - readPos = 0; - } else { - byte[] b = new byte[buf.length * 2]; - System.arraycopy(buf, 0, b, 0, buf.length); - buf = b; - } - } - - /** - * Extracts buffered data into the provided byte[] array, starting - * at position bPos, up to a maximum of bAvail bytes. Returns how - * many bytes were actually extracted. - * - * @param b byte[] array to extract the buffered data into. - * @param bPos position in byte[] array to start extraction at. - * @param bAvail amount of bytes we're allowed to extract. We may extract - * fewer (if fewer are available). - * @return The number of bytes successfully extracted into the provided - * byte[] array. - */ - int readResults(byte[] b, int bPos, int bAvail) { - if (buf != null) { - int len = Math.min(avail(), bAvail); - if (buf != b) { - System.arraycopy(buf, readPos, b, bPos, len); - readPos += len; - if (readPos >= pos) { - buf = null; - } - } else { - // Re-using the original consumer's output array is only - // allowed for one round. - buf = null; - } - return len; - } else { - return eof ? -1 : 0; - } - } - - /** - * Small optimization where we try to buffer directly to the consumer's - * output array for one round (if consumer calls this method first!) instead - * of starting our own buffer. - * - * @param out byte[] array to buffer directly to. - * @param outPos Position to start buffering into. - * @param outAvail Amount of bytes available for direct buffering. - */ - void setInitialBuffer(byte[] out, int outPos, int outAvail) { - // We can re-use consumer's original output array under - // special circumstances, saving on some System.arraycopy(). - if (out != null && out.length == outAvail) { - buf = out; - pos = outPos; - readPos = outPos; - } - } - - /** - * <p> - * Encodes all of the provided data, starting at inPos, for inAvail bytes. - * Must be called at least twice: once with the data to encode, and once - * with inAvail set to "-1" to alert encoder that EOF has been reached, - * so flush last remaining bytes (if not multiple of 3). - * </p><p> - * Thanks to "commons" project in ws.apache.org for the bitwise operations, - * and general approach. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - * </p> - * - * @param in byte[] array of binary data to base64 encode. - * @param inPos Position to start reading data from. - * @param inAvail Amount of bytes available from input for encoding. - */ - void encode(byte[] in, int inPos, int inAvail) { - if (eof) { - return; - } - - // inAvail < 0 is how we're informed of EOF in the underlying data we're - // encoding. - if (inAvail < 0) { - eof = true; - if (buf == null || buf.length - pos < encodeSize) { - resizeBuf(); - } - switch (modulus) { - case 1: - buf[pos++] = intToBase64[(x >> 2) & MASK_6BITS]; - buf[pos++] = intToBase64[(x << 4) & MASK_6BITS]; - buf[pos++] = PAD; - buf[pos++] = PAD; - break; - - case 2: - buf[pos++] = intToBase64[(x >> 10) & MASK_6BITS]; - buf[pos++] = intToBase64[(x >> 4) & MASK_6BITS]; - buf[pos++] = intToBase64[(x << 2) & MASK_6BITS]; - buf[pos++] = PAD; - break; - } - if (lineLength > 0) { - System.arraycopy(lineSeparator, 0, buf, pos, lineSeparator.length); - pos += lineSeparator.length; - } - } else { - for (int i = 0; i < inAvail; i++) { - if (buf == null || buf.length - pos < encodeSize) { - resizeBuf(); - } - modulus = (++modulus) % 3; - int b = in[inPos++]; - if (b < 0) { b += 256; } - x = (x << 8) + b; - if (0 == modulus) { - buf[pos++] = intToBase64[(x >> 18) & MASK_6BITS]; - buf[pos++] = intToBase64[(x >> 12) & MASK_6BITS]; - buf[pos++] = intToBase64[(x >> 6) & MASK_6BITS]; - buf[pos++] = intToBase64[x & MASK_6BITS]; - currentLinePos += 4; - if (lineLength > 0 && lineLength <= currentLinePos) { - System.arraycopy(lineSeparator, 0, buf, pos, lineSeparator.length); - pos += lineSeparator.length; - currentLinePos = 0; - } - } - } - } - } - - /** - * <p> - * Decodes all of the provided data, starting at inPos, for inAvail bytes. - * Should be called at least twice: once with the data to decode, and once - * with inAvail set to "-1" to alert decoder that EOF has been reached. - * The "-1" call is not necessary when decoding, but it doesn't hurt, either. - * </p><p> - * Ignores all non-base64 characters. This is how chunked (e.g. 76 character) - * data is handled, since CR and LF are silently ignored, but has implications - * for other bytes, too. This method subscribes to the garbage-in, garbage-out - * philosophy: it will not check the provided data for validity. - * </p><p> - * Thanks to "commons" project in ws.apache.org for the bitwise operations, - * and general approach. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - * </p> - - * @param in byte[] array of ascii data to base64 decode. - * @param inPos Position to start reading data from. - * @param inAvail Amount of bytes available from input for encoding. - */ - void decode(byte[] in, int inPos, int inAvail) { - if (eof) { - return; - } - if (inAvail < 0) { - eof = true; - } - for (int i = 0; i < inAvail; i++) { - if (buf == null || buf.length - pos < decodeSize) { - resizeBuf(); - } - byte b = in[inPos++]; - if (b == PAD) { - x = x << 6; - switch (modulus) { - case 2: - x = x << 6; - buf[pos++] = (byte) ((x >> 16) & MASK_8BITS); - break; - case 3: - buf[pos++] = (byte) ((x >> 16) & MASK_8BITS); - buf[pos++] = (byte) ((x >> 8) & MASK_8BITS); - break; - } - // WE'RE DONE!!!! - eof = true; - return; - } else { - if (b >= 0 && b < base64ToInt.length) { - int result = base64ToInt[b]; - if (result >= 0) { - modulus = (++modulus) % 4; - x = (x << 6) + result; - if (modulus == 0) { - buf[pos++] = (byte) ((x >> 16) & MASK_8BITS); - buf[pos++] = (byte) ((x >> 8) & MASK_8BITS); - buf[pos++] = (byte) (x & MASK_8BITS); - } - } - } - } - } - } - - /** - * Returns whether or not the <code>octet</code> is in the base 64 alphabet. - * - * @param octet - * The value to test - * @return <code>true</code> if the value is defined in the the base 64 alphabet, <code>false</code> otherwise. - */ - public static boolean isBase64(byte octet) { - return octet == PAD || (octet >= 0 && octet < base64ToInt.length && base64ToInt[octet] != -1); - } - - /** - * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. - * Currently the method treats whitespace as valid. - * - * @param arrayOctet - * byte array to test - * @return <code>true</code> if all bytes are valid characters in the Base64 alphabet or if the byte array is - * empty; false, otherwise - */ - public static boolean isArrayByteBase64(byte[] arrayOctet) { - for (int i = 0; i < arrayOctet.length; i++) { - if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) { - return false; - } - } - return true; - } - - /* - * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. - * - * @param arrayOctet - * byte array to test - * @return <code>true</code> if any byte is a valid character in the Base64 alphabet; false herwise - */ - private static boolean containsBase64Byte(byte[] arrayOctet) { - for (int i = 0; i < arrayOctet.length; i++) { - if (isBase64(arrayOctet[i])) { - return true; - } - } - return false; - } - - /** - * Encodes binary data using the base64 algorithm but does not chunk the output. - * - * @param binaryData - * binary data to encode - * @return Base64 characters - */ - public static byte[] encodeBase64(byte[] binaryData) { - return encodeBase64(binaryData, false); - } - - /** - * Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks - * - * @param binaryData - * binary data to encode - * @return Base64 characters chunked in 76 character blocks - */ - public static byte[] encodeBase64Chunked(byte[] binaryData) { - return encodeBase64(binaryData, true); - } - - /** - * Decodes a byte[] containing containing characters in the Base64 alphabet. - * - * @param pArray - * A byte array containing Base64 character data - * @return a byte array containing binary data - */ - public byte[] decode(byte[] pArray) { - return decodeBase64(pArray); - } - - /** - * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. - * - * @param binaryData - * Array containing binary data to encode. - * @param isChunked - * if <code>true</code> this encoder will chunk the base64 output into 76 character blocks - * @return Base64-encoded data. - * @throws IllegalArgumentException - * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} - */ - public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) { - if (binaryData == null || binaryData.length == 0) { - return binaryData; - } - Base64 b64 = isChunked ? new Base64() : new Base64(0); - - long len = (binaryData.length * 4) / 3; - long mod = len % 4; - if (mod != 0) { - len += 4 - mod; - } - if (isChunked) { - len += (1 + (len / CHUNK_SIZE)) * CHUNK_SEPARATOR.length; - } - - if (len > Integer.MAX_VALUE) { - throw new IllegalArgumentException( - "Input array too big, output array would be bigger than Integer.MAX_VALUE=" + Integer.MAX_VALUE); - } - byte[] buf = new byte[(int) len]; - b64.setInitialBuffer(buf, 0, buf.length); - b64.encode(binaryData, 0, binaryData.length); - b64.encode(binaryData, 0, -1); // Notify encoder of EOF. - - // Encoder might have resized, even though it was unnecessary. - if (b64.buf != buf) { - b64.readResults(buf, 0, buf.length); - } - return buf; - } - - /** - * Decodes Base64 data into octets - * - * @param base64Data Byte array containing Base64 data - * @return Array containing decoded data. - */ - public static byte[] decodeBase64(byte[] base64Data) { - if (base64Data == null || base64Data.length == 0) { - return base64Data; - } - Base64 b64 = new Base64(); - - long len = (base64Data.length * 3) / 4; - byte[] buf = new byte[(int) len]; - b64.setInitialBuffer(buf, 0, buf.length); - b64.decode(base64Data, 0, base64Data.length); - b64.decode(base64Data, 0, -1); // Notify decoder of EOF. - - // We have no idea what the line-length was, so we - // cannot know how much of our array wasn't used. - byte[] result = new byte[b64.pos]; - b64.readResults(result, 0, result.length); - return result; - } - - /** - * Check if a byte value is whitespace or not. - * - * @param byteToCheck the byte to check - * @return true if byte is whitespace, false otherwise - */ - private static boolean isWhiteSpace(byte byteToCheck){ - switch (byteToCheck) { - case ' ' : - case '\n' : - case '\r' : - case '\t' : - return true; - default : - return false; - } - } - - /** - * Discards any characters outside of the base64 alphabet, per the requirements on page 25 of RFC 2045 - "Any - * characters outside of the base64 alphabet are to be ignored in base64 encoded data." - * - * @param data - * The base-64 encoded data to groom - * @return The data, less non-base64 characters (see RFC 2045). - */ - static byte[] discardNonBase64(byte[] data) { - byte groomedData[] = new byte[data.length]; - int bytesCopied = 0; - - for (int i = 0; i < data.length; i++) { - if (isBase64(data[i])) { - groomedData[bytesCopied++] = data[i]; - } - } - - byte packedData[] = new byte[bytesCopied]; - - System.arraycopy(groomedData, 0, packedData, 0, bytesCopied); - - return packedData; - } - - // Implementation of the Encoder Interface - - /** - * Encodes a byte[] containing binary data, into a byte[] containing characters in the Base64 alphabet. - * - * @param pArray - * a byte array containing binary data - * @return A byte array containing only Base64 character data - */ - public byte[] encode(byte[] pArray) { - return encodeBase64(pArray, false); - } - - // Implementation of integer encoding used for crypto - /** - * Decode a byte64-encoded integer according to crypto - * standards such as W3C's XML-Signature - * - * @param pArray a byte array containing base64 character data - * @return A BigInteger - */ - public static BigInteger decodeInteger(byte[] pArray) { - return new BigInteger(1, decodeBase64(pArray)); - } - - /** - * Encode to a byte64-encoded integer according to crypto - * standards such as W3C's XML-Signature - * - * @param bigInt a BigInteger - * @return A byte array containing base64 character data - * @throws NullPointerException if null is passed in - */ - public static byte[] encodeInteger(BigInteger bigInt) { - if(bigInt == null) { - throw new NullPointerException("encodeInteger called with null parameter"); - } - - return encodeBase64(toIntegerBytes(bigInt), false); - } - - /** - * Returns a byte-array representation of a <code>BigInteger</code> - * without sign bit. - * - * @param bigInt <code>BigInteger</code> to be converted - * @return a byte array representation of the BigInteger parameter - */ - static byte[] toIntegerBytes(BigInteger bigInt) { - int bitlen = bigInt.bitLength(); - // round bitlen - bitlen = ((bitlen + 7) >> 3) << 3; - byte[] bigBytes = bigInt.toByteArray(); - - if(((bigInt.bitLength() % 8) != 0) && - (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) { - return bigBytes; - } - - // set up params for copying everything but sign bit - int startSrc = 0; - int len = bigBytes.length; - - // if bigInt is exactly byte-aligned, just skip signbit in copy - if((bigInt.bitLength() % 8) == 0) { - startSrc = 1; - len--; - } - - int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec - byte[] resizedBytes = new byte[bitlen / 8]; - - System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len); - - return resizedBytes; - } -} diff --git a/bbb-lti/src/java/net/oauth/signature/HMAC_SHA1.java b/bbb-lti/src/java/net/oauth/signature/HMAC_SHA1.java deleted file mode 100644 index ed9dc5c69489a9b536c12fa7123f4a35083ad4b7..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/signature/HMAC_SHA1.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2007 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.signature; - -import java.io.UnsupportedEncodingException; -import java.security.GeneralSecurityException; -import java.util.Arrays; - -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import net.oauth.OAuth; -import net.oauth.OAuthException; - -/** - * @author John Kristian - */ -public class HMAC_SHA1 extends OAuthSignatureMethod { - - @Override - public String getSignature(String baseString) throws OAuthException { - try { - String signature = base64Encode(computeSignature(baseString)); - return signature; - } catch (GeneralSecurityException e) { - throw new OAuthException(e); - } catch (UnsupportedEncodingException e) { - throw new OAuthException(e); - } - } - - @Override - public boolean isValid(String signature, String baseString) - throws OAuthException { - try { - byte[] expected = computeSignature(baseString); - byte[] actual = decodeBase64(signature); - return Arrays.equals(expected, actual); - } catch (GeneralSecurityException e) { - throw new OAuthException(e); - } catch (UnsupportedEncodingException e) { - throw new OAuthException(e); - } - } - - private byte[] computeSignature(String baseString) - throws GeneralSecurityException, UnsupportedEncodingException { - SecretKey key = null; - synchronized (this) { - if (this.key == null) { - String keyString = OAuth.percentEncode(getConsumerSecret()) - + '&' + OAuth.percentEncode(getTokenSecret()); - byte[] keyBytes = keyString.getBytes(ENCODING); - this.key = new SecretKeySpec(keyBytes, MAC_NAME); - } - key = this.key; - } - Mac mac = Mac.getInstance(MAC_NAME); - mac.init(key); - byte[] text = baseString.getBytes(ENCODING); - return mac.doFinal(text); - } - - /** ISO-8859-1 or US-ASCII would work, too. */ - private static final String ENCODING = OAuth.ENCODING; - - private static final String MAC_NAME = "HmacSHA1"; - - private SecretKey key = null; - - @Override - public void setConsumerSecret(String consumerSecret) { - synchronized (this) { - key = null; - } - super.setConsumerSecret(consumerSecret); - } - - @Override - public void setTokenSecret(String tokenSecret) { - synchronized (this) { - key = null; - } - super.setTokenSecret(tokenSecret); - } - -} diff --git a/bbb-lti/src/java/net/oauth/signature/OAuthSignatureMethod.java b/bbb-lti/src/java/net/oauth/signature/OAuthSignatureMethod.java deleted file mode 100644 index 5b53b07de347fa073e3534854a232492ef9707f8..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/signature/OAuthSignatureMethod.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2007 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.signature; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import net.oauth.OAuth; -import net.oauth.OAuthAccessor; -import net.oauth.OAuthConsumer; -import net.oauth.OAuthException; -import net.oauth.OAuthMessage; -import net.oauth.OAuthProblemException; - -/** - * A pair of algorithms for computing and verifying an OAuth digital signature. - * - * @author John Kristian - */ -public abstract class OAuthSignatureMethod { - - /** Add a signature to the message. - * @throws URISyntaxException - * @throws IOException */ - public void sign(OAuthMessage message) - throws OAuthException, IOException, URISyntaxException { - message.addParameter(new OAuth.Parameter("oauth_signature", - getSignature(message))); - } - - /** - * Check whether the message has a valid signature. - * @throws URISyntaxException - * - * @throws OAuthProblemException - * the signature is invalid - */ - public void validate(OAuthMessage message) - throws IOException, OAuthException, URISyntaxException { - message.requireParameters("oauth_signature"); - String signature = message.getSignature(); - String baseString = getBaseString(message); - if (!isValid(signature, baseString)) { - OAuthProblemException problem = new OAuthProblemException( - "signature_invalid"); - problem.setParameter("oauth_signature", signature); - problem.setParameter("oauth_signature_base_string", baseString); - problem.setParameter("oauth_signature_method", message - .getSignatureMethod()); - throw problem; - } - } - - protected String getSignature(OAuthMessage message) - throws OAuthException, IOException, URISyntaxException { - String baseString = getBaseString(message); - String signature = getSignature(baseString); - // Logger log = Logger.getLogger(getClass().getName()); - // if (log.isLoggable(Level.FINE)) { - // log.fine(signature + "=getSignature(" + baseString + ")"); - // } - return signature; - } - - protected void initialize(String name, OAuthAccessor accessor) - throws OAuthException { - String secret = accessor.consumer.consumerSecret; - if (name.endsWith(_ACCESSOR)) { - // This code supports the 'Accessor Secret' extensions - // described in http://oauth.pbwiki.com/AccessorSecret - final String key = OAuthConsumer.ACCESSOR_SECRET; - Object accessorSecret = accessor.getProperty(key); - if (accessorSecret == null) { - accessorSecret = accessor.consumer.getProperty(key); - } - if (accessorSecret != null) { - secret = accessorSecret.toString(); - } - } - if (secret == null) { - secret = ""; - } - setConsumerSecret(secret); - } - - public static final String _ACCESSOR = "-Accessor"; - - /** Compute the signature for the given base string. */ - protected abstract String getSignature(String baseString) throws OAuthException; - - /** Decide whether the signature is valid. */ - protected abstract boolean isValid(String signature, String baseString) - throws OAuthException; - - private String consumerSecret; - - private String tokenSecret; - - protected String getConsumerSecret() { - return consumerSecret; - } - - protected void setConsumerSecret(String consumerSecret) { - this.consumerSecret = consumerSecret; - } - - public String getTokenSecret() { - return tokenSecret; - } - - public void setTokenSecret(String tokenSecret) { - this.tokenSecret = tokenSecret; - } - - public static String getBaseString(OAuthMessage message) - throws IOException, URISyntaxException { - List<Map.Entry<String, String>> parameters; - String url = message.URL; - int q = url.indexOf('?'); - if (q < 0) { - parameters = message.getParameters(); - } else { - // Combine the URL query string with the other parameters: - parameters = new ArrayList<Map.Entry<String, String>>(); - parameters.addAll(OAuth.decodeForm(message.URL.substring(q + 1))); - parameters.addAll(message.getParameters()); - url = url.substring(0, q); - } - return OAuth.percentEncode(message.method.toUpperCase()) + '&' - + OAuth.percentEncode(normalizeUrl(url)) + '&' - + OAuth.percentEncode(normalizeParameters(parameters)); - } - - protected static String normalizeUrl(String url) throws URISyntaxException { - URI uri = new URI(url); - String scheme = uri.getScheme().toLowerCase(); - String authority = uri.getAuthority().toLowerCase(); - boolean dropPort = (scheme.equals("http") && uri.getPort() == 80) - || (scheme.equals("https") && uri.getPort() == 443); - if (dropPort) { - // find the last : in the authority - int index = authority.lastIndexOf(":"); - if (index >= 0) { - authority = authority.substring(0, index); - } - } - String path = uri.getRawPath(); - if (path == null || path.length() <= 0) { - path = "/"; // conforms to RFC 2616 section 3.2.2 - } - // we know that there is no query and no fragment here. - return scheme + "://" + authority + path; - } - - protected static String normalizeParameters( - Collection<? extends Map.Entry> parameters) throws IOException { - if (parameters == null) { - return ""; - } - List<ComparableParameter> p = new ArrayList<ComparableParameter>( - parameters.size()); - for (Map.Entry parameter : parameters) { - if (!"oauth_signature".equals(parameter.getKey())) { - p.add(new ComparableParameter(parameter)); - } - } - Collections.sort(p); - return OAuth.formEncode(getParameters(p)); - } - - public static byte[] decodeBase64(String s) { - return BASE64.decode(s.getBytes()); - } - - public static String base64Encode(byte[] b) { - return new String(BASE64.encode(b)); - } - - private static final Base64 BASE64 = new Base64(); - - public static OAuthSignatureMethod newSigner(OAuthMessage message, - OAuthAccessor accessor) throws IOException, OAuthException { - message.requireParameters(OAuth.OAUTH_SIGNATURE_METHOD); - OAuthSignatureMethod signer = newMethod(message.getSignatureMethod(), - accessor); - signer.setTokenSecret(accessor.tokenSecret); - return signer; - } - - /** The factory for signature methods. */ - public static OAuthSignatureMethod newMethod(String name, - OAuthAccessor accessor) throws OAuthException { - try { - Class methodClass = NAME_TO_CLASS.get(name); - if (methodClass != null) { - OAuthSignatureMethod method = (OAuthSignatureMethod) methodClass - .newInstance(); - method.initialize(name, accessor); - return method; - } - OAuthProblemException problem = new OAuthProblemException(OAuth.Problems.SIGNATURE_METHOD_REJECTED); - String acceptable = OAuth.percentEncode(NAME_TO_CLASS.keySet()); - if (acceptable.length() > 0) { - problem.setParameter("oauth_acceptable_signature_methods", - acceptable.toString()); - } - throw problem; - } catch (InstantiationException e) { - throw new OAuthException(e); - } catch (IllegalAccessException e) { - throw new OAuthException(e); - } - } - - /** - * Subsequently, newMethod(name) will attempt to instantiate the given - * class, with no constructor parameters. - */ - public static void registerMethodClass(String name, Class clazz) { - NAME_TO_CLASS.put(name, clazz); - } - - private static final Map<String, Class> NAME_TO_CLASS = new ConcurrentHashMap<String, Class>(); - static { - registerMethodClass("HMAC-SHA1", HMAC_SHA1.class); - registerMethodClass("PLAINTEXT", PLAINTEXT.class); - registerMethodClass("RSA-SHA1", RSA_SHA1.class); - registerMethodClass("HMAC-SHA1" + _ACCESSOR, HMAC_SHA1.class); - registerMethodClass("PLAINTEXT" + _ACCESSOR, PLAINTEXT.class); - } - - /** An efficiently sortable wrapper around a parameter. */ - private static class ComparableParameter implements - Comparable<ComparableParameter> { - - ComparableParameter(Map.Entry value) { - this.value = value; - String n = toString(value.getKey()); - String v = toString(value.getValue()); - this.key = OAuth.percentEncode(n) + ' ' + OAuth.percentEncode(v); - // ' ' is used because it comes before any character - // that can appear in a percentEncoded string. - } - - final Map.Entry value; - - private final String key; - - private static String toString(Object from) { - return (from == null) ? null : from.toString(); - } - - public int compareTo(ComparableParameter that) { - return this.key.compareTo(that.key); - } - - @Override - public String toString() { - return key; - } - - } - - /** Retrieve the original parameters from a sorted collection. */ - private static List<Map.Entry> getParameters( - Collection<ComparableParameter> parameters) { - if (parameters == null) { - return null; - } - List<Map.Entry> list = new ArrayList<Map.Entry>(parameters.size()); - for (ComparableParameter parameter : parameters) { - list.add(parameter.value); - } - return list; - } - -} diff --git a/bbb-lti/src/java/net/oauth/signature/PLAINTEXT.java b/bbb-lti/src/java/net/oauth/signature/PLAINTEXT.java deleted file mode 100644 index 59c94a900eafd2889619c053804d7afc357b2d5d..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/signature/PLAINTEXT.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2007 Netflix, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.signature; - -import net.oauth.OAuth; -import net.oauth.OAuthException; - -/** - * @author John Kristian - */ -class PLAINTEXT extends OAuthSignatureMethod { - - @Override - public String getSignature(String baseString) { - return getSignature(); - } - - @Override - protected boolean isValid(String signature, String baseString) - throws OAuthException { - return signature.equals(getSignature()); - } - - private synchronized String getSignature() { - if (signature == null) { - signature = OAuth.percentEncode(getConsumerSecret()) + '&' - + OAuth.percentEncode(getTokenSecret()); - } - return signature; - } - - private String signature = null; - - @Override - public void setConsumerSecret(String consumerSecret) { - synchronized (this) { - signature = null; - } - super.setConsumerSecret(consumerSecret); - } - - @Override - public void setTokenSecret(String tokenSecret) { - synchronized (this) { - signature = null; - } - super.setTokenSecret(tokenSecret); - } - -} diff --git a/bbb-lti/src/java/net/oauth/signature/RSA_SHA1.java b/bbb-lti/src/java/net/oauth/signature/RSA_SHA1.java deleted file mode 100644 index a0f92a7923ec7cc7d27b841a67fea4293d6698f2..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/signature/RSA_SHA1.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright 2007 Google, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.oauth.signature; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.security.GeneralSecurityException; -import java.security.KeyFactory; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.Signature; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.EncodedKeySpec; -import java.security.spec.KeySpec; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; - -import net.oauth.OAuth; -import net.oauth.OAuthAccessor; -import net.oauth.OAuthException; -import net.oauth.signature.pem.PEMReader; -import net.oauth.signature.pem.PKCS1EncodedKeySpec; - -/** - * Class to handle RSA-SHA1 signatures on OAuth requests. A consumer - * that wishes to use public-key signatures on messages does not need - * a shared secret with the service provider, but it needs a private - * RSA signing key. You create it like this: - * - * OAuthConsumer c = new OAuthConsumer(callback_url, consumer_key, - * null, provider); - * c.setProperty(RSA_SHA1.PRIVATE_KEY, consumer_privateRSAKey); - * - * consumer_privateRSAKey must be an RSA signing key and - * of type java.security.PrivateKey, String, byte[] or InputStream. - * The key must either PKCS#1 or PKCS#8 encoded. - * - * A service provider that wishes to verify signatures made by such a - * consumer does not need a shared secret with the consumer, but it needs - * to know the consumer's public key. You create the necessary - * OAuthConsumer object (on the service provider's side) like this: - * - * OAuthConsumer c = new OAuthConsumer(callback_url, consumer_key, - * null, provider); - * c.setProperty(RSA_SHA1.PUBLIC_KEY, consumer_publicRSAKey); - * - * consumer_publicRSAKey must be the consumer's public RSAkey and - * of type java.security.PublicKey, String, or byte[]. In the latter two - * cases, the key must be X509-encoded (byte[]) or X509-encoded and - * then Base64-encoded (String). - * - * Alternatively, a service provider that wishes to verify signatures made - * by such a consumer can use a X509 certificate containing the consumer's - * public key. You create the necessary OAuthConsumer object (on the service - * provider's side) like this: - * - * OAuthConsumer c = new OAuthConsumer(callback_url, consumer_key, - * null, provider); - * c.setProperty(RSA_SHA1.X509_CERTIFICATE, consumer_cert); - * - * consumer_cert must be a X509 Certificate containing the consumer's public - * key and be of type java.security.cert.X509Certificate, String, - * or byte[]. In the latter two cases, the certificate must be DER-encoded - * (byte[]) or PEM-encoded (String). - * - * @author Dirk Balfanz - * - */ -public class RSA_SHA1 extends OAuthSignatureMethod { - - final static public String PRIVATE_KEY = "RSA-SHA1.PrivateKey"; - final static public String PUBLIC_KEY = "RSA-SHA1.PublicKey"; - final static public String X509_CERTIFICATE = "RSA-SHA1.X509Certificate"; - - private PrivateKey privateKey = null; - private PublicKey publicKey = null; - - @Override - protected void initialize(String name, OAuthAccessor accessor) - throws OAuthException { - super.initialize(name, accessor); - - // Due to the support of PEM input stream, the keys must be cached. - // The stream may not be markable so it can't be read again. - try { - Object privateKeyObject = accessor.consumer.getProperty(PRIVATE_KEY); - if (privateKeyObject != null) { - privateKey = loadPrivateKey(privateKeyObject); - } - - Object publicKeyObject = accessor.consumer.getProperty(PUBLIC_KEY); - if (publicKeyObject != null) { - publicKey = loadPublicKey(publicKeyObject, false); - } else { // public key was null. perhaps they gave us a X509 cert. - Object certObject = accessor.consumer.getProperty(X509_CERTIFICATE); - if (certObject != null) { - publicKey = loadPublicKey(certObject, true); - } - } - } catch (GeneralSecurityException e) { - throw new OAuthException(e); - } catch (IOException e) { - throw new OAuthException(e); - } - } - - private PublicKey getPublicKeyFromDerCert(byte[] certObject) - throws GeneralSecurityException { - CertificateFactory fac = CertificateFactory.getInstance("X509"); - ByteArrayInputStream in = new ByteArrayInputStream(certObject); - X509Certificate cert = (X509Certificate)fac.generateCertificate(in); - return cert.getPublicKey(); - } - - private PublicKey getPublicKeyFromDer(byte[] publicKeyObject) - throws GeneralSecurityException { - KeyFactory fac = KeyFactory.getInstance("RSA"); - EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyObject); - return fac.generatePublic(pubKeySpec); - } - - private PublicKey getPublicKeyFromPem(String pem) - throws GeneralSecurityException, IOException { - - InputStream stream = new ByteArrayInputStream( - pem.getBytes("UTF-8")); - - PEMReader reader = new PEMReader(stream); - byte[] bytes = reader.getDerBytes(); - PublicKey pubKey; - - if (PEMReader.PUBLIC_X509_MARKER.equals(reader.getBeginMarker())) { - KeySpec keySpec = new X509EncodedKeySpec(bytes); - KeyFactory fac = KeyFactory.getInstance("RSA"); - pubKey = fac.generatePublic(keySpec); - } else if (PEMReader.CERTIFICATE_X509_MARKER.equals(reader.getBeginMarker())) { - pubKey = getPublicKeyFromDerCert(bytes); - } else { - throw new IOException("Invalid PEM fileL: Unknown marker for " + - " public key or cert " + reader.getBeginMarker()); - } - - return pubKey; - } - - private PrivateKey getPrivateKeyFromDer(byte[] privateKeyObject) - throws GeneralSecurityException { - KeyFactory fac = KeyFactory.getInstance("RSA"); - EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(privateKeyObject); - return fac.generatePrivate(privKeySpec); - } - - private PrivateKey getPrivateKeyFromPem(String pem) - throws GeneralSecurityException, IOException { - - InputStream stream = new ByteArrayInputStream( - pem.getBytes("UTF-8")); - - PEMReader reader = new PEMReader(stream); - byte[] bytes = reader.getDerBytes(); - KeySpec keySpec; - - if (PEMReader.PRIVATE_PKCS1_MARKER.equals(reader.getBeginMarker())) { - keySpec = (new PKCS1EncodedKeySpec(bytes)).getKeySpec(); - } else if (PEMReader.PRIVATE_PKCS8_MARKER.equals(reader.getBeginMarker())) { - keySpec = new PKCS8EncodedKeySpec(bytes); - } else { - throw new IOException("Invalid PEM file: Unknown marker " + - "for private key " + reader.getBeginMarker()); - } - - KeyFactory fac = KeyFactory.getInstance("RSA"); - return fac.generatePrivate(keySpec); - } - - @Override - protected String getSignature(String baseString) throws OAuthException { - try { - byte[] signature = sign(baseString.getBytes(OAuth.ENCODING)); - return base64Encode(signature); - } catch (UnsupportedEncodingException e) { - throw new OAuthException(e); - } catch (GeneralSecurityException e) { - throw new OAuthException(e); - } - } - - @Override - protected boolean isValid(String signature, String baseString) - throws OAuthException { - try { - return verify(decodeBase64(signature), - baseString.getBytes(OAuth.ENCODING)); - } catch (UnsupportedEncodingException e) { - throw new OAuthException(e); - } catch (GeneralSecurityException e) { - throw new OAuthException(e); - } - } - - private byte[] sign(byte[] message) throws GeneralSecurityException { - if (privateKey == null) { - throw new IllegalStateException("need to set private key with " + - "OAuthConsumer.setProperty when " + - "generating RSA-SHA1 signatures."); - } - Signature signer = Signature.getInstance("SHA1withRSA"); - signer.initSign(privateKey); - signer.update(message); - return signer.sign(); - } - - private boolean verify(byte[] signature, byte[] message) - throws GeneralSecurityException { - if (publicKey == null) { - throw new IllegalStateException("need to set public key with " + - " OAuthConsumer.setProperty when " + - "verifying RSA-SHA1 signatures."); - } - Signature verifier = Signature.getInstance("SHA1withRSA"); - verifier.initVerify(publicKey); - verifier.update(message); - return verifier.verify(signature); - } - - /** - * Load private key from various sources, including - * <ul> - * <li>A PrivateKey object - * <li>A string buffer for PEM - * <li>A byte array with PKCS#8 encoded key - * </ul> - * @param privateKeyObject - * @return The private key - * @throws IOException - * @throws GeneralSecurityException - */ - private PrivateKey loadPrivateKey(Object privateKeyObject) - throws IOException, GeneralSecurityException { - - PrivateKey privateKey; - - if (privateKeyObject instanceof PrivateKey) { - privateKey = (PrivateKey)privateKeyObject; - } else if (privateKeyObject instanceof String) { - try { - // PEM Reader's native string constructor is for filename. - privateKey = getPrivateKeyFromPem((String)privateKeyObject); - } catch (IOException e) { - // Check if it's PEM with markers stripped - privateKey = getPrivateKeyFromDer( - decodeBase64((String)privateKeyObject)); - } - } else if (privateKeyObject instanceof byte[]) { - privateKey = getPrivateKeyFromDer((byte[])privateKeyObject); - } else { - throw new IllegalArgumentException( - "Private key set through RSA_SHA1.PRIVATE_KEY must be of " + - "type PrivateKey, String or byte[] and not " + - privateKeyObject.getClass().getName()); - } - - return privateKey; - } - - /** - * Load a public key from key file or certificate. It can load from - * different sources depending on the type of the input, - * <ul> - * <li>A PublicKey object - * <li>A X509Certificate object - * <li>A string buffer for PEM - * <li>A byte array with X509 encoded key or certificate - * </ul> - * - * @param publicKeyObject The object for public key or certificate - * @param isCert True if this object is provided as Certificate - * @return The public key - * @throws IOException - * @throws GeneralSecurityException - */ - private PublicKey loadPublicKey(Object publicKeyObject, boolean isCert) - throws IOException, GeneralSecurityException { - - PublicKey publicKey; - - if (publicKeyObject instanceof PublicKey) { - publicKey = (PublicKey)publicKeyObject; - } else if (publicKeyObject instanceof X509Certificate) { - publicKey = ((X509Certificate) publicKeyObject).getPublicKey(); - } else if (publicKeyObject instanceof String) { - try { - publicKey = getPublicKeyFromPem((String)publicKeyObject); - } catch (IOException e) { - // Check if it's marker-stripped PEM for public key - if (isCert) - throw e; - publicKey = getPublicKeyFromDer( - decodeBase64((String)publicKeyObject)); - } - } else if (publicKeyObject instanceof byte[]) { - if (isCert) - publicKey = getPublicKeyFromDerCert((byte[])publicKeyObject); - else - publicKey = getPublicKeyFromDer((byte[])publicKeyObject); - } else { - String source; - if (isCert) - source = "RSA_SHA1.X509_CERTIFICATE"; - else - source = "RSA_SHA1.PUBLIC_KEY"; - throw new IllegalArgumentException( - "Public key or certificate set through " + source + " must be of " + - "type PublicKey, String or byte[], and not " + - publicKeyObject.getClass().getName()); - } - - return publicKey; - } -} diff --git a/bbb-lti/src/java/net/oauth/signature/pem/Asn1Object.java b/bbb-lti/src/java/net/oauth/signature/pem/Asn1Object.java deleted file mode 100644 index 4994f1f1b304dee72954e2f2f9818fd60e48bf7f..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/signature/pem/Asn1Object.java +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2009 AOL LLC. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************/ -package net.oauth.signature.pem; - -import java.io.IOException; -import java.math.BigInteger; - -/** - * An ASN.1 TLV. The object is not parsed. It can - * only handle integers and strings. - * - * @author zhang - * - */ -class Asn1Object { - - protected final int type; - protected final int length; - protected final byte[] value; - protected final int tag; - - /** - * Construct a ASN.1 TLV. The TLV could be either a - * constructed or primitive entity. - * - * <p/>The first byte in DER encoding is made of following fields, - * <pre> - *------------------------------------------------- - *|Bit 8|Bit 7|Bit 6|Bit 5|Bit 4|Bit 3|Bit 2|Bit 1| - *------------------------------------------------- - *| Class | CF | + Type | - *------------------------------------------------- - * </pre> - * <ul> - * <li>Class: Universal, Application, Context or Private - * <li>CF: Constructed flag. If 1, the field is constructed. - * <li>Type: This is actually called tag in ASN.1. It - * indicates data type (Integer, String) or a construct - * (sequence, choice, set). - * </ul> - * - * @param tag Tag or Identifier - * @param length Length of the field - * @param value Encoded octet string for the field. - */ - public Asn1Object(int tag, int length, byte[] value) { - this.tag = tag; - this.type = tag & 0x1F; - this.length = length; - this.value = value; - } - - public int getType() { - return type; - } - - public int getLength() { - return length; - } - - public byte[] getValue() { - return value; - } - - public boolean isConstructed() { - return (tag & DerParser.CONSTRUCTED) == DerParser.CONSTRUCTED; - } - - /** - * For constructed field, return a parser for its content. - * - * @return A parser for the construct. - * @throws IOException - */ - public DerParser getParser() throws IOException { - if (!isConstructed()) - throw new IOException("Invalid DER: can't parse primitive entity"); //$NON-NLS-1$ - - return new DerParser(value); - } - - /** - * Get the value as integer - * - * @return BigInteger - * @throws IOException - */ - public BigInteger getInteger() throws IOException { - if (type != DerParser.INTEGER) - throw new IOException("Invalid DER: object is not integer"); //$NON-NLS-1$ - - return new BigInteger(value); - } - - /** - * Get value as string. Most strings are treated - * as Latin-1. - * - * @return Java string - * @throws IOException - */ - public String getString() throws IOException { - - String encoding; - - switch (type) { - - // Not all are Latin-1 but it's the closest thing - case DerParser.NUMERIC_STRING: - case DerParser.PRINTABLE_STRING: - case DerParser.VIDEOTEX_STRING: - case DerParser.IA5_STRING: - case DerParser.GRAPHIC_STRING: - case DerParser.ISO646_STRING: - case DerParser.GENERAL_STRING: - encoding = "ISO-8859-1"; //$NON-NLS-1$ - break; - - case DerParser.BMP_STRING: - encoding = "UTF-16BE"; //$NON-NLS-1$ - break; - - case DerParser.UTF8_STRING: - encoding = "UTF-8"; //$NON-NLS-1$ - break; - - case DerParser.UNIVERSAL_STRING: - throw new IOException("Invalid DER: can't handle UCS-4 string"); //$NON-NLS-1$ - - default: - throw new IOException("Invalid DER: object is not a string"); //$NON-NLS-1$ - } - - return new String(value, encoding); - } -} diff --git a/bbb-lti/src/java/net/oauth/signature/pem/DerParser.java b/bbb-lti/src/java/net/oauth/signature/pem/DerParser.java deleted file mode 100644 index fff242ea846fc833d9a43cb79b810c2de5a5d11d..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/signature/pem/DerParser.java +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2009 AOL LLC. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************/ -package net.oauth.signature.pem; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; - -/** - * A bare-minimum ASN.1 DER decoder, just having enough functions to - * decode PKCS#1 private keys. Especially, it doesn't handle explicitly - * tagged types with an outer tag. - * - * <p/>This parser can only handle one layer. To parse nested constructs, - * get a new parser for each layer using <code>Asn1Object.getParser()</code>. - * - * <p/>There are many DER decoders in JRE but using them will tie this - * program to a specific JCE/JVM. - * - * @author zhang - * - */ -class DerParser { - - // Classes - public final static int UNIVERSAL = 0x00; - public final static int APPLICATION = 0x40; - public final static int CONTEXT = 0x80; - public final static int PRIVATE = 0xC0; - - // Constructed Flag - public final static int CONSTRUCTED = 0x20; - - // Tag and data types - public final static int ANY = 0x00; - public final static int BOOLEAN = 0x01; - public final static int INTEGER = 0x02; - public final static int BIT_STRING = 0x03; - public final static int OCTET_STRING = 0x04; - public final static int NULL = 0x05; - public final static int OBJECT_IDENTIFIER = 0x06; - public final static int REAL = 0x09; - public final static int ENUMERATED = 0x0a; - public final static int RELATIVE_OID = 0x0d; - - public final static int SEQUENCE = 0x10; - public final static int SET = 0x11; - - public final static int NUMERIC_STRING = 0x12; - public final static int PRINTABLE_STRING = 0x13; - public final static int T61_STRING = 0x14; - public final static int VIDEOTEX_STRING = 0x15; - public final static int IA5_STRING = 0x16; - public final static int GRAPHIC_STRING = 0x19; - public final static int ISO646_STRING = 0x1A; - public final static int GENERAL_STRING = 0x1B; - - public final static int UTF8_STRING = 0x0C; - public final static int UNIVERSAL_STRING = 0x1C; - public final static int BMP_STRING = 0x1E; - - public final static int UTC_TIME = 0x17; - public final static int GENERALIZED_TIME = 0x18; - - protected InputStream in; - - /** - * Create a new DER decoder from an input stream. - * - * @param in - * The DER encoded stream - */ - public DerParser(InputStream in) throws IOException { - this.in = in; - } - - /** - * Create a new DER decoder from a byte array. - * - * @param The - * encoded bytes - * @throws IOException - */ - public DerParser(byte[] bytes) throws IOException { - this(new ByteArrayInputStream(bytes)); - } - - /** - * Read next object. If it's constructed, the value holds - * encoded content and it should be parsed by a new - * parser from <code>Asn1Object.getParser</code>. - * - * @return A object - * @throws IOException - */ - public Asn1Object read() throws IOException { - int tag = in.read(); - - if (tag == -1) - throw new IOException("Invalid DER: stream too short, missing tag"); //$NON-NLS-1$ - - int length = getLength(); - - byte[] value = new byte[length]; - int n = in.read(value); - if (n < length) - throw new IOException("Invalid DER: stream too short, missing value"); //$NON-NLS-1$ - - Asn1Object o = new Asn1Object(tag, length, value); - - return o; - } - - /** - * Decode the length of the field. Can only support length - * encoding up to 4 octets. - * - * <p/>In BER/DER encoding, length can be encoded in 2 forms, - * <ul> - * <li>Short form. One octet. Bit 8 has value "0" and bits 7-1 - * give the length. - * <li>Long form. Two to 127 octets (only 4 is supported here). - * Bit 8 of first octet has value "1" and bits 7-1 give the - * number of additional length octets. Second and following - * octets give the length, base 256, most significant digit first. - * </ul> - * @return The length as integer - * @throws IOException - */ - private int getLength() throws IOException { - - int i = in.read(); - if (i == -1) - throw new IOException("Invalid DER: length missing"); //$NON-NLS-1$ - - // A single byte short length - if ((i & ~0x7F) == 0) - return i; - - int num = i & 0x7F; - - // We can't handle length longer than 4 bytes - if ( i >= 0xFF || num > 4) - throw new IOException("Invalid DER: length field too big (" //$NON-NLS-1$ - + i + ")"); //$NON-NLS-1$ - - byte[] bytes = new byte[num]; - int n = in.read(bytes); - if (n < num) - throw new IOException("Invalid DER: length too short"); //$NON-NLS-1$ - - return new BigInteger(1, bytes).intValue(); - } - -} diff --git a/bbb-lti/src/java/net/oauth/signature/pem/PEMReader.java b/bbb-lti/src/java/net/oauth/signature/pem/PEMReader.java deleted file mode 100644 index 71e826e15a08fd25f8a1865f7ab0b00992b9434e..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/signature/pem/PEMReader.java +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2009 AOL LLC. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - **************************************************************************** - * - * @author: zhang - * @version: $Revision: 73016 $ - * @created: Apr 24, 2009 - * - * Description: A class to decode PEM files - * - ****************************************************************************/ -package net.oauth.signature.pem; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import net.oauth.signature.OAuthSignatureMethod; - -/** - * This class convert PEM into byte array. The begin marker - * is saved and it can be used to determine the type of the - * PEM file. - * - * @author zhang - */ -public class PEMReader { - - // Begin markers for all supported PEM files - public static final String PRIVATE_PKCS1_MARKER = - "-----BEGIN RSA PRIVATE KEY-----"; - public static final String PRIVATE_PKCS8_MARKER = - "-----BEGIN PRIVATE KEY-----"; - public static final String CERTIFICATE_X509_MARKER = - "-----BEGIN CERTIFICATE-----"; - public static final String PUBLIC_X509_MARKER = - "-----BEGIN PUBLIC KEY-----"; - - private static final String BEGIN_MARKER = "-----BEGIN "; - - private InputStream stream; - private byte[] derBytes; - private String beginMarker; - - public PEMReader(InputStream inStream) throws IOException { - stream = inStream; - readFile(); - } - - public PEMReader(byte[] buffer) throws IOException { - this(new ByteArrayInputStream(buffer)); - } - - public PEMReader(String fileName) throws IOException { - this(new FileInputStream(fileName)); - } - - public byte[] getDerBytes() { - return derBytes; - } - - public String getBeginMarker() { - return beginMarker; - } - - /** - * Read the PEM file and save the DER encoded octet - * stream and begin marker. - * - * @throws IOException - */ - protected void readFile() throws IOException { - - String line; - BufferedReader reader = new BufferedReader( - new InputStreamReader(stream)); - try { - while ((line = reader.readLine()) != null) - { - if (line.indexOf(BEGIN_MARKER) != -1) - { - beginMarker = line.trim(); - String endMarker = beginMarker.replace("BEGIN", "END"); - derBytes = readBytes(reader, endMarker); - return; - } - } - throw new IOException("Invalid PEM file: no begin marker"); - } finally { - reader.close(); - } - } - - - /** - * Read the lines between BEGIN and END marker and convert - * the Base64 encoded content into binary byte array. - * - * @return DER encoded octet stream - * @throws IOException - */ - private byte[] readBytes(BufferedReader reader, String endMarker) throws IOException - { - String line = null; - StringBuffer buf = new StringBuffer(); - - while ((line = reader.readLine()) != null) - { - if (line.indexOf(endMarker) != -1) { - - return OAuthSignatureMethod.decodeBase64(buf.toString()); - } - - buf.append(line.trim()); - } - - throw new IOException("Invalid PEM file: No end marker"); - } -} diff --git a/bbb-lti/src/java/net/oauth/signature/pem/PKCS1EncodedKeySpec.java b/bbb-lti/src/java/net/oauth/signature/pem/PKCS1EncodedKeySpec.java deleted file mode 100644 index 5cb893b102d34c97fb65dfd3106d66481de42628..0000000000000000000000000000000000000000 --- a/bbb-lti/src/java/net/oauth/signature/pem/PKCS1EncodedKeySpec.java +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2009 AOL LLC. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - **************************************************************************** - * - * @author: zhang - * @version: $Revision: 73016 $ - * @created: Apr 24, 2009 - * - * Description: A KeySpec for PKCS#1 encoded RSA private key - * - ****************************************************************************/ -package net.oauth.signature.pem; - -import java.io.IOException; -import java.math.BigInteger; -import java.security.spec.RSAPrivateCrtKeySpec; - -/** - * PKCS#1 encoded private key is commonly used with OpenSSL. It provides CRT parameters - * so the private key operation can be much faster than using exponent/modulus alone, - * which is the case for PKCS#8 encoded key. - * - * <p/>Unfortunately, JCE doesn't have an API to decode the DER. This class takes DER - * buffer and decoded into CRT key. - * - * @author zhang - */ -public class PKCS1EncodedKeySpec { - - private RSAPrivateCrtKeySpec keySpec; - - /** - * Create a PKCS#1 keyspec from DER encoded buffer - * - * @param keyBytes DER encoded octet stream - * @throws IOException - */ - public PKCS1EncodedKeySpec(byte[] keyBytes) throws IOException { - decode(keyBytes); - } - - /** - * Get the key spec that JCE understands. - * - * @return CRT keyspec defined by JCE - */ - public RSAPrivateCrtKeySpec getKeySpec() { - return keySpec; - } - - /** - * Decode PKCS#1 encoded private key into RSAPrivateCrtKeySpec. - * - * <p/>The ASN.1 syntax for the private key with CRT is - * - * <pre> - * -- - * -- Representation of RSA private key with information for the CRT algorithm. - * -- - * RSAPrivateKey ::= SEQUENCE { - * version Version, - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER, -- (inverse of q) mod p - * otherPrimeInfos OtherPrimeInfos OPTIONAL - * } - * </pre> - * - * @param keyBytes PKCS#1 encoded key - * @throws IOException - */ - - private void decode(byte[] keyBytes) throws IOException { - - DerParser parser = new DerParser(keyBytes); - - Asn1Object sequence = parser.read(); - if (sequence.getType() != DerParser.SEQUENCE) - throw new IOException("Invalid DER: not a sequence"); //$NON-NLS-1$ - - // Parse inside the sequence - parser = sequence.getParser(); - - parser.read(); // Skip version - BigInteger modulus = parser.read().getInteger(); - BigInteger publicExp = parser.read().getInteger(); - BigInteger privateExp = parser.read().getInteger(); - BigInteger prime1 = parser.read().getInteger(); - BigInteger prime2 = parser.read().getInteger(); - BigInteger exp1 = parser.read().getInteger(); - BigInteger exp2 = parser.read().getInteger(); - BigInteger crtCoef = parser.read().getInteger(); - - keySpec = new RSAPrivateCrtKeySpec( - modulus, publicExp, privateExp, prime1, prime2, - exp1, exp2, crtCoef); - } -}