All Downloads are FREE. Search and download functionalities are using the official Maven repository.

okhttp3.tls.Certificates.kt Maven / Gradle / Ivy

/*
 * Copyright (C) 2020 Square, 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.
 */

@file:JvmName("Certificates")

package okhttp3.tls

import java.security.GeneralSecurityException
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
import okio.Buffer
import okio.ByteString
import okio.ByteString.Companion.toByteString

/**
 * Decodes a multiline string that contains a [certificate][certificatePem] which is
 * [PEM-encoded][rfc_7468]. A typical input string looks like this:
 *
 * ```
 * -----BEGIN CERTIFICATE-----
 * MIIBYTCCAQegAwIBAgIBKjAKBggqhkjOPQQDAjApMRQwEgYDVQQLEwtlbmdpbmVl
 * cmluZzERMA8GA1UEAxMIY2FzaC5hcHAwHhcNNzAwMTAxMDAwMDA1WhcNNzAwMTAx
 * MDAwMDEwWjApMRQwEgYDVQQLEwtlbmdpbmVlcmluZzERMA8GA1UEAxMIY2FzaC5h
 * cHAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASda8ChkQXxGELnrV/oBnIAx3dD
 * ocUOJfdz4pOJTP6dVQB9U3UBiW5uSX/MoOD0LL5zG3bVyL3Y6pDwKuYvfLNhoyAw
 * HjAcBgNVHREBAf8EEjAQhwQBAQEBgghjYXNoLmFwcDAKBggqhkjOPQQDAgNIADBF
 * AiAyHHg1N6YDDQiY920+cnI5XSZwEGhAtb9PYWO8bLmkcQIhAI2CfEZf3V/obmdT
 * yyaoEufLKVXhrTQhRfodTeigi4RX
 * -----END CERTIFICATE-----
 * ```
 */
fun String.decodeCertificatePem(): X509Certificate {
  try {
    val certificateFactory = CertificateFactory.getInstance("X.509")
    val certificates = certificateFactory
        .generateCertificates(
            Buffer().writeUtf8(this).inputStream())

    return certificates.single() as X509Certificate
  } catch (nsee: NoSuchElementException) {
    throw IllegalArgumentException("failed to decode certificate", nsee)
  } catch (iae: IllegalArgumentException) {
    throw IllegalArgumentException("failed to decode certificate", iae)
  } catch (e: GeneralSecurityException) {
    throw IllegalArgumentException("failed to decode certificate", e)
  }
}

/**
 * Returns the certificate encoded in [PEM format][rfc_7468].
 *
 * [rfc_7468]: https://tools.ietf.org/html/rfc7468
 */
fun X509Certificate.certificatePem(): String {
  return buildString {
    append("-----BEGIN CERTIFICATE-----\n")
    encodeBase64Lines(encoded.toByteString())
    append("-----END CERTIFICATE-----\n")
  }
}

internal fun StringBuilder.encodeBase64Lines(data: ByteString) {
  val base64 = data.base64()
  for (i in 0 until base64.length step 64) {
    append(base64, i, minOf(i + 64, base64.length)).append('\n')
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy