use of com.microsoft.identity.common.exception.ClientException in project microsoft-authentication-library-common-for-android by AzureAD.
the class JWSBuilder method generateSignedJWT.
/**
* Generate the signed JWT.
*/
public String generateSignedJWT(String nonce, String audience, RSAPrivateKey privateKey, RSAPublicKey pubKey, X509Certificate cert) throws ClientException {
// http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-25
// In the JWS Compact Serialization, a JWS object is represented as the
// combination of these three string values,
// BASE64URL(UTF8(JWS Protected Header)),
// BASE64URL(JWS Payload), and
// BASE64URL(JWS Signature),
// concatenated in that order, with the three strings being separated by
// two period ('.') characters.
// Base64 encoding without padding, wrapping and urlsafe.
final String methodName = ":generateSignedJWT";
if (StringExtensions.isNullOrBlank(nonce)) {
throw new IllegalArgumentException("nonce");
}
if (StringExtensions.isNullOrBlank(audience)) {
throw new IllegalArgumentException("audience");
}
if (privateKey == null) {
throw new IllegalArgumentException("privateKey");
}
if (pubKey == null) {
throw new IllegalArgumentException("pubKey");
}
Gson gson = new Gson();
Claims claims = new Claims();
claims.mNonce = nonce;
claims.mAudience = audience;
claims.mIssueAt = System.currentTimeMillis() / SECONDS_MS;
JwsHeader header = new JwsHeader();
header.mAlgorithm = JWS_HEADER_ALG;
// recommended UpperCase in JWT Spec
header.mType = "JWT";
final String signingInput;
final String signature;
try {
// Server side expects x5c in the header to verify the signer and
// lookup the certificate from device registration
// Each string in the array is a base64
// encoded ([RFC4648] Section 4 -- not base64url encoded) DER
// [ITU.X690.1994] PKIX certificate value. The certificate
// containing the public key corresponding to the key used
// to digitally sign the JWS MUST be the first certificate
// http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-27
header.mCert = new String[1];
header.mCert[0] = new String(Base64.encode(cert.getEncoded(), Base64.NO_WRAP), AuthenticationConstants.CHARSET_UTF8);
// redundant but current ADFS code base is looking for
String headerJsonString = gson.toJson(header);
String claimsJsonString = gson.toJson(claims);
Logger.verbose(TAG + methodName, "Generate client certificate challenge response JWS Header. ");
signingInput = StringExtensions.encodeBase64URLSafeString(headerJsonString.getBytes(AuthenticationConstants.CHARSET_UTF8)) + "." + StringExtensions.encodeBase64URLSafeString(claimsJsonString.getBytes(AuthenticationConstants.CHARSET_UTF8));
signature = sign(privateKey, signingInput.getBytes(AuthenticationConstants.CHARSET_UTF8));
} catch (UnsupportedEncodingException e) {
throw new ClientException(ErrorStrings.UNSUPPORTED_ENCODING, "Unsupported encoding", e);
} catch (CertificateEncodingException e) {
throw new ClientException(ErrorStrings.CERTIFICATE_ENCODING_ERROR, "Certificate encoding error", e);
}
return signingInput + "." + signature;
}
use of com.microsoft.identity.common.exception.ClientException in project microsoft-authentication-library-common-for-android by AzureAD.
the class BrokerOperationExecutorTests method expectBindFailureException.
private void expectBindFailureException(final List<IIpcStrategy> strategyList) {
try {
final BrokerOperationExecutor executor = new BrokerOperationExecutor(strategyList);
executor.execute(getMockParameter(), getBrokerOperation());
Assert.fail("Failure is expected.");
} catch (final BaseException e) {
Assert.assertTrue(e instanceof ClientException);
Assert.assertEquals(e.getErrorCode(), ErrorStrings.BROKER_BIND_SERVICE_FAILED);
Assert.assertEquals(e.getSuppressed().length, strategyList.size());
}
}
use of com.microsoft.identity.common.exception.ClientException in project microsoft-authentication-library-common-for-android by AzureAD.
the class BrokerValidator method verifySignatureAndThrow.
/**
* Verifies that the installed broker package's signing certificate hash matches the known
* release certificate hash.
* <p>
* If signature hash verification fails, this will throw a Client exception containing the cause of error, which could contain a list of mismatch hashes.
*
* @param brokerPackageName The broker package to inspect.
* @return SignatureHash of brokerPackageName, if the verification succeeds..
*/
public String verifySignatureAndThrow(final String brokerPackageName) throws ClientException {
try {
// Read all the certificates associated with the package name. In higher version of
// android sdk, package manager will only returned the cert that is used to sign the
// APK. Even a cert is claimed to be issued by another certificates, sdk will return
// the signing cert. However, for the lower version of android, it will return all the
// certs in the chain. We need to verify that the cert chain is correctly chained up.
final List<X509Certificate> certs = readCertDataForBrokerApp(brokerPackageName);
// Verify the cert list contains the cert we trust.
final String signatureHash = verifySignatureHash(certs);
// no need to perform certificate chain validation.
if (certs.size() > 1) {
verifyCertificateChain(certs);
}
return signatureHash;
} catch (NameNotFoundException e) {
throw new ClientException(ErrorStrings.APP_PACKAGE_NAME_NOT_FOUND, e.getMessage(), e);
} catch (NoSuchAlgorithmException e) {
throw new ClientException(ErrorStrings.NO_SUCH_ALGORITHM, e.getMessage(), e);
} catch (final IOException | GeneralSecurityException e) {
throw new ClientException(ErrorStrings.BROKER_VERIFICATION_FAILED, e.getMessage(), e);
}
}
use of com.microsoft.identity.common.exception.ClientException in project microsoft-authentication-library-common-for-android by AzureAD.
the class BrokerValidator method readCertDataForBrokerApp.
@SuppressLint("PackageManagerGetSignatures")
@SuppressWarnings("deprecation")
private List<X509Certificate> readCertDataForBrokerApp(final String brokerPackageName) throws NameNotFoundException, ClientException, IOException, GeneralSecurityException {
// GET_SIGNATURES has been deprecated
final PackageInfo packageInfo = mContext.getPackageManager().getPackageInfo(brokerPackageName, PackageManager.GET_SIGNATURES);
if (packageInfo == null) {
throw new ClientException(ErrorStrings.APP_PACKAGE_NAME_NOT_FOUND, "No broker package existed.");
}
// .signatures has been deprecated
if (packageInfo.signatures == null || packageInfo.signatures.length == 0) {
throw new ClientException(BROKER_APP_VERIFICATION_FAILED, "No signature associated with the broker package.");
}
final List<X509Certificate> certificates = new ArrayList<>(packageInfo.signatures.length);
for (final Signature signature : packageInfo.signatures) {
final byte[] rawCert = signature.toByteArray();
final InputStream certStream = new ByteArrayInputStream(rawCert);
final CertificateFactory certificateFactory;
final X509Certificate x509Certificate;
try {
certificateFactory = CertificateFactory.getInstance("X509");
x509Certificate = (X509Certificate) certificateFactory.generateCertificate(certStream);
certificates.add(x509Certificate);
} catch (final CertificateException e) {
throw new ClientException(BROKER_APP_VERIFICATION_FAILED);
}
}
return certificates;
}
use of com.microsoft.identity.common.exception.ClientException in project microsoft-authentication-library-common-for-android by AzureAD.
the class AzureActiveDirectoryAudience method getTenantUuidForAlias.
/**
* Must be called on a worker thread.
*
* Method which queries the {@link OpenIdProviderConfiguration}
* to get tenant UUID for the authority with tenant alias.
*
* @return : tenant UUID
* @throws ServiceException
* @throws ClientException
*/
@WorkerThread
public String getTenantUuidForAlias(@NonNull final String authority) throws ServiceException, ClientException {
// if the tenant id is already a UUID, return
if (StringUtil.isUuid(mTenantId)) {
return mTenantId;
}
final OpenIdProviderConfiguration providerConfiguration = loadOpenIdProviderConfigurationMetadata(authority);
final String issuer = providerConfiguration.getIssuer();
final Uri issuerUri = Uri.parse(issuer);
final List<String> paths = issuerUri.getPathSegments();
if (paths.isEmpty()) {
final String errMsg = "OpenId Metadata did not contain a path to the tenant";
com.microsoft.identity.common.internal.logging.Logger.error(TAG, errMsg, null);
throw new ClientException(errMsg);
}
final String tenantUUID = paths.get(0);
if (!StringUtil.isUuid(tenantUUID)) {
final String errMsg = "OpenId Metadata did not contain UUID in the path ";
Logger.error(TAG, errMsg, null);
throw new ClientException(errMsg);
}
return tenantUUID;
}
Aggregations