PKCS11SignApplet
for
replacement.SimpleSignApplet
is simple in the sense that refined
GUI features are avoided (like multiple threads used to correctly implement
the progress bar), in favor to a clear exposition of specific signature
procedures.
The goal was to illustrate an approach in which the client side encryption, involving cryptographic token management via JNI, is completely separated from server side CMS message building. This lightens the applet, which has not to bear the weight of the BouncyCastle classes.
Note that in actual implementation of SimpleSignApplet
digesting is done on the server, and encapsulated in a digestInfo. Only digestInfo
is sent to the applet.
Another feature is the encapsulation of the JNI part (the excellent pkcs11
wrapper developed by IAIK of Graz University of Technology, and the pcsc
wrapper taken from Open Card Framework project), along with the corresponding
native libraries, in a standard Java Extension, named
SmartCardAccess
. See it.trento.comune.j4sign.installer
and Deploying Java Extensions.
The extension is deployed automatically the first time the applet is loaded.
The ultimate dependency for the applet is the cryptoki library, which has to
be provided from the PKCS11 token manufacturer. The
PCSCHelper
class uses the pcsc wrapper
trying to infer the correct library from the ATR string returned from the
token.
Some words about security; all downloaded jars, including the
SmartCardAccess
extension, has to be signed in order to work;
this is needed for tho reasons:
The entire example, with the
CMSServlet
server side counterpart,
is designed to permit the use of the standard JDK tools. The applet can be
executed with applet viewer tool (no HttpSession in the servlet, nor HTML
forms on the client side are used).
This eases the use of an IDE for test and debugging; we use, and recommend,
the Eclipse) IDE.
N.B.: IN A REAL WORLD WEB APPLICATION SCENARIO, YOU CAN (AND SHOULD) TAKE ADVANTAGE OF THE FULL SERVLET API, AND HTTP/HTML FEATURES.
Here are the SimpleSignApplet
operations in detail; the applet
talks with the server (servlet) in HTTP:
retrieve
parameter with value DATA
;
the server returns the message to sign.retrieve
parameter with value
ENCODED_AUTHENTICATED_ATTRIBUTES
, and a retrieve
parameter
with the certificate as value; the server calculates (using also the certificate)
the Authenticated Attributes data, SHA-256 digests and encapsulates them in a digestInfo.N.B. note that in this example signature verification only ensures integrity; a complete verification to ensure non-repudiation requires checking the full certification path including the CA root certificate, and CRL verification on the CA side. (Good stuff for a next release ...)
public class SimpleSignApplet
extends javax.swing.JApplet
implements java.awt.event.ActionListener
CMSServlet
,
Serialized Formjavax.swing.JApplet.AccessibleJApplet
java.applet.Applet.AccessibleApplet
Modifier and Type | Field and Description |
---|---|
private java.lang.String |
attrPrintout
Deprecated.
|
private java.lang.String |
baseHttpUrl
Deprecated.
|
private byte[] |
certificate
Deprecated.
|
private java.lang.String |
cryptokiLib
Deprecated.
|
static int |
DATA_LOADED
Deprecated.
|
private javax.swing.JTextArea |
dataArea
Deprecated.
|
static java.lang.String |
DEFAULT_BASE_HTTP_URL
Deprecated.
|
private byte[] |
digestInfo
Deprecated.
|
private byte[] |
encryptedDigest
Deprecated.
|
static int |
ERROR
Deprecated.
|
private javax.swing.JButton |
loadButton
Deprecated.
|
private java.io.PrintStream |
log
Deprecated.
|
private short |
OBJECT_SEARCH_CRITERION
Deprecated.
|
static int |
POST_ERROR
Deprecated.
|
static int |
POST_OK_VERIFY_ERROR
Deprecated.
|
static int |
POST_OK_VERIFY_OK
Deprecated.
|
private javax.swing.JProgressBar |
progressBar
Deprecated.
|
private javax.swing.JPasswordField |
pwd
Deprecated.
|
static int |
RESET
Deprecated.
|
private static short |
SEARCH_BY_CERTIFICATE_KEY_USAGE
Deprecated.
|
private static short |
SEARCH_BY_PRIVATE_KEY
Deprecated.
|
static int |
SIGN_DONE
Deprecated.
|
private java.lang.String |
signerLabel
Deprecated.
|
private java.lang.String |
textToSign
Deprecated.
|
accessibleContext, rootPane, rootPaneCheckingEnabled
Constructor and Description |
---|
SimpleSignApplet()
Deprecated.
|
Modifier and Type | Method and Description |
---|---|
void |
actionPerformed(java.awt.event.ActionEvent e)
Deprecated.
The implementation of the callback method for ActionListener.
|
void |
destroy()
Deprecated.
Cleans up whatever resources are being held.
|
private boolean |
detectCardAndCriptoki()
Deprecated.
This triggers the PCSC wrapper stuff; a
PCSCHelper class is used
to detect reader and token presence, trying also to provide a candidate
PKCS#11 cryptoki for it; detection is bypassed if an applet parameter
forcing cryptoki selection is provided. |
private void |
displayDataToSign()
Deprecated.
Shows on the text area of the applet the message content and the current
authenticated attributes dump (that includes the timestamp that will be
signed).
|
private void |
findCertificate()
Deprecated.
|
(package private) java.lang.String |
formatAsHexString(byte[] bytes)
Deprecated.
|
java.lang.String |
getBaseHttpUrl()
Deprecated.
|
byte[] |
getCertificate()
Deprecated.
Gets the signer certificate.
|
private java.lang.String |
getCryptokiLib()
Deprecated.
Gets the native cryptoki library name; this is the library provided by
the token manufacturer that implements the PKCS#11 standard API.
|
byte[] |
getDigestInfo()
Deprecated.
Returns the digest of the bytes to sign.
|
byte[] |
getEncryptedDigest()
Deprecated.
The result of encryption of data obtained from
#getDigest() ;
Encryption is done on the token. |
private java.lang.String |
getSignerLabel()
Deprecated.
The textual identifier of the objects related to the signer on a PKCS#11
token; do not rely only on this to find objects; labels are manufacturer
dependent.
|
private java.lang.String |
httpGet(java.net.URL url)
Deprecated.
Generic implementation of a HTTP GET; used from the data retrieval
methods.
|
private java.lang.String |
httpPOST(java.net.URL url,
java.lang.String data)
Deprecated.
Generic implementation of a HTTP POST; used from the data sending and retrieval
methods.
|
void |
init()
Deprecated.
Initializes the applet; the applet accepts as optional parameters the
label of the signer on the token, and the url of the running servlet to
use for CMS operations.
|
private void |
initStatus(int min,
int max)
Deprecated.
Initializes the status bar, extabilishing the value range.
|
private boolean |
loadData()
Deprecated.
Triggers three different HTTP GET requests against the server:
The first for retrieving the textual content to sign (the message)
The second for retrieving the time-dependent bytes to sign (the
authenticated attributes)
The third for retrieving a textual rapresentetion of the bytes to
sign (the authenticated attributes printout)
The local digest value is updated according with the new bytes to sign.
|
private java.lang.String |
retrieveAuthenticatedAttributesPrintout()
Deprecated.
Implements the HTTP GET request that returns the textual representation
of the current "authenticated attributes".
|
private byte[] |
retrieveDigestInfo()
Deprecated.
Implements the HTTP GET request that returns the data to digest and
encrypt..
|
private java.lang.String |
retrieveTextToSign()
Deprecated.
Implements the HTTP GET request that returns the message to sign.
|
private int |
sendSignatureAndCertificate()
Deprecated.
Implements of the HTTP POST that sends the encrypted digest and the
signer certificate to the server.
|
void |
setBaseHttpUrl(java.lang.String baseHttpUrl)
Deprecated.
|
private void |
setCertificate(byte[] newCertificate)
Deprecated.
Inserire qui la descrizione del metodo.
|
private void |
setCryptokiLib(java.lang.String newCryptokiLib)
Deprecated.
Sets the native PKCS#11 implementation to use.
|
void |
setDigestInfo(byte[] newDigestInfo)
Deprecated.
Sets the digest.
|
void |
setEncryptedDigest(byte[] newEncryptedDigest)
Deprecated.
Sets the encrypted digest.
|
private void |
setSignerLabel(java.lang.String newSignerLabel)
Deprecated.
The label to use to retrieve signer - related objects on the token.
|
private void |
setStatus(int code,
java.lang.String statusString)
Deprecated.
Manages status messages displayed on the status bar.
|
void |
sign()
Deprecated.
Triggers the digest encryption on the token, using services provided by
PKCS11Signer class. |
void |
start()
Deprecated.
Called to start the applet.
|
void |
stop()
Deprecated.
Called to stop the applet.
|
addImpl, createRootPane, getAccessibleContext, getContentPane, getGlassPane, getGraphics, getJMenuBar, getLayeredPane, getRootPane, getTransferHandler, isRootPaneCheckingEnabled, paramString, remove, repaint, setContentPane, setGlassPane, setJMenuBar, setLayeredPane, setLayout, setRootPane, setRootPaneCheckingEnabled, setTransferHandler, update
getAppletContext, getAppletInfo, getAudioClip, getAudioClip, getCodeBase, getDocumentBase, getImage, getImage, getLocale, getParameter, getParameterInfo, isActive, isValidateRoot, newAudioClip, play, play, resize, resize, setStub, showStatus
add, add, add, add, add, addContainerListener, addPropertyChangeListener, addPropertyChangeListener, applyComponentOrientation, areFocusTraversalKeysSet, countComponents, deliverEvent, doLayout, findComponentAt, findComponentAt, getAlignmentX, getAlignmentY, getComponent, getComponentAt, getComponentAt, getComponentCount, getComponents, getComponentZOrder, getContainerListeners, getFocusTraversalKeys, getFocusTraversalPolicy, getInsets, getLayout, getListeners, getMaximumSize, getMinimumSize, getMousePosition, getPreferredSize, insets, invalidate, isAncestorOf, isFocusCycleRoot, isFocusCycleRoot, isFocusTraversalPolicyProvider, isFocusTraversalPolicySet, layout, list, list, locate, minimumSize, paint, paintComponents, preferredSize, print, printComponents, processContainerEvent, processEvent, remove, removeAll, removeContainerListener, removeNotify, setComponentZOrder, setFocusCycleRoot, setFocusTraversalKeys, setFocusTraversalPolicy, setFocusTraversalPolicyProvider, setFont, transferFocusDownCycle, validate, validateTree
action, add, addComponentListener, addFocusListener, addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener, addKeyListener, addMouseListener, addMouseMotionListener, addMouseWheelListener, bounds, checkImage, checkImage, coalesceEvents, contains, contains, createImage, createImage, createVolatileImage, createVolatileImage, disable, disableEvents, dispatchEvent, enable, enable, enableEvents, enableInputMethods, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, getBackground, getBaseline, getBaselineResizeBehavior, getBounds, getBounds, getColorModel, getComponentListeners, getComponentOrientation, getCursor, getDropTarget, getFocusCycleRootAncestor, getFocusListeners, getFocusTraversalKeysEnabled, getFont, getFontMetrics, getForeground, getGraphicsConfiguration, getHeight, getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint, getInputContext, getInputMethodListeners, getInputMethodRequests, getKeyListeners, getLocation, getLocation, getLocationOnScreen, getMouseListeners, getMouseMotionListeners, getMousePosition, getMouseWheelListeners, getName, getParent, getPeer, getPropertyChangeListeners, getPropertyChangeListeners, getSize, getSize, getToolkit, getTreeLock, getWidth, getX, getY, gotFocus, handleEvent, hasFocus, hide, imageUpdate, inside, isBackgroundSet, isCursorSet, isDisplayable, isDoubleBuffered, isEnabled, isFocusable, isFocusOwner, isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isMaximumSizeSet, isMinimumSizeSet, isOpaque, isPreferredSizeSet, isShowing, isValid, isVisible, keyDown, keyUp, list, list, list, location, lostFocus, mouseDown, mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus, paintAll, postEvent, prepareImage, prepareImage, printAll, processComponentEvent, processFocusEvent, processHierarchyBoundsEvent, processHierarchyEvent, processInputMethodEvent, processKeyEvent, processMouseEvent, processMouseMotionEvent, processMouseWheelEvent, remove, removeComponentListener, removeFocusListener, removeHierarchyBoundsListener, removeHierarchyListener, removeInputMethodListener, removeKeyListener, removeMouseListener, removeMouseMotionListener, removeMouseWheelListener, removePropertyChangeListener, removePropertyChangeListener, repaint, repaint, repaint, requestFocus, requestFocus, requestFocusInWindow, requestFocusInWindow, reshape, revalidate, setBackground, setBounds, setBounds, setComponentOrientation, setCursor, setDropTarget, setEnabled, setFocusable, setFocusTraversalKeysEnabled, setForeground, setIgnoreRepaint, setLocale, setLocation, setLocation, setMaximumSize, setMinimumSize, setName, setPreferredSize, setSize, setSize, setVisible, show, show, size, toString, transferFocus, transferFocusBackward, transferFocusUpCycle
private javax.swing.JTextArea dataArea
private javax.swing.JButton loadButton
private javax.swing.JPasswordField pwd
private java.io.PrintStream log
private javax.swing.JProgressBar progressBar
private java.lang.String textToSign
private java.lang.String attrPrintout
private byte[] digestInfo
private byte[] encryptedDigest
private java.lang.String cryptokiLib
private java.lang.String signerLabel
private java.lang.String baseHttpUrl
private byte[] certificate
private static final short SEARCH_BY_PRIVATE_KEY
private static final short SEARCH_BY_CERTIFICATE_KEY_USAGE
private short OBJECT_SEARCH_CRITERION
public static final int ERROR
public static final int RESET
public static final int DATA_LOADED
public static final int SIGN_DONE
public static final int POST_ERROR
public static final int POST_OK_VERIFY_OK
public static final int POST_OK_VERIFY_ERROR
public static final java.lang.String DEFAULT_BASE_HTTP_URL
public void actionPerformed(java.awt.event.ActionEvent e)
actionPerformed
in interface java.awt.event.ActionListener
ActionListener.actionPerformed(java.awt.event.ActionEvent)
public void destroy()
public byte[] getCertificate()
private java.lang.String getCryptokiLib()
public byte[] getDigestInfo()
public byte[] getEncryptedDigest()
#getDigest()
;
Encryption is done on the token.private java.lang.String getSignerLabel()
private boolean loadData()
private java.lang.String retrieveTextToSign()
private byte[] retrieveDigestInfo()
private java.lang.String retrieveAuthenticatedAttributesPrintout()
private java.lang.String httpGet(java.net.URL url) throws java.io.IOException
url
- the url to GET.java.io.IOException
retrieveTextToSign()
,
#retrieveBytesToSign()
,
retrieveAuthenticatedAttributesPrintout()
private java.lang.String httpPOST(java.net.URL url, java.lang.String data) throws java.io.IOException
url
- the url to POST to.data
- the data to POST.java.io.IOException
private int sendSignatureAndCertificate()
int
result code of
POST_ERROR
if the POST was not
completed, POST_OK_VERIFY_ERROR
if the
POST was ok but there was a signature verification error,
POST_OK_VERIFY_OK
if all was ok and the
CMS message file was written on the server filesystem.public void init()
private void displayDataToSign()
private void initStatus(int min, int max)
min
- minimum value for the status bar.max
- maximum value for the status bar.private void setStatus(int code, java.lang.String statusString)
code
- statusString
- private boolean detectCardAndCriptoki() throws java.io.IOException
PCSCHelper
class is used
to detect reader and token presence, trying also to provide a candidate
PKCS#11 cryptoki for it; detection is bypassed if an applet parameter
forcing cryptoki selection is provided.java.io.IOException
private void setCertificate(byte[] newCertificate)
newCertificate
- byteprivate void setCryptokiLib(java.lang.String newCryptokiLib)
newCryptokiLib
- java.lang.String name of the native librarypublic void setDigestInfo(byte[] newDigestInfo)
newDigest
- byte[] containing the digest value to set.public void setEncryptedDigest(byte[] newEncryptedDigest)
newEncryptedDigest
- byte[] containing the encrypted digest value to set..private void setSignerLabel(java.lang.String newSignerLabel)
newSignerLabel
- java.lang.String the signer identifier on the token.public void sign() throws java.security.cert.CertificateException
PKCS11Signer
class. Different criteria can be used to find
relevant objects on the key: the default implementation here tries to act
in order to build an italian legal-value document. A Certificate carrying
an KeyUsage extension of non-repudiation marked critical is searched; if
found the corresponding private key is used to sign. A real-world
application should consent the user the certificate for signing.java.security.cert.CertificateException
private void findCertificate() throws java.security.cert.CertificateException
java.security.cert.CertificateException
public void start()
public void stop()
java.lang.String formatAsHexString(byte[] bytes)
public java.lang.String getBaseHttpUrl()
public void setBaseHttpUrl(java.lang.String baseHttpUrl)