Class that an interface to caching HTTP signatures for a given 19 | * {@link Credentials} instance.
20 | * 21 | *HTTP signature dates have a resolution of one second. If a two signatures 22 | * are requested for the exact same signature date time (within 1 second), then 23 | * we do not need to recalculate the signature (a computationally expensive 24 | * operation). In order to accomplish this, this class contains two fields 25 | * that cache the last signature date time and the last signature. Using the 26 | * cache, when two requests come through with the same date time, then we only 27 | * need to calculate the signature for a single request.
28 | * 29 | *This class maintains a cache per {@link Credentials} object because 30 | * the signature will differ due to different credentials using different 31 | * signing keys.
32 | * 33 | * @author Elijah Zupancic 34 | * @since 4.0.0 35 | */ 36 | class HttpSignatureCache { 37 | /** 38 | * Credentials to associate cache with. 39 | */ 40 | private final Credentials credentials; 41 | 42 | /** 43 | * The date time of the last HTTP signature. 44 | */ 45 | private String lastDate = ""; 46 | 47 | /** 48 | * The last generated HTTP signature associated with this credential. 49 | */ 50 | private String lastSignature = ""; 51 | 52 | /** 53 | * Creates a new cache for the specified credential. 54 | * 55 | * @param credentials credentials to associate cache with 56 | */ 57 | HttpSignatureCache(final Credentials credentials) { 58 | if (credentials == null) { 59 | throw new IllegalArgumentException("Credentials must be present"); 60 | } 61 | 62 | if (credentials.getUserPrincipal() == null) { 63 | throw new IllegalArgumentException("User principal must be present"); 64 | } 65 | 66 | if (credentials.getUserPrincipal().getName() == null) { 67 | throw new IllegalArgumentException("User principal name must be present"); 68 | } 69 | 70 | this.credentials = credentials; 71 | } 72 | 73 | /** 74 | * Method that attempts to get a valid cached signature based on the 75 | * specified parameters. If a cached credential is not valid, then 76 | * a new signature will be generated and stored for later use in caching. 77 | * 78 | * @param stringDate date to use for HTTP signature 79 | * @param signer signer class to use for generating signature 80 | * @param keyPair cryptographic key pair to use for generating signature 81 | * 82 | * @return a valid HTTP signature string to be passed as a header value 83 | * 84 | * @throws AuthenticationException thrown if there is a problem authenticating the signature 85 | */ 86 | synchronized String updateAndGetSignature(final String stringDate, 87 | final Signer signer, 88 | final KeyPair keyPair) 89 | throws AuthenticationException { 90 | 91 | // Signing date time is equal, so we returned cached signature 92 | // stringDate parameter should *never* be null or blank 93 | if (lastDate.equals(stringDate)) { 94 | return lastSignature; 95 | } 96 | 97 | lastDate = stringDate; 98 | 99 | final String login = credentials.getUserPrincipal().getName(); 100 | 101 | // If date didn't match, then we calculate signature and store it 102 | try { 103 | final String authz = signer.createAuthorizationHeader( 104 | login, keyPair, stringDate); 105 | lastSignature = authz; 106 | 107 | return authz; 108 | } catch (HttpSignatureException e) { 109 | String details = String.format("Unable to authenticate [%s] " 110 | + "using keypair [%s]", 111 | login, keyPair); 112 | throw new AuthenticationException(details, e); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /apache-http-client/src/main/java/com/joyent/http/signature/apache/httpclient/HttpSignatureConfigurator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.http.signature.apache.httpclient; 9 | 10 | import com.joyent.http.signature.ThreadLocalSigner; 11 | import org.apache.http.auth.AuthScheme; 12 | import org.apache.http.auth.Credentials; 13 | import org.apache.http.client.AuthenticationStrategy; 14 | import org.apache.http.impl.client.HttpClientBuilder; 15 | 16 | import java.security.KeyPair; 17 | 18 | /** 19 | * Configuration helper class for configuring a {@link HttpClientBuilder} to use 20 | * HTTP Signatures authentication. 21 | * 22 | * @author Elijah Zupancic 23 | * @since 2.0.5 24 | */ 25 | @SuppressWarnings({"checkstyle:javadocmethod", "checkstyle:javadoctype", 26 | "checkstyle:javadocvariable", "unused"}) 27 | public class HttpSignatureConfigurator { 28 | /** 29 | * Public/private keypair object used to sign HTTP requests. 30 | */ 31 | private final KeyPair keyPair; 32 | 33 | /** 34 | * Credentials containing a username. 35 | */ 36 | private final Credentials credentials; 37 | 38 | /** 39 | * Authentication scheme to use to authenticate requests. 40 | */ 41 | private final HttpSignatureAuthScheme authScheme; 42 | 43 | /** 44 | * Authentication strategy instance that is assigned to all requests configured in the 45 | * {@link HttpClientBuilder}. 46 | */ 47 | private final AuthenticationStrategy authenticationStrategy; 48 | 49 | /** 50 | * Creates a new instance. 51 | * 52 | * @param keyPair public/private keypair object used to sign HTTP requests 53 | * @param credentials credentials containing a username 54 | * @param useNativeCodeToSign true to enable native code acceleration of cryptographic singing 55 | * 56 | * @deprecated Prefer {@link #HttpSignatureConfigurator(KeyPair, 57 | * Credentials, ThreadLocalSigner)} if configuration of Signer 58 | * algorithm, hashes, or providers is required. 59 | */ 60 | @Deprecated 61 | public HttpSignatureConfigurator(final KeyPair keyPair, 62 | final Credentials credentials, 63 | final boolean useNativeCodeToSign) { 64 | this.keyPair = keyPair; 65 | this.credentials = credentials; 66 | this.authScheme = new HttpSignatureAuthScheme(keyPair, useNativeCodeToSign); 67 | this.authenticationStrategy = new HttpSignatureAuthenticationStrategy(authScheme, 68 | credentials); 69 | } 70 | 71 | /** 72 | * Creates a new instance. 73 | * 74 | * @param keyPair public/private keypair object used to sign HTTP requests 75 | * @param credentials credentials containing a username 76 | * @param signer For use with http signature 77 | */ 78 | public HttpSignatureConfigurator(final KeyPair keyPair, 79 | final Credentials credentials, 80 | final ThreadLocalSigner signer) { 81 | this.keyPair = keyPair; 82 | this.credentials = credentials; 83 | this.authScheme = new HttpSignatureAuthScheme(keyPair, signer); 84 | this.authenticationStrategy = new HttpSignatureAuthenticationStrategy(authScheme, 85 | credentials); 86 | } 87 | 88 | 89 | /** 90 | * Configures a {@link HttpClientBuilder} to use HTTP Signature authentication. 91 | * 92 | * @param httpClientBuilder build to configure 93 | */ 94 | public void configure(final HttpClientBuilder httpClientBuilder) { 95 | httpClientBuilder.setTargetAuthenticationStrategy(authenticationStrategy); 96 | } 97 | 98 | public KeyPair getKeyPair() { 99 | return keyPair; 100 | } 101 | 102 | public Credentials getCredentials() { 103 | return credentials; 104 | } 105 | 106 | public AuthScheme getAuthScheme() { 107 | return authScheme; 108 | } 109 | 110 | public AuthenticationStrategy getAuthenticationStrategy() { 111 | return authenticationStrategy; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /apache-http-client/src/main/java/com/joyent/http/signature/apache/httpclient/HttpSignatureRequestInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.http.signature.apache.httpclient; 9 | 10 | import org.apache.http.Header; 11 | import org.apache.http.HttpException; 12 | import org.apache.http.HttpRequest; 13 | import org.apache.http.HttpRequestInterceptor; 14 | import org.apache.http.auth.Credentials; 15 | import org.apache.http.protocol.HttpContext; 16 | 17 | import java.io.IOException; 18 | 19 | /** 20 | * Alternative to HTTP Client {@link org.apache.http.auth.AuthScheme} approach 21 | * that uses a {@link org.apache.http.HttpRequestInterceptor} to perform 22 | * HTTP signature authentication. 23 | * 24 | * @author Elijah Zupancic 25 | * @since 3.0.0 26 | */ 27 | public class HttpSignatureRequestInterceptor implements HttpRequestInterceptor { 28 | /** 29 | * Flag indicating that HTTP signature authentication is enabled. 30 | */ 31 | private final boolean authEnabled; 32 | 33 | /** 34 | * Authentication scheme instance to use to create authentication header. 35 | */ 36 | private final HttpSignatureAuthScheme authScheme; 37 | 38 | /** 39 | * Credentials of the user authenticating using HTTP signatures. 40 | */ 41 | private final Credentials credentials; 42 | 43 | /** 44 | * Creates a new instance. 45 | * 46 | * @param authScheme authentication scheme used to generate signature 47 | * @param credentials credentials of user authenticating 48 | * @param authEnabled flag indicating if authentication is enabled 49 | */ 50 | public HttpSignatureRequestInterceptor(final HttpSignatureAuthScheme authScheme, 51 | final Credentials credentials, 52 | final boolean authEnabled) { 53 | this.authScheme = authScheme; 54 | this.credentials = credentials; 55 | this.authEnabled = authEnabled; 56 | } 57 | 58 | @Override 59 | public void process(final HttpRequest request, final HttpContext context) 60 | throws HttpException, IOException { 61 | if (!authEnabled) { 62 | return; 63 | } 64 | 65 | final long start = System.nanoTime(); 66 | final Header authorization = authScheme.authenticate( 67 | this.credentials, request, context); 68 | final long end = System.nanoTime(); 69 | 70 | request.setHeader(authorization); 71 | request.setHeader("x-http-signing-time-ns", String.valueOf(end - start)); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /apache-http-client/src/main/java/com/joyent/http/signature/apache/httpclient/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Package containing utility classes for using HTTP Signature with the 11 | * Apache HTTP Client. 12 | * 13 | * There are two primary implementations an {@link org.apache.http.auth.AuthScheme} 14 | * implementation implemented as {@link com.joyent.http.signature.apache.httpclient.HttpSignatureAuthScheme} and 15 | * a {@link org.apache.http.HttpRequestInterceptor} implementation implemented 16 | * as {@link com.joyent.http.signature.apache.httpclient.HttpSignatureRequestInterceptor}. 17 | * Both classes are valid ways of implementing HTTP Signatures with the Apache 18 | * Commons HTTP Client. Depending on your application one implementation may 19 | * be better than another. 20 | * 21 | * @author Elijah Zupancic 22 | */ 23 | package com.joyent.http.signature.apache.httpclient; 24 | -------------------------------------------------------------------------------- /apache-http-client/src/test/java/com/joyent/http/signature/apache/httpclient/HttpSignatureAuthIT.java: -------------------------------------------------------------------------------- 1 | package com.joyent.http.signature.apache.httpclient; 2 | 3 | import com.joyent.http.signature.ThreadLocalSigner; 4 | import org.apache.http.*; 5 | import org.apache.http.auth.Credentials; 6 | import org.apache.http.auth.UsernamePasswordCredentials; 7 | import org.apache.http.client.config.RequestConfig; 8 | import org.apache.http.client.methods.HttpHead; 9 | import org.apache.http.client.protocol.HttpClientContext; 10 | import org.apache.http.entity.ContentType; 11 | import org.apache.http.impl.client.CloseableHttpClient; 12 | import org.apache.http.impl.client.HttpClientBuilder; 13 | import org.apache.http.impl.client.HttpClients; 14 | import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 15 | import org.apache.http.message.BasicHeader; 16 | 17 | import java.io.File; 18 | import java.io.IOException; 19 | import java.net.InetSocketAddress; 20 | import java.net.Proxy; 21 | import java.net.ProxySelector; 22 | import java.net.URI; 23 | import java.security.KeyPair; 24 | import java.util.*; 25 | 26 | import static org.testng.Assert.assertEquals; 27 | 28 | /** 29 | * Integration test for testing the Apache HTTP Client with HTTP Signature 30 | * authentication. This test needs to be run manually at this time. 31 | */ 32 | @SuppressWarnings("deprecation") 33 | public class HttpSignatureAuthIT { 34 | public static final String SDC_KEY_ID_ENV_KEY = "SDC_KEY_ID"; 35 | private static final String SDC_URL_ENV_KEY = "SDC_URL"; 36 | private static final String SDC_ACCOUNT_ENV_KEY = "SDC_ACCOUNT"; 37 | private static final String SDC_KEY_PATH_ENV_KEY = "SDC_KEY_PATH"; 38 | 39 | private static final ThreadLocalSigner SIGNER = new ThreadLocalSigner(); 40 | 41 | // @Test 42 | public void canAuthenticate() throws IOException { 43 | final KeyPair keyPair = createKeyPair(); 44 | 45 | final String user = System.getenv(SDC_ACCOUNT_ENV_KEY); 46 | Objects.requireNonNull(user, SDC_ACCOUNT_ENV_KEY + " must be set"); 47 | 48 | final String keyId = System.getenv(SDC_KEY_ID_ENV_KEY); 49 | Objects.requireNonNull(keyId, SDC_KEY_ID_ENV_KEY + " must be set"); 50 | 51 | final Credentials credentials = new UsernamePasswordCredentials( 52 | user, keyId); 53 | HttpSignatureConfigurator configurator = new HttpSignatureConfigurator(keyPair, 54 | credentials, true); 55 | 56 | try (CloseableHttpClient conn = createConnection(configurator)) { 57 | String baseUrl = System.getenv(SDC_URL_ENV_KEY); 58 | Objects.requireNonNull(baseUrl, SDC_URL_ENV_KEY + " must be present"); 59 | 60 | URI uri = URI.create(String.format("%s/%s/machines", 61 | baseUrl, user)); 62 | 63 | HttpHead head = new HttpHead(uri); 64 | HttpClientContext context = new HttpClientContext(); 65 | HttpResponse response = conn.execute(head, context); 66 | 67 | assertEquals(response.getStatusLine().getStatusCode(), 68 | HttpStatus.SC_OK); 69 | } 70 | } 71 | 72 | private CloseableHttpClient createConnection(final HttpSignatureConfigurator configurator) { 73 | final PoolingHttpClientConnectionManager connectionManager = 74 | new PoolingHttpClientConnectionManager(); 75 | 76 | final RequestConfig requestConfig = RequestConfig.custom() 77 | .setAuthenticationEnabled(true) 78 | .setContentCompressionEnabled(true) 79 | .build(); 80 | 81 | final Collection extends Header> headers = Arrays.asList( 82 | new BasicHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType()) 83 | ); 84 | 85 | final HttpClientBuilder httpClientBuilder = HttpClients.custom() 86 | .setDefaultHeaders(Collections.unmodifiableCollection(headers)) 87 | .setConnectionManager(connectionManager) 88 | .setDefaultRequestConfig(requestConfig); 89 | 90 | configurator.configure(httpClientBuilder); 91 | 92 | final HttpHost proxyHost = findProxyServer(); 93 | 94 | if (proxyHost != null) { 95 | httpClientBuilder.setProxy(proxyHost); 96 | } 97 | 98 | return httpClientBuilder.build(); 99 | } 100 | 101 | /** 102 | * Creates a {@link KeyPair} object based on the factory's configuration. 103 | * @return an encryption key pair 104 | */ 105 | private KeyPair createKeyPair() { 106 | final KeyPair keyPair; 107 | final String keyPath = System.getenv(SDC_KEY_PATH_ENV_KEY); 108 | Objects.requireNonNull(keyPath, SDC_KEY_PATH_ENV_KEY + " must be set"); 109 | 110 | try { 111 | keyPair = SIGNER.get().getKeyPair(new File(keyPath).toPath()); 112 | } catch (IOException e) { 113 | String msg = String.format("Unable to read key files from path: %s", 114 | keyPath); 115 | throw new RuntimeException(msg, e); 116 | } 117 | 118 | return keyPair; 119 | } 120 | 121 | /** 122 | * Finds the host of the proxy server that was configured as part of the 123 | * JVM settings. 124 | * 125 | * @return proxy server as {@link HttpHost}, if no proxy then null 126 | */ 127 | private HttpHost findProxyServer() { 128 | final ProxySelector proxySelector = ProxySelector.getDefault(); 129 | final String rootURI = System.getenv(SDC_URL_ENV_KEY); 130 | Objects.requireNonNull(rootURI, "SDC_URL must be set"); 131 | ListClass copied wholesale from the com.squareup.crypto.rsa project that uses 30 | * native libgmp to improve RSA performance. The only modifications to this 31 | * class are formatting and style.
32 | */ 33 | public class MantaNativeRSACoreEngine { 34 | private RSAKeyParameters key; 35 | private boolean forEncryption; 36 | private boolean isPrivate; 37 | private boolean isSmallExponent; 38 | 39 | // cached components for private CRT key 40 | private GmpInteger p; 41 | private GmpInteger q; 42 | private GmpInteger dP; 43 | private GmpInteger dQ; 44 | private BigInteger qInv; 45 | 46 | // cached components for public key 47 | private GmpInteger exponent; 48 | private GmpInteger modulus; 49 | 50 | /** 51 | * initialise the RSA engine. 52 | * 53 | * @param forEncryption true if we are encrypting, false otherwise. 54 | * @param param the necessary RSA key parameters. 55 | */ 56 | public void init( 57 | boolean forEncryption, 58 | CipherParameters param) { 59 | if (param instanceof ParametersWithRandom) { 60 | ParametersWithRandom rParam = (ParametersWithRandom) param; 61 | 62 | key = (RSAKeyParameters) rParam.getParameters(); 63 | } else { 64 | key = (RSAKeyParameters) param; 65 | } 66 | 67 | this.forEncryption = forEncryption; 68 | 69 | if (key instanceof RSAPrivateCrtKeyParameters) { 70 | isPrivate = true; 71 | // 72 | // we have the extra factors, use the Chinese Remainder Theorem - the author 73 | // wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for 74 | // advice regarding the expression of this. 75 | // 76 | RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters) key; 77 | 78 | p = new GmpInteger(crtKey.getP()); 79 | q = new GmpInteger(crtKey.getQ()); 80 | dP = new GmpInteger(crtKey.getDP()); 81 | dQ = new GmpInteger(crtKey.getDQ()); 82 | qInv = crtKey.getQInv(); 83 | 84 | exponent = modulus = null; 85 | } else { 86 | isPrivate = false; 87 | exponent = new GmpInteger(key.getExponent()); 88 | modulus = new GmpInteger(key.getModulus()); 89 | isSmallExponent = exponent.bitLength() < 64; 90 | 91 | p = q = dP = dQ = null; 92 | qInv = null; 93 | } 94 | } 95 | 96 | /** 97 | * Return the maximum size for an input block to this engine. 98 | * For RSA this is always one byte less than the key size on 99 | * encryption, and the same length as the key size on decryption. 100 | * 101 | * @return maximum size for an input block. 102 | */ 103 | public int getInputBlockSize() { 104 | int bitSize = key.getModulus().bitLength(); 105 | 106 | if (forEncryption) { 107 | return (bitSize + 7) / 8 - 1; 108 | } else { 109 | return (bitSize + 7) / 8; 110 | } 111 | } 112 | 113 | /** 114 | * Return the maximum size for an output block to this engine. 115 | * For RSA this is always one byte less than the key size on 116 | * decryption, and the same length as the key size on encryption. 117 | * 118 | * @return maximum size for an output block. 119 | */ 120 | public int getOutputBlockSize() { 121 | int bitSize = key.getModulus().bitLength(); 122 | 123 | if (forEncryption) { 124 | return (bitSize + 7) / 8; 125 | } else { 126 | return (bitSize + 7) / 8 - 1; 127 | } 128 | } 129 | 130 | public BigInteger convertInput( 131 | byte[] in, 132 | int inOff, 133 | int inLen) { 134 | if (inLen > (getInputBlockSize() + 1)) { 135 | throw new DataLengthException("input too large for RSA cipher."); 136 | } else if (inLen == (getInputBlockSize() + 1) && !forEncryption) { 137 | throw new DataLengthException("input too large for RSA cipher."); 138 | } 139 | 140 | byte[] block; 141 | 142 | if (inOff != 0 || inLen != in.length) { 143 | block = new byte[inLen]; 144 | 145 | System.arraycopy(in, inOff, block, 0, inLen); 146 | } else { 147 | block = in; 148 | } 149 | 150 | BigInteger res = new BigInteger(1, block); 151 | if (res.compareTo(key.getModulus()) >= 0) { 152 | throw new DataLengthException("input too large for RSA cipher."); 153 | } 154 | 155 | return res; 156 | } 157 | 158 | public byte[] convertOutput( 159 | BigInteger result) { 160 | byte[] output = result.toByteArray(); 161 | 162 | if (forEncryption) { 163 | if (output[0] == 0 && output.length > getOutputBlockSize()) // have ended up with an extra zero byte, copy down. 164 | { 165 | byte[] tmp = new byte[output.length - 1]; 166 | 167 | System.arraycopy(output, 1, tmp, 0, tmp.length); 168 | 169 | return tmp; 170 | } 171 | 172 | if (output.length < getOutputBlockSize()) // have ended up with less bytes than normal, lengthen 173 | { 174 | byte[] tmp = new byte[getOutputBlockSize()]; 175 | 176 | System.arraycopy(output, 0, tmp, tmp.length - output.length, output.length); 177 | 178 | return tmp; 179 | } 180 | } else { 181 | if (output[0] == 0) // have ended up with an extra zero byte, copy down. 182 | { 183 | byte[] tmp = new byte[output.length - 1]; 184 | 185 | System.arraycopy(output, 1, tmp, 0, tmp.length); 186 | 187 | return tmp; 188 | } 189 | } 190 | 191 | return output; 192 | } 193 | 194 | public BigInteger processBlock(BigInteger input) { 195 | if (isPrivate) { 196 | BigInteger mP, mQ, h, m; 197 | 198 | // mP = ((input mod p) ^ dP)) mod p 199 | mP = modPowSecure(input.remainder(p), dP, p); 200 | 201 | // mQ = ((input mod q) ^ dQ)) mod q 202 | mQ = modPowSecure(input.remainder(q), dQ, q); 203 | 204 | // h = qInv * (mP - mQ) mod p 205 | h = mP.subtract(mQ); 206 | h = h.multiply(qInv); 207 | h = h.mod(p); // mod (in Java) returns the positive residual 208 | 209 | // m = h * q + mQ 210 | m = h.multiply(q); 211 | m = m.add(mQ); 212 | 213 | return m; 214 | } else { 215 | if (isSmallExponent) { 216 | // Public key with reasonable (small) exponent, no need for secure. 217 | return modPowInsecure(input, exponent, modulus); 218 | } else { 219 | // Client mistakenly configured private key as public? Better be safe than sorry. 220 | return modPowSecure(input, exponent, modulus); 221 | } 222 | } 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /common/src/main/java/com/joyent/http/signature/crypto/NativeRSABlindedEngine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000 - 2016 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org) 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 | * OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | package com.joyent.http.signature.crypto; 23 | 24 | import com.squareup.jnagmp.Gmp; 25 | import org.bouncycastle.crypto.CipherParameters; 26 | import org.bouncycastle.crypto.DataLengthException; 27 | import org.bouncycastle.crypto.engines.RSABlindedEngine; 28 | import org.bouncycastle.crypto.params.ParametersWithRandom; 29 | import org.bouncycastle.crypto.params.RSAKeyParameters; 30 | import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; 31 | import org.bouncycastle.util.BigIntegers; 32 | 33 | import java.math.BigInteger; 34 | import java.security.SecureRandom; 35 | 36 | /** 37 | *This is a copy of {@link RSABlindedEngine} with the RSA core engine 38 | * replace with a native implementation. We copied the library code here 39 | * because there is no better way to for us to inherit the properties.
40 | * 41 | *Note: changes from the original are only using libgmp to do modpow.
42 | * 43 | *Relevant copyright belongs to:
44 | * Copyright (c) 2000 - 2015 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
45 | *
Do you agree to change the licensing from = 96 | the MIT license for the Java Manta Project (https://github.com/joyent/java-manta) to the MPL v2?
Do you agree to change the licensing from the MIT license = 102 | for the Java HTTP Signature Project (https://github.com/joyent/java-http-s= 104 | ignature) to the MPL v2?