Decode an X509 certificate chain.

@param codec The codec to do the decoding of the Any.
@param encodedCertChain The codec encoded byte[] containing the X509 certificate chain.
@return the X509 certificate chain
@throws SASException
16853
@SuppressWarnings("unchecked")
    @Sensitive
    public static X509Certificate[] decodeCertChain(Codec codec, @Sensitive byte[] encodedCertChain) throws SASException {
        X509Certificate[] certificateChain = null;

        try {
            Any any = codec.decode_value(encodedCertChain, X509CertificateChainHelper.type());
            byte[] decodedCertificateChain = X509CertificateChainHelper.extract(any);

            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            ByteArrayInputStream bais = new ByteArrayInputStream(decodedCertificateChain);
            CertPath certPath = certificateFactory.generateCertPath(bais);
            List<X509Certificate> certificates = (List<X509Certificate>) certPath.getCertificates();

            certificateChain = new X509Certificate[certificates.size()];
            for (int i = 0; i < certificates.size(); i++) {
                certificateChain[i] = certificates.get(i);
            }
        } catch (Exception e) {
            throw new SASException(1, e);
        }
        return certificateChain;
    }
124801
public static byte[] getEncodedInternal(Certificate cert)
            throws CertificateEncodingException {
        if (cert instanceof X509CertImpl) {
            return ((X509CertImpl)cert).getEncodedInternal();
        } else {
            return cert.getEncoded();
        }
    }
564606
public static CodeDecryptResult codeDecrypt(String accessToken, CodeDecrypt codeDecrypt) {
		return codeDecrypt(accessToken, JsonUtil.toJSONString(codeDecrypt));
	}
1059965
public static String encode(final String decoded) {
        try {
            return s_codec.encode(decoded);
        } catch (EncoderException e) {
            throw new IllegalStateException(Bundle.getErrorString("URLCodec_encodeException", new String[] {e.getMessage()}), e);
        }
    }
1152119
private final byte[][] decode(byte[] encodedPrivateKey) {
        byte[][] decodedKey = new byte[8][];
        if (encodedPrivateKey.length > (PUBLIC_EXPONENT_LENGTH + PRIME_P_LENGTH + PRIME_Q_LENGTH)) {
            // it is potentially the new encoding mechanism based on R3.5 [with CRT key information added for Domino]
            // determine the length of the CRT key by looking at the first four bytes
            byte[] lengthBytes = new byte[PRIVATE_EXPONENT_LENGTH_FIELD_LENGTH];
            for (int i = 0; i < PRIVATE_EXPONENT_LENGTH_FIELD_LENGTH; i++) {
                lengthBytes[i] = encodedPrivateKey[i];
            }
            privateExponentLength = toInt(lengthBytes);
            decodedKey[PRIVATE_EXPONENT] = new byte[privateExponentLength];
            decodedKey[PUBLIC_EXPONENT] = new byte[PUBLIC_EXPONENT_LENGTH];
            decodedKey[PRIME_P] = new byte[PRIME_P_LENGTH];
            decodedKey[PRIME_Q] = new byte[PRIME_Q_LENGTH];

            System.arraycopy(encodedPrivateKey, PRIVATE_EXPONENT_LENGTH_FIELD_LENGTH, decodedKey[PRIVATE_EXPONENT], 0, privateExponentLength);
            System.arraycopy(encodedPrivateKey, PRIVATE_EXPONENT_LENGTH_FIELD_LENGTH + privateExponentLength, decodedKey[PUBLIC_EXPONENT], 0, PUBLIC_EXPONENT_LENGTH);
            System.arraycopy(encodedPrivateKey, PRIVATE_EXPONENT_LENGTH_FIELD_LENGTH + privateExponentLength + PUBLIC_EXPONENT_LENGTH, decodedKey[PRIME_P], 0, PRIME_P_LENGTH);
            System.arraycopy(encodedPrivateKey, PRIVATE_EXPONENT_LENGTH_FIELD_LENGTH + privateExponentLength + PUBLIC_EXPONENT_LENGTH + PRIME_P_LENGTH, decodedKey[PRIME_Q], 0,
                             PRIME_Q_LENGTH);
        } else {
            // it is a R3.02 key [without CRT key information] 
            decodedKey[PUBLIC_EXPONENT] = new byte[PUBLIC_EXPONENT_LENGTH];
            decodedKey[PRIME_P] = new byte[PRIME_P_LENGTH];
            decodedKey[PRIME_Q] = new byte[PRIME_Q_LENGTH];

            System.arraycopy(encodedPrivateKey, 0, decodedKey[PUBLIC_EXPONENT], 0, PUBLIC_EXPONENT_LENGTH);
            System.arraycopy(encodedPrivateKey, PUBLIC_EXPONENT_LENGTH, decodedKey[PRIME_P], 0, PRIME_P_LENGTH);
            System.arraycopy(encodedPrivateKey, PUBLIC_EXPONENT_LENGTH + PRIME_P_LENGTH, decodedKey[PRIME_Q], 0, PRIME_Q_LENGTH);
        }
        return decodedKey;
    }
1206044
@Override
    public IdentityToken encodeIdentityToken(Codec codec) {
        IdentityToken token = null;

        SubjectManager subjectManager = new SubjectManager();
        Subject subject = subjectManager.getInvocationSubject();
        if (subject == null) {
            subject = subjectManager.getCallerSubject();
        }

        /*
         * At this point, we have either the invocation subject or the caller subject. Now we need to extract the
         * credentials from this subject. We will use the SubjectHelper utility class to acheive the same.
         */
        SubjectHelper subjectHelper = new SubjectHelper();
        WSCredential wsCredential = subjectHelper.getWSCredential(subject);
        /*
         * in wsCredential object, the certificate is stored against the property name "wssecurity.identity_value".
         * We need to get the value corresponding to this property name.
         */
        try {
            /*
             * Now, from the WSCredential, make sure that the identity token type is certificate chain. To do this,
             * get the value of the property called "wssecurity.identity_name"
             */
            String identityTypeValue = (String) wsCredential.get(Constants.IDENTITY_NAME);
            /*
             * The identityTypeValue must be “ClientCertificate”. There is no point in continuing the process
             * if the value is not “ClientCertificate”
             */
            boolean isITTCert = Constants.ClientCertificate.equalsIgnoreCase(identityTypeValue);
            /* Get the certificate chain from WSCredential */
            X509Certificate[] certificateChain = (X509Certificate[]) wsCredential.get(Constants.IDENTITY_VALUE);

            if (isITTCert && (certificateChain != null)) {
                token = new IdentityToken();
                byte[] encodedCertificateChain = Util.encodeCertChain(codec, certificateChain);
                token.certificate_chain(encodedCertificateChain);
            } else {
                /*
                 * This else means, either the token type is not set to certificate, or the certificate does not exist.
                 * In either case, we need to throw an exception. This exception will be captured in the catch
                 * block, along with other possible exceptions like CredentialExpiredException and
                 * CredentialDestroyedException.
                 */
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                    Tr.debug(tc, "Certificate is not available to continue with Identity Assertion. identityTypeValue=" + identityTypeValue);
                }
                String messageFromBundle = Tr.formatMessage(tc, "CSIv2_CLIENT_ASSERTION_CERTIFICATE_INVALID");
                throw new Exception(messageFromBundle);
            }
        } catch (Exception e) {
            /*
             * We consolidate all possible exceptions here. We log the message and then throw them as a single
             * NO_PERMISSION exception
             */
            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                Tr.debug(tc, "The client cannot create the ITTX509CertChain identity assertion token. The exception message is: " + e.getMessage());
            }
            String messageFromBundle = Tr.formatMessage(tc, "CSIv2_CLIENT_ASSERTION_CANNOT_ENCODE_CC", e.getMessage());
            throw new org.omg.CORBA.NO_PERMISSION(messageFromBundle, SecurityMinorCodes.CREDENTIAL_NOT_AVAILABLE, org.omg.CORBA.CompletionStatus.COMPLETED_NO);

        }
        return token;
    }
1322666
static X509Certificate selfSignedCertificate() throws CertificateException {
        return (X509Certificate) SslContext.X509_CERT_FACTORY.generateCertificate(
                new ByteArrayInputStream(CERT.getBytes(CharsetUtil.US_ASCII))
        );
    }
33911
protected void validateCertificate(X509Certificate[] chain) throws com.ibm.wsspi.security.wim.exception.CertificateMapFailedException {
        // validate the certificate array
        if (chain == null || chain.length == 0) {
            throw new com.ibm.wsspi.security.wim.exception.CertificateMapFailedException();
        }

        for (X509Certificate cert : chain) {
            if (cert == null) {
                throw new com.ibm.wsspi.security.wim.exception.CertificateMapFailedException();
            }
        }
    }
342502
public final HttpClient cookieCodec(ClientCookieEncoder encoder, ClientCookieDecoder decoder) {
		return tcpConfiguration(tcp -> tcp.bootstrap(
				b -> HttpClientConfiguration.cookieCodec(b, encoder, decoder)));
	}
1122299
@Override
  public X509Certificate getClientCertificate()
    throws CertificateException
  {
    X509Certificate []certs = getClientCertificates();

    if (certs == null || certs.length == 0)
      return null;
    else
      return certs[0];
  }
200800
static byte[] getCodecNameUTF8(String compressionCodecName) {
    byte[] codecNameBytes = CODEC_NAME_CACHE.get(compressionCodecName);
    if (codecNameBytes == null) {
      try {
        codecNameBytes = compressionCodecName.getBytes("UTF-8");
      } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
      }
      CODEC_NAME_CACHE.put(compressionCodecName, codecNameBytes);
    }
    return codecNameBytes;
  }
1250106
public static byte decodeByteDesc(byte[] src, int srcOffset)
        throws CorruptEncodingException
    {
        try {
            return (byte)(src[srcOffset] ^ 0x7f);
        } catch (IndexOutOfBoundsException e) {
            throw new CorruptEncodingException(null, e);
        }
    }
399509
function DBCSCodec(codecOptions, iconv) {
    this.encodingName = codecOptions.encodingName;
    if (!codecOptions)
        throw new Error("DBCS codec is called without the data.")
    if (!codecOptions.table)
        throw new Error("Encoding '" + this.encodingName + "' has no data.");

    // Load tables.
    var mappingTable = codecOptions.table();


    // Decode tables: MBCS -> Unicode.

    // decodeTables is a trie, encoded as an array of arrays of integers. Internal arrays are trie nodes and all have len = 256.
    // Trie root is decodeTables[0].
    // Values: >=  0 -> unicode character code. can be > 0xFFFF
    //         == UNASSIGNED -> unknown/unassigned sequence.
    //         == GB18030_CODE -> this is the end of a GB18030 4-byte sequence.
    //         <= NODE_START -> index of the next node in our trie to process next byte.
    //         <= SEQ_START  -> index of the start of a character code sequence, in decodeTableSeq.
    this.decodeTables = [];
    this.decodeTables[0] = UNASSIGNED_NODE.slice(0); // Create root node.

    // Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here. 
    this.decodeTableSeq = [];

    // Actual mapping tables consist of chunks. Use them to fill up decode tables.
    for (var i = 0; i < mappingTable.length; i++)
        this._addDecodeChunk(mappingTable[i]);

    this.defaultCharUnicode = iconv.defaultCharUnicode;

    
    // Encode tables: Unicode -> DBCS.

    // `encodeTable` is array mapping from unicode char to encoded char. All its values are integers for performance.
    // Because it can be sparse, it is represented as array of buckets by 256 chars each. Bucket can be null.
    // Values: >=  0 -> it is a normal char. Write the value (if <=256 then 1 byte, if <=65536 then 2 bytes, etc.).
    //         == UNASSIGNED -> no conversion found. Output a default char.
    //         <= SEQ_START  -> it's an index in encodeTableSeq, see below. The character starts a sequence.
    this.encodeTable = [];
    
    // `encodeTableSeq` is used when a sequence of unicode characters is encoded as a single code. We use a tree of
    // objects where keys correspond to characters in sequence and leafs are the encoded dbcs values. A special DEF_CHAR key
    // means end of sequence (needed when one sequence is a strict subsequence of another).
    // Objects are kept separately from encodeTable to increase performance.
    this.encodeTableSeq = [];

    // Some chars can be decoded, but need not be encoded.
    var skipEncodeChars = {};
    if (codecOptions.encodeSkipVals)
        for (var i = 0; i < codecOptions.encodeSkipVals.length; i++) {
            var val = codecOptions.encodeSkipVals[i];
            if (typeof val === 'number')
                skipEncodeChars[val] = true;
            else
                for (var j = val.from; j <= val.to; j++)
                    skipEncodeChars[j] = true;
        }
        
    // Use decode trie to recursively fill out encode tables.
    this._fillEncodeTable(0, 0, skipEncodeChars);

    // Add more encoding pairs when needed.
    if (codecOptions.encodeAdd) {
        for (var uChar in codecOptions.encodeAdd)
            if (Object.prototype.hasOwnProperty.call(codecOptions.encodeAdd, uChar))
                this._setEncodeChar(uChar.charCodeAt(0), codecOptions.encodeAdd[uChar]);
    }

    this.defCharSB  = this.encodeTable[0][iconv.defaultCharSingleByte.charCodeAt(0)];
    if (this.defCharSB === UNASSIGNED) this.defCharSB = this.encodeTable[0]['?'];
    if (this.defCharSB === UNASSIGNED) this.defCharSB = "?".charCodeAt(0);


    // Load & create GB18030 tables when needed.
    if (typeof codecOptions.gb18030 === 'function') {
        this.gb18030 = codecOptions.gb18030(); // Load GB18030 ranges.

        // Add GB18030 decode tables.
        var thirdByteNodeIdx = this.decodeTables.length;
        var thirdByteNode = this.decodeTables[thirdByteNodeIdx] = UNASSIGNED_NODE.slice(0);

        var fourthByteNodeIdx = this.decodeTables.length;
        var fourthByteNode = this.decodeTables[fourthByteNodeIdx] = UNASSIGNED_NODE.slice(0);

        for (var i = 0x81; i <= 0xFE; i++) {
            var secondByteNodeIdx = NODE_START - this.decodeTables[0][i];
            var secondByteNode = this.decodeTables[secondByteNodeIdx];
            for (var j = 0x30; j <= 0x39; j++)
                secondByteNode[j] = NODE_START - thirdByteNodeIdx;
        }
        for (var i = 0x81; i <= 0xFE; i++)
            thirdByteNode[i] = NODE_START - fourthByteNodeIdx;
        for (var i = 0x30; i <= 0x39; i++)
            fourthByteNode[i] = GB18030_CODE
    }        
}
1021248
function InternalCodec(codecOptions, iconv) {
    this.enc = codecOptions.encodingName;
    this.bomAware = codecOptions.bomAware;

    if (this.enc === "base64")
        this.encoder = InternalEncoderBase64;
    else if (this.enc === "cesu8") {
        this.enc = "utf8"; // Use utf8 for decoding.
        this.encoder = InternalEncoderCesu8;

        // Add decoder for versions of Node not supporting CESU-8
        if (Buffer.from('eda0bdedb2a9', 'hex').toString() !== '💩') {
            this.decoder = InternalDecoderCesu8;
            this.defaultCharUnicode = iconv.defaultCharUnicode;
        }
    }
}
793555
protected B codec(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder) {
        enforceConstraint("codec", "server", isServer);
        enforceConstraint("codec", "maxReservedStreams", maxReservedStreams);
        enforceConstraint("codec", "connection", connection);
        enforceConstraint("codec", "frameLogger", frameLogger);
        enforceConstraint("codec", "validateHeaders", validateHeaders);
        enforceConstraint("codec", "headerSensitivityDetector", headerSensitivityDetector);
        enforceConstraint("codec", "encoderEnforceMaxConcurrentStreams", encoderEnforceMaxConcurrentStreams);

        checkNotNull(decoder, "decoder");
        checkNotNull(encoder, "encoder");

        if (decoder.connection() != encoder.connection()) {
            throw new IllegalArgumentException("The specified encoder and decoder have different connections.");
        }

        this.decoder = decoder;
        this.encoder = encoder;

        return self();
    }
309642
public static boolean decodeGSSUPToken(Codec codec, @Sensitive byte[] token_arr,
                                           InitialContextToken gssup_tok) {
        boolean result = false;
        if (gssup_tok != null) {
            try {
                byte[] data = readGSSTokenData(GSSUPMechOID.value.substring(4), token_arr);
                if (data != null) {
                    Any a = codec.decode_value(data, InitialContextTokenHelper.type());
                    InitialContextToken token = InitialContextTokenHelper.extract(a);
                    if (token != null) {
                        gssup_tok.username = token.username;
                        gssup_tok.password = token.password;
                        gssup_tok.target_name = decodeGSSExportedName(token.target_name).getName().getBytes("UTF-8");

                        result = true;
                    }
                }
            } catch (Exception ex) {
                // do nothing, return false
            }
        }
        return result;
    }
1049970
public void derEncode(OutputStream out) throws IOException {
        if (signedCert == null)
            throw new IOException("Null certificate to encode");
        out.write(signedCert.clone());
    }