001/*
002 * (C) Copyright 2011-2012 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Wojciech Sulejman
018 *     Florent Guillaume
019 */
020package org.nuxeo.ecm.platform.signature.api.sign;
021
022import java.security.cert.X509Certificate;
023import java.util.List;
024
025import org.nuxeo.ecm.core.api.Blob;
026import org.nuxeo.ecm.core.api.DocumentModel;
027import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
028import org.nuxeo.ecm.core.convert.api.ConversionException;
029import org.nuxeo.ecm.platform.signature.api.exception.SignException;
030
031/**
032 * Provides digital signature services that can be performed on PDF documents, e.g.:
033 * <ul>
034 * <li>signing a specific PDF,</li>
035 * <li>obtaining a list of certificates already associated with a document.</li>
036 * </ul>
037 * A PDF document can be signed using a user certificate. This requires an existing user certificate present in the
038 * system. A certificate password must be made available to use this service.
039 */
040public interface SignatureService {
041
042    /**
043     * Information about a blob and its signing status.
044     */
045    class StatusWithBlob {
046
047        /**
048         * The signing status for a document that is not signable (no attachment or unsupported attachment type).
049         */
050        public static final int UNSIGNABLE = -1;
051
052        /**
053         * The signing status for a document that is not signed.
054         */
055        public static final int UNSIGNED = 0;
056
057        /**
058         * The signing status for a document that is signed by the current user (and maybe others).
059         */
060        public static final int SIGNED_CURRENT = 1;
061
062        /**
063         * The signing status for a document that is signed by users other than the current user.
064         */
065        public static final int SIGNED_OTHER = 2;
066
067        /**
068         * A document's status may be:
069         * <ul>
070         * <li>unsignable ({@link #UNSIGNABLE}),</li>
071         * <li>unsigned ({@link #UNSIGNED}),</li>
072         * <li>signed by the current user (and maybe also others) ( {@link #SIGNED_CURRENT}),</li>
073         * <li>signed only by others ({@link #SIGNED_OTHER}).</li>
074         * </ul>
075         */
076        public final int status;
077
078        public final Blob blob;
079
080        public final BlobHolder blobHolder;
081
082        public final String path;
083
084        public StatusWithBlob(int status, Blob blob, BlobHolder blobHolder, String path) {
085            this.status = status;
086            this.blob = blob;
087            this.blobHolder = blobHolder;
088            this.path = path;
089        }
090
091        public int getStatus() {
092            return status;
093        }
094
095        public Blob getBlob() {
096            return blob;
097        }
098
099        public String getPath() {
100            return path;
101        }
102
103        @Override
104        public String toString() {
105            return getClass().getSimpleName() + "(status=" + status + ",path=" + path + ",blob=" + blob + ")";
106        }
107    }
108
109    /**
110     * Finds the signing status for the document.
111     * <p>
112     * A signature user is determined according to its email.
113     *
114     * @param doc the document
115     * @return the signing status
116     */
117    StatusWithBlob getSigningStatus(DocumentModel doc, DocumentModel currentUser);
118
119    enum SigningDisposition {
120        /** Replace the main blob with the signed one. */
121        REPLACE,
122        /** Replace the main blob with the signed one and archive the original. */
123        ARCHIVE,
124        /** Put the signed blob as an attachment. */
125        ATTACH
126    }
127
128    /**
129     * Signs a document with a user certificate (converts it into a PDF first if needed).
130     * <p>
131     * Requires a password to retrieve the certificate from the user keystore.
132     * <p>
133     * Does not save the modified document.
134     *
135     * @param doc the document to sign
136     * @param user the signing user
137     * @param userKeyPassword the password for the user's signing certificate
138     * @param reason the signing reason
139     * @param pdfa {@code true} if the generated PDF should be a PDF/A-1b
140     * @param disposition the signing disposition
141     * @param archiveFilename the archive filename when using an archive
142     * @return a blob containing the signed PDF
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 doc Document model beign signed
152     * @param pdfBlob the blob containing the PDF to sign
153     * @param user the signing user
154     * @param userKeyPassword the password for the user's signing certificate
155     * @param reason the signing reason
156     * @return a blob containing the signed PDF
157     */
158    Blob signPDF(Blob pdfBlob, DocumentModel doc, 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    SignatureLayout getSignatureLayout();
169}