001/* 002 * (C) Copyright 2011-2012 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Wojciech Sulejman 016 * Florent Guillaume 017 */ 018package org.nuxeo.ecm.platform.signature.api.sign; 019 020import java.security.cert.X509Certificate; 021import java.util.List; 022 023import org.nuxeo.ecm.core.api.Blob; 024import org.nuxeo.ecm.core.api.DocumentModel; 025import org.nuxeo.ecm.core.api.blobholder.BlobHolder; 026import org.nuxeo.ecm.core.convert.api.ConversionException; 027import org.nuxeo.ecm.platform.signature.api.exception.SignException; 028 029/** 030 * Provides digital signature services that can be performed on PDF documents, e.g.: 031 * <ul> 032 * <li>signing a specific PDF,</li> 033 * <li>obtaining a list of certificates already associated with a document.</li> 034 * </ul> 035 * A PDF document can be signed using a user certificate. This requires an existing user certificate present in the 036 * system. A certificate password must be made available to use this service. 037 */ 038public interface SignatureService { 039 040 /** 041 * Information about a blob and its signing status. 042 */ 043 public class StatusWithBlob { 044 045 /** 046 * The signing status for a document that is not signable (no attachment or unsupported attachment type). 047 */ 048 public static final int UNSIGNABLE = -1; 049 050 /** 051 * The signing status for a document that is not signed. 052 */ 053 public static final int UNSIGNED = 0; 054 055 /** 056 * The signing status for a document that is signed by the current user (and maybe others). 057 */ 058 public static final int SIGNED_CURRENT = 1; 059 060 /** 061 * The signing status for a document that is signed by users other than the current user. 062 */ 063 public static final int SIGNED_OTHER = 2; 064 065 /** 066 * A document's status may be: 067 * <ul> 068 * <li>unsignable ({@link #UNSIGNABLE}),</li> 069 * <li>unsigned ({@link #UNSIGNED}),</li> 070 * <li>signed by the current user (and maybe also others) ( {@link #SIGNED_CURRENT}),</li> 071 * <li>signed only by others ({@link #SIGNED_OTHER}).</li> 072 * </ul> 073 */ 074 public final int status; 075 076 public final Blob blob; 077 078 public final BlobHolder blobHolder; 079 080 public final String path; 081 082 public StatusWithBlob(int status, Blob blob, BlobHolder blobHolder, String path) { 083 this.status = status; 084 this.blob = blob; 085 this.blobHolder = blobHolder; 086 this.path = path; 087 } 088 089 public int getStatus() { 090 return status; 091 } 092 093 public Blob getBlob() { 094 return blob; 095 } 096 097 public String getPath() { 098 return path; 099 } 100 101 @Override 102 public String toString() { 103 return getClass().getSimpleName() + "(status=" + status + ",path=" + path + ",blob=" + blob + ")"; 104 } 105 } 106 107 /** 108 * Finds the signing status for the document. 109 * <p> 110 * A signature user is determined according to its email. 111 * 112 * @param doc the document 113 * @return the signing status 114 */ 115 StatusWithBlob getSigningStatus(DocumentModel doc, DocumentModel currentUser); 116 117 enum SigningDisposition { 118 /** Replace the main blob with the signed one. */ 119 REPLACE, 120 /** Replace the main blob with the signed one and archive the original. */ 121 ARCHIVE, 122 /** Put the signed blob as an attachment. */ 123 ATTACH 124 } 125 126 /** 127 * Signs a document with a user certificate (converts it into a PDF first if needed). 128 * <p> 129 * Requires a password to retrieve the certificate from the user keystore. 130 * <p> 131 * Does not save the modified document. 132 * 133 * @param doc the document to sign 134 * @param user the signing user 135 * @param userKeyPassword the password for the user's signing certificate 136 * @param reason the signing reason 137 * @param pdfa {@code true} if the generated PDF should be a PDF/A-1b 138 * @param disposition the signing disposition 139 * @param archiveFilename the archive filename when using an archive 140 * @return a blob containing the signed PDF 141 * @throws SignException 142 * @throws ConversionException 143 */ 144 Blob signDocument(DocumentModel doc, DocumentModel user, String userKeyPassword, String reason, boolean pdfa, 145 SigningDisposition disposition, String archiveFilename); 146 147 /** 148 * Signs a PDF document with a user certificate. Requires a password to retrieve the certificate from the user 149 * keystore. 150 * 151 * @param pdfBlob the blob containing the PDF to sign 152 * @param user the signing user 153 * @param userKeyPassword the password for the user's signing certificate 154 * @param reason the signing reason 155 * @return a blob containing the signed PDF 156 * @throws SignException 157 */ 158 Blob signPDF(Blob pdfBlob, DocumentModel user, String userKeyPassword, String reason) throws SignException; 159 160 /** 161 * Returns a list of certificates associated with a given document. 162 * 163 * @param doc the document 164 * @return the list of certificates (may be empty) 165 */ 166 List<X509Certificate> getCertificates(DocumentModel doc); 167 168}