package com.sunyard.chsm.utils;

import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.ByteArrayInputStream;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import static com.sunyard.chsm.utils.SydCmsUtil.readContentInfo;


/**
 * @author zyh
 * @since 2024/12/19
 */
public class CertUtil {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static X509Certificate convertToX509Cert(String certificateString)  {
        String pemCert;
        if(certificateString.contains("-----BEGIN CERTIFICATE-----")){
            pemCert =certificateString;
        }else {
            String cert_begin = "-----BEGIN CERTIFICATE-----\n";
            String end_cert = "\n-----END CERTIFICATE-----";
            pemCert = cert_begin + certificateString + end_cert;
        }
        try {
            CertificateFactory CF = CertificateFactory.getInstance("X.509", "BC"); // 从证书工厂中获取X.509的单例类
            return (X509Certificate) CF.generateCertificate(new ByteArrayInputStream(pemCert.getBytes()));  // 将文件流的证书转化为证书类
        } catch (CertificateException | NoSuchProviderException e) {
            throw new RuntimeException(e);
        }
    }



    public static String getSn(String cert) {
        try {

            if(cert.contains("-----BEGIN CERTIFICATE-----")){
                String[] lines = cert.split("\n");
                // 构建新的证书字符串，去掉第一行和最后一行
                StringBuilder cleanedCertificate = new StringBuilder();
                for (int i = 1; i < lines.length - 1; i++) {
                    cleanedCertificate.append(lines[i]);
                }
                cert = cleanedCertificate.toString();
            }
            //从证书中获取sn
            Object pkContent = readContentInfo(CodecUtils.decodeBase64(cert));

            //逐级从结构体中获取需要的sn
            ASN1Sequence pkSeq = ASN1Sequence.getInstance(pkContent);
            ASN1Sequence pkSeq0 = (ASN1Sequence) pkSeq.getObjectAt(0).toASN1Primitive();
            ASN1Integer sn = (ASN1Integer) pkSeq0.getObjectAt(1).toASN1Primitive();
            String serNum = CodecUtils.encodeHex(sn.getEncoded());

            //去掉长度
            return serNum.substring(4);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
