+(declare-function ldap-search "ldap"
+ (filter &optional host attributes attrsonly withdn))
+
+(defun smime-cert-by-ldap-1 (mail host)
+ "Get certificate for MAIL from the ldap server at HOST."
+ (let ((ldapresult
+ (funcall
+ (if (featurep 'xemacs)
+ (progn
+ (require 'smime-ldap)
+ 'smime-ldap-search)
+ (progn
+ (require 'ldap)
+ 'ldap-search))
+ (concat "mail=" mail)
+ host '("userCertificate") nil))
+ (retbuf (generate-new-buffer (format "*certificate for %s*" mail)))
+ cert)
+ (if (and (>= (length ldapresult) 1)
+ (> (length (cadaar ldapresult)) 0))
+ (with-current-buffer retbuf
+ ;; Certificates on LDAP servers _should_ be in DER format,
+ ;; but there are some servers out there that distributes the
+ ;; certificates in PEM format (with or without
+ ;; header/footer) so we try to handle them anyway.
+ (if (or (string= (substring (cadaar ldapresult) 0 27)
+ "-----BEGIN CERTIFICATE-----")
+ (string= (substring (cadaar ldapresult) 0 3)
+ "MII"))
+ (setq cert
+ (smime-replace-in-string
+ (cadaar ldapresult)
+ (concat "\\(\n\\|\r\\|-----BEGIN CERTIFICATE-----\\|"
+ "-----END CERTIFICATE-----\\)")
+ "" t))
+ (setq cert (base64-encode-string (cadaar ldapresult) t)))
+ (insert "-----BEGIN CERTIFICATE-----\n")
+ (let ((i 0) (len (length cert)))
+ (while (> (- len 64) i)
+ (insert (substring cert i (+ i 64)) "\n")
+ (setq i (+ i 64)))
+ (insert (substring cert i len) "\n"))
+ (insert "-----END CERTIFICATE-----\n"))
+ (kill-buffer retbuf)
+ (setq retbuf nil))
+ retbuf))
+
+(defun smime-cert-by-ldap (mail)
+ "Find certificate via LDAP for address MAIL."
+ (if smime-ldap-host-list
+ (catch 'certbuf
+ (dolist (host smime-ldap-host-list)
+ (let ((retbuf (smime-cert-by-ldap-1 mail host)))
+ (when retbuf
+ (throw 'certbuf retbuf)))))))
+