Skip to content

Commit 7ea5c92

Browse files
somalayaCopilot
andauthored
Added telemetry to capture encrypt and decrypt operations in device PoP scenarios, Fixes AB#3468126 (#2844)
**What :** Adding telemetry to capture Encrypt and Decrypt crypto operations in device PoP cases **Why :** We think these operations are not invoked at all and we marked it as deprecated in previous PRs. But to remove them completely, we need the telemetry to check if they are for sure not being invoked. **Testing :** Verified that the spans are getting created correctly. Fixes [AB#3468126](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3468126) --------- Co-authored-by: Copilot <[email protected]>
1 parent a27d627 commit 7ea5c92

File tree

3 files changed

+74
-85
lines changed

3 files changed

+74
-85
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ vNext
1010
- [MINOR] Adds Authentication Constants to be used for broker latency timestamp in response (#2831)
1111
- [MINOR] Implemented Common logic to retrieve broker latency duration from result Broker Bundle (#2835)
1212
- [MINOR] Add support for WebApps getToken API (#2803)
13+
- [MINOR] Added telemetry to capture the DRSNonce call (#3302)
1314

1415
Version 23.1.1
1516
-----------

common4j/src/main/com/microsoft/identity/common/java/opentelemetry/SpanName.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,9 @@ public enum SpanName {
8383
/**
8484
* Span name for DRS (Device Registration Service) nonce request operations.
8585
*/
86-
DRSNonceRequest
86+
DRSNonceRequest,
87+
/**
88+
* Span name for Device POP crypto operations.
89+
*/
90+
DevicePopCryptoOperation
8791
}

common4j/src/main/com/microsoft/identity/common/java/platform/AbstractDevicePopManager.java

Lines changed: 68 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import static com.microsoft.identity.common.java.exception.ClientException.NO_SUCH_PADDING;
4040
import static com.microsoft.identity.common.java.exception.ClientException.SIGNING_FAILURE;
4141
import static com.microsoft.identity.common.java.exception.ClientException.THUMBPRINT_COMPUTATION_FAILURE;
42+
import static com.microsoft.identity.common.java.exception.ClientException.UNKNOWN_CRYPTO_ERROR;
4243
import static com.microsoft.identity.common.java.exception.ClientException.UNKNOWN_EXPORT_FORMAT;
4344
import static com.microsoft.identity.common.java.marker.PerfConstants.CodeMarkerConstants.GENERATE_AT_POP_ASYMMETRIC_KEYPAIR_END;
4445
import static com.microsoft.identity.common.java.marker.PerfConstants.CodeMarkerConstants.GENERATE_AT_POP_ASYMMETRIC_KEYPAIR_START;
@@ -61,6 +62,7 @@
6162
import com.microsoft.identity.common.java.opentelemetry.OTelUtility;
6263
import com.microsoft.identity.common.java.opentelemetry.SpanExtension;
6364
import com.microsoft.identity.common.java.opentelemetry.SpanName;
65+
import com.microsoft.identity.common.java.opentelemetry.AttributeName;
6466
import com.microsoft.identity.common.java.util.StringUtil;
6567
import com.microsoft.identity.common.java.util.TaskCompletedCallbackWithError;
6668
import com.nimbusds.jose.JOSEException;
@@ -202,7 +204,7 @@ protected static final class CertificateProperties {
202204

203205
/**
204206
* Properties embedded in the SignedHttpRequest.
205-
* Roughly conforms to: https://tools.ietf.org/html/draft-ietf-oauth-signed-http-request-03
207+
* Roughly conforms to: <a href="https://tools.ietf.org/html/draft-ietf-oauth-signed-http-request-03">...</a>
206208
*/
207209
private static final class SignedHttpRequestJwtClaims {
208210

@@ -589,10 +591,10 @@ public String encrypt(@NonNull final Cipher cipher,
589591

590592
@Override
591593
public byte[] encrypt(@NonNull final Cipher cipher, @NonNull final byte[] plaintext) throws ClientException {
592-
String errCode;
593-
Exception exception;
594594
final String methodTag = TAG + ":encrypt";
595-
try {
595+
final Span span = OTelUtility.createSpan(SpanName.DevicePopCryptoOperation.name());
596+
span.setAttribute(AttributeName.crypto_operation.name(), "encrypt");
597+
try (final Scope scope = SpanExtension.makeCurrentSpan(span)) {
596598
// Load our key material
597599
final KeyStore.PrivateKeyEntry privateKeyEntry = mKeyManager.getEntry();
598600

@@ -607,46 +609,52 @@ public byte[] encrypt(@NonNull final Cipher cipher, @NonNull final byte[] plaint
607609
input.init(javax.crypto.Cipher.ENCRYPT_MODE, publicKey);
608610
}
609611

610-
return input.doFinal(plaintext);
611-
} catch (final InvalidKeyException e) {
612-
errCode = INVALID_KEY;
613-
exception = e;
614-
} catch (final UnrecoverableEntryException e) {
615-
errCode = INVALID_PROTECTION_PARAMS;
616-
exception = e;
617-
} catch (final NoSuchAlgorithmException e) {
618-
errCode = NO_SUCH_ALGORITHM;
619-
exception = e;
620-
} catch (final KeyStoreException e) {
621-
errCode = KEYSTORE_NOT_INITIALIZED;
622-
exception = e;
623-
} catch (final NoSuchPaddingException e) {
624-
errCode = NO_SUCH_PADDING;
625-
exception = e;
626-
} catch (final InvalidAlgorithmParameterException e) {
627-
errCode = INVALID_ALG_PARAMETER;
628-
exception = e;
629-
} catch (final BadPaddingException e) {
630-
errCode = BAD_PADDING;
631-
exception = e;
632-
} catch (final IllegalBlockSizeException e) {
633-
errCode = INVALID_BLOCK_SIZE;
634-
exception = e;
635-
}
636-
637-
final ClientException clientException = new ClientException(
638-
errCode,
639-
exception.getMessage(),
640-
exception
641-
);
612+
final byte[] result = input.doFinal(plaintext);
613+
span.setStatus(StatusCode.OK);
614+
return result;
615+
} catch (final InvalidKeyException | UnrecoverableEntryException | NoSuchAlgorithmException |
616+
KeyStoreException | NoSuchPaddingException | InvalidAlgorithmParameterException |
617+
BadPaddingException | IllegalBlockSizeException e) {
618+
final String errCode = mapCryptoExceptionToErrorCode(e);
619+
span.recordException(e);
620+
span.setStatus(StatusCode.ERROR);
642621

643-
Logger.error(
644-
methodTag,
645-
errCode,
646-
exception
647-
);
622+
final ClientException clientException = new ClientException(errCode, e.getMessage(), e);
623+
Logger.error(methodTag, errCode, e);
624+
throw clientException;
625+
} finally {
626+
span.end();
627+
}
628+
}
648629

649-
throw clientException;
630+
/**
631+
* Maps cryptographic exceptions to corresponding ClientException error code constants.
632+
* This helper method is used by both encrypt and decrypt operations to provide consistent
633+
* error code mappings for various cryptographic failure scenarios.
634+
*
635+
* @param e The exception to map to an error code. Must be non-null.
636+
* @return The corresponding ClientException error code constant.
637+
* Note : Returns {@link ClientException#UNKNOWN_CRYPTO_ERROR} as the default fallback when the exception type doesn't match any known types.
638+
*/
639+
private String mapCryptoExceptionToErrorCode(@NonNull final Exception e) {
640+
if (e instanceof NoSuchAlgorithmException) {
641+
return NO_SUCH_ALGORITHM;
642+
} else if (e instanceof NoSuchPaddingException) {
643+
return NO_SUCH_PADDING;
644+
} else if (e instanceof InvalidKeyException) {
645+
return INVALID_KEY;
646+
} else if (e instanceof UnrecoverableEntryException) {
647+
return INVALID_PROTECTION_PARAMS;
648+
} else if (e instanceof KeyStoreException) {
649+
return KEYSTORE_NOT_INITIALIZED;
650+
} else if (e instanceof BadPaddingException) {
651+
return BAD_PADDING;
652+
} else if (e instanceof IllegalBlockSizeException) {
653+
return INVALID_BLOCK_SIZE;
654+
} else if (e instanceof InvalidAlgorithmParameterException) {
655+
return INVALID_ALG_PARAMETER;
656+
}
657+
return UNKNOWN_CRYPTO_ERROR; // default fallback
650658
}
651659

652660
@Override
@@ -657,10 +665,10 @@ public String decrypt(@NonNull final Cipher cipher,
657665

658666
@Override
659667
public byte[] decrypt(@NonNull Cipher cipher, byte[] ciphertext) throws ClientException {
660-
String errCode;
661-
Exception exception;
662668
final String methodTag = TAG + ":decrypt";
663-
try {
669+
final Span span = OTelUtility.createSpan(SpanName.DevicePopCryptoOperation.name());
670+
span.setAttribute(AttributeName.crypto_operation.name(), "decrypt");
671+
try (final Scope scope = SpanExtension.makeCurrentSpan(span)) {
664672
// Load our key material
665673
final KeyStore.PrivateKeyEntry privateKeyEntry = mKeyManager.getEntry();
666674

@@ -676,46 +684,22 @@ public byte[] decrypt(@NonNull Cipher cipher, byte[] ciphertext) throws ClientEx
676684
} else {
677685
outputCipher.init(javax.crypto.Cipher.DECRYPT_MODE, privateKey);
678686
}
679-
return outputCipher.doFinal(ciphertext);
680-
} catch (final NoSuchAlgorithmException e) {
681-
errCode = NO_SUCH_ALGORITHM;
682-
exception = e;
683-
} catch (final InvalidKeyException e) {
684-
errCode = INVALID_KEY;
685-
exception = e;
686-
} catch (final UnrecoverableEntryException e) {
687-
errCode = INVALID_PROTECTION_PARAMS;
688-
exception = e;
689-
} catch (final NoSuchPaddingException e) {
690-
errCode = NO_SUCH_ALGORITHM;
691-
exception = e;
692-
} catch (final KeyStoreException e) {
693-
errCode = KEYSTORE_NOT_INITIALIZED;
694-
exception = e;
695-
} catch (final BadPaddingException e) {
696-
errCode = BAD_PADDING;
697-
exception = e;
698-
} catch (final IllegalBlockSizeException e) {
699-
errCode = INVALID_BLOCK_SIZE;
700-
exception = e;
701-
} catch (final InvalidAlgorithmParameterException e) {
702-
errCode = INVALID_ALG_PARAMETER;
703-
exception = e;
704-
}
705-
706-
final ClientException clientException = new ClientException(
707-
errCode,
708-
exception.getMessage(),
709-
exception
710-
);
711-
712-
Logger.error(
713-
methodTag,
714-
errCode,
715-
exception
716-
);
687+
final byte[] result = outputCipher.doFinal(ciphertext);
688+
span.setStatus(StatusCode.OK);
689+
return result;
690+
} catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
691+
UnrecoverableEntryException | KeyStoreException | BadPaddingException |
692+
IllegalBlockSizeException | InvalidAlgorithmParameterException e) {
693+
final String errCode = mapCryptoExceptionToErrorCode(e);
694+
span.recordException(e);
695+
span.setStatus(StatusCode.ERROR);
717696

718-
throw clientException;
697+
final ClientException clientException = new ClientException(errCode, e.getMessage(), e);
698+
Logger.error(methodTag, errCode, e);
699+
throw clientException;
700+
} finally {
701+
span.end();
702+
}
719703
}
720704

721705
@Override

0 commit comments

Comments
 (0)