ASN1Decoder icon indicating copy to clipboard operation
ASN1Decoder copied to clipboard

Can the rawValue from ASN1Object be used as a certificate Data?

Open alam156 opened this issue 2 years ago • 10 comments

I have modified this library to extract certificate chain from p7b string. I am able to get x509Certificate information using the method x509Certificate(). What i need to do is parse only this Certificate's Data. I tried this with rawValue but in vain. How can i extract only certificate data. In my p7b string, there is 2 certificate. I only need 1st certificate.

alam156 avatar Jun 02 '23 06:06 alam156

`var pkcs7 = try PKCS7(data: data!) let cert = pkcs7.certificate

public init(data: Data) throws { let asn1 = try ASN1DERDecoder.decode(data: data)

    guard let firstBlock = asn1.first,
        let mainBlock = firstBlock.sub(1)?.sub(0) else {
        throw PKCS7Error.parseError
    }

    self.mainBlock = mainBlock

    guard firstBlock.sub(0)?.value as? String == OID.pkcs7signedData.rawValue else {
        throw PKCS7Error.notSupported
    }
}

public var certificate: X509Certificate? { return mainBlock.sub(1)?.sub(1)?.sub?.first.map { try? X509Certificate(asn1: $0) } ?? nil } `

I tried to get mainBlock.sub(1)?.sub(1)?.sub?.first.rawValue and use it as certificateData. But it doesn't work. Note: The X509Certificate information perfectly extracted using this. I need only the Certificate Data

alam156 avatar Jun 02 '23 07:06 alam156

P7B have a slightly different encoding, here a sample code to read all the certificates without modifications:

// P7B should be encoded as PEM, so it need to get converted as currently PKCS7 parse only DER data
guard var pemString = String(data: pemData, encoding: .utf8) else { return }
pemString = pemString.replacingOccurrences(of: "-----BEGIN PKCS7-----", with: "")
pemString = pemString.replacingOccurrences(of: "-----END PKCS7-----", with: "")
guard let derData = Data(base64Encoded: pemString, options: .ignoreUnknownCharacters) else { return }

var certificates: [X509Certificate] = []

let pkcs7 = try PKCS7(data: derData)
let certificateCount = pkcs7.mainBlock.sub(1)?.sub(1)?.subCount() ?? 0

for i in 0..<certificateCount {
    if let value = pkcs7.mainBlock.sub(1)?.sub(1)?.sub(i)?.rawValue, 
      let certificate = try? X509Certificate(data: value) {
        certificates.append(certificate)
    }
}

certificates contains the results

filom avatar Jun 02 '23 11:06 filom

@alam156 I'm trying to get and use certificateData. But it doesn't work. Please share your solution. mainBlock.sub(3)?.sub?.first?.rawValue doestn work X509Certificate object doesnt has "data" variable

RuslanMirosh avatar Feb 07 '24 17:02 RuslanMirosh

@filom I need to create SecCertificate from X509Certificate

RuslanMirosh avatar Feb 07 '24 17:02 RuslanMirosh

The rawValue needs a prefix, add derEncodedSequence, then you can create a SecCertificate:

let cer = pkcs7.mainBlock.sub(3)?.sub?.first?.rawValue?.derEncodedSequence
let secCer = SecCertificateCreateWithData(nil, cer as NSData)

filom avatar Feb 07 '24 20:02 filom

@filom thank you very much, can I convert X509Certificate to PEM data and create SecCertificate from X509Certificate, without pkcs7?

RuslanMirosh avatar Feb 10 '24 15:02 RuslanMirosh

To create a SecCertificate you need a certificate in DER format not a PEM.

filom avatar Feb 10 '24 20:02 filom

I have it. I need convert X509Cetrificate to SecSertificate

RuslanMirosh avatar Feb 10 '24 20:02 RuslanMirosh

Need get data from x509Certificate object

RuslanMirosh avatar Feb 10 '24 20:02 RuslanMirosh

If you have a X509Cetrificate object, you must have created it with DER or PEM data, so if you have either one of them you don't have to pass through a X509Cetrificate parser object to recompose it back to a DER object. If you have a PEM data, then it's simple to convert it to DER and finally create a SecCertificate.

filom avatar Feb 10 '24 21:02 filom