首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法从公共Lisp中的p12文件中提取信息

无法从公共Lisp中的p12文件中提取信息
EN

Stack Overflow用户
提问于 2017-04-10 14:11:25
回答 1查看 662关注 0票数 8

我试图从用PKCS#12加密的通用Lisp中的客户端证书中提取信息。

我尝试了以下步骤:

  1. 使用p12将给定的d2i_PKCS12_bio文件加载到BIO
  2. 使用PKCS12_verify_mac验证密码
  3. PKCS12_parse解析文件

以下是实际的CFFI代码:

代码语言:javascript
复制
(defun load-pkcs12 (file &optional passphrase)
  (openssl-add-all-digests)
  (pkcs12-pbe-add)
  ;; 1. Load the given p12 file
  (let ((content (slurp-file file)))
    (cffi:with-pointer-to-vector-data (data-sap content)
      (let* ((bio (bio-new-mem-buf data-sap (length content)))
             (p12 (d2i-pkcs12-bio bio (cffi:null-pointer)))
             (pkey (evp-pkey-new))
             (cert (x509-new)))
        (unwind-protect
             (progn
               ;; 2. Verify the passphrase
               (let ((res (pkcs12-verify-mac p12 (or passphrase (cffi:null-pointer)) (length passphrase))))
                 (when (zerop res)
                   (error (format nil "Error while verifying mac~%~A" (get-errors)))))

               ;; 3. Parse the file
               (cffi:with-foreign-objects ((*pkey :pointer)
                                           (*cert :pointer))
                 (setf (cffi:mem-ref *pkey :pointer) pkey
                       (cffi:mem-ref *cert :pointer) cert)
                 (let ((res
                         (pkcs12-parse p12
                                       (or passphrase (cffi:null-pointer))
                                       *pkey
                                       *cert
                                       (cffi:null-pointer))))
                   (when (zerop res)
                     (error "Error in pkcs12-parse~%~A" (get-errors)))))
               (pkcs12-free p12)

               ;; 4. Show the result
               (let ((bio (cl+ssl::bio-new (bio-s-mem))))
                 (unwind-protect
                      (progn
                        (x509-print-ex bio cert 0 0)
                        (bio-to-string bio))
                   (bio-free bio))))
          (evp-pkey-free pkey)
          (x509-free cert))))))

然而,X509_print_ex的结果总是毫无意义的:

代码语言:javascript
复制
Certificate:
Data:
    Version: 1 (0x0)
    Serial Number: 0 (0x0)
    Signature Algorithm: itu-t
    Issuer: 
    Validity
        Not Before: Bad time value

当我使用openssl命令尝试它时,它看起来很好,所以我假设p12文件是可以的:

代码语言:javascript
复制
$ openssl pkcs12 -in sslcert.p12 -clcerts -nokeys
Enter Import Password: <input passphrase>
MAC verified OK
Bag Attributes
    localKeyID: 31 0E 0D 31 05 8D 20 13 BA B3 81 85 57 AD 28 52 9F D0 19 BE
subject=/C=JP/ST=Tokyo/L=Minato/O=<company>/OU=Development/CN=<user>/emailAddress=admin@example.co.jp
issuer=/C=JP/ST=Tokyo/O=<company>/OU=Development/CN=SuperUser Intermediate CA/emailAddress=admin@example.co.jp
-----BEGIN CERTIFICATE-----
...PEM-encoded certificate...
-----END CERTIFICATE-----

mime的完整片段是论主旨。主要功能是load-pkcs12,位于文件的底部。

代码语言:javascript
复制
(load-pkcs12 #P"/path/to/sslcert.p12" "password")

这里有人能帮忙吗?

我指的是

EN

回答 1

Stack Overflow用户

发布于 2022-11-05 03:51:23

我认为该代码的问题是将pkeycert分配为空对象,分别使用evp-pkey-newx509-new

下面的代码实现了类似的功能;请注意cffi:foreign-alloccffi:mem-ref的使用。

代码语言:javascript
复制
(define-condition ssl-pkcs12-error (error)
  ((texto :initarg :texto :initform nil :reader ssl-pkcs12-error-texto)))

(defun ssl-pkcs12-descifra (archivo contra salida)
  (let ((fp (cffi:foreign-funcall "fopen" :string archivo :string "rb" :pointer)))
    (when (cffi:null-pointer-p fp)
      (error 'ssl-pkcs12-error :texto (format nil "No pudo abrise el archivo: ~s" archivo)))
    (let ((p12 (d2i-pkcs12-fp fp (cffi:null-pointer))))
      (cffi:foreign-funcall "fclose" :pointer fp :int)
      (when (cffi:null-pointer-p p12)
        (error 'ssl-pkcs12-error :texto "Error leyendo el archivo PKCS#12"))
      (let* ((pkey (cffi:foreign-alloc :pointer))
             (cert (cffi:foreign-alloc :pointer))
             (res (pkcs12-parse p12 contra pkey cert (cffi:null-pointer))))
        (pkcs12-free p12)
        (when (zerop res)
          (error 'ssl-pkcs12-error :texto "Error interpretando el archivo PKCS#12"))
        (let ((fp (cffi:foreign-funcall "fopen" :string salida :string "w" :pointer)))
          (when (cffi:null-pointer-p fp)
            (error 'ssl-pkcs12-error
                   :texto (format nil "No pudo crearse el archivo: ~s" salida)))
          (unless (cffi:null-pointer-p (cffi:mem-ref pkey :pointer))
            (pem-write-privatekey fp (cffi:mem-ref pkey :pointer)
                                  (cffi:null-pointer) (cffi:null-pointer)
                                  0 (cffi:null-pointer) (cffi:null-pointer))
            (evp-pkey-free (cffi:mem-ref pkey :pointer)))
          (unless (null-pointer-p (cffi:mem-ref cert :pointer))
            (pem-write-x509 fp (cffi:mem-ref cert :pointer))
            (x509-free (cffi:mem-ref cert :pointer)))
          (cffi:foreign-free pkey)
          (cffi:foreign-free cert)
          (cffi:foreign-funcall "fclose" :pointer fp :int))))))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43325515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档