Source Code Cross Referenced for Protocol.java in  » 6.0-JDK-Modules » j2me » com » sun » io » j2me » jcrmi » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » com.sun.io.j2me.jcrmi 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *   
0003:         *
0004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006:         * 
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License version
0009:         * 2 only, as published by the Free Software Foundation.
0010:         * 
0011:         * This program is distributed in the hope that it will be useful, but
0012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014:         * General Public License version 2 for more details (a copy is
0015:         * included at /legal/license.txt).
0016:         * 
0017:         * You should have received a copy of the GNU General Public License
0018:         * version 2 along with this work; if not, write to the Free Software
0019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA
0021:         * 
0022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023:         * Clara, CA 95054 or visit www.sun.com if you need additional
0024:         * information or have any questions.
0025:         */
0026:
0027:        package com.sun.io.j2me.jcrmi;
0028:
0029:        import com.sun.j2me.app.AppPackage;
0030:        import com.sun.j2me.security.SatsaPermission;
0031:        import java.io.*;
0032:        import java.rmi.Remote;
0033:        import java.rmi.RemoteException;
0034:        import com.sun.j2me.crypto.NoSuchAlgorithmException;
0035:        import com.sun.j2me.crypto.DigestException;
0036:        import com.sun.j2me.crypto.MessageDigest;
0037:        import javax.microedition.io.Connection;
0038:        import javax.microedition.io.StreamConnection;
0039:        import javax.microedition.jcrmi.JavaCardRMIConnection;
0040:        import javax.microedition.jcrmi.RemoteStub;
0041:
0042:        import com.sun.j2me.io.ConnectionBaseInterface;
0043:        import com.sun.io.j2me.apdu.APDUManager;
0044:        import com.sun.io.j2me.apdu.Handle;
0045:        import com.sun.satsa.acl.ACLPermissions;
0046:        import com.sun.satsa.acl.AccessControlManager;
0047:        import com.sun.satsa.acl.JCRMIPermissions;
0048:        import com.sun.satsa.util.Utils;
0049:        import javacard.framework.*;
0050:        import javacard.framework.service.ServiceException;
0051:
0052:        import com.sun.j2me.main.Configuration;
0053:
0054:        import com.sun.j2me.security.TrustedClass;
0055:        import com.sun.j2me.security.Token;
0056:        import com.sun.satsa.security.SecurityInitializer;
0057:
0058:        /**
0059:         * JCRMI connection to card application.
0060:         */
0061:        public class Protocol implements  JavaCardRMIConnection,
0062:                ConnectionBaseInterface, StreamConnection {
0063:
0064:            /*
0065:             * Inner class to request security token from SecurityTokenInitializer.
0066:             * SecurityTokenInitializer should be able to check this inner class name.
0067:             */
0068:            static private class SecurityTrusted implements  TrustedClass {
0069:            };
0070:
0071:            /** This class has a different security domain than the App suite */
0072:            private static Token securityToken = SecurityInitializer
0073:                    .requestToken(new SecurityTrusted());
0074:
0075:            /**
0076:             * Size of APDU buffer.
0077:             */
0078:            private static final int APDUBufferSize = 255;
0079:
0080:            /**
0081:             * Stub object for initial remote reference.
0082:             */
0083:            private Remote initialReference;
0084:
0085:            /**
0086:             * Reference object for initial remote reference.
0087:             */
0088:            private Reference internalReference;
0089:
0090:            /**
0091:             * Remote reference uses this buffer to prepare INVOKE APDU command.
0092:             */
0093:            private byte[] APDUBuffer = new byte[APDUBufferSize];
0094:
0095:            /**
0096:             * Current offset in <code>APDUBuffer</code> buffer for
0097:             * <code>write</code> methods.
0098:             */
0099:            private int offset;
0100:
0101:            /**
0102:             * Response APDU data.
0103:             */
0104:            private byte[] response;
0105:
0106:            /**
0107:             * Current offset in <code>response</code> buffer for
0108:             * <code>read</code> methods.
0109:             */
0110:            private int r_offset;
0111:
0112:            /**
0113:             * SHA-1 message digest object used by this connection.
0114:             */
0115:            private MessageDigest SHA;
0116:
0117:            /** The current APDU connection handle. */
0118:            private Handle h;
0119:
0120:            /**
0121:             * A flag to indicate if connection is open or not.
0122:             */
0123:            private boolean connectionOpen;
0124:
0125:            /**
0126:             * This object verifies access rights of MIDlet.
0127:             */
0128:            private JCRMIPermissions verifier;
0129:
0130:            /**
0131:             * Connector uses this method to initialize the connection object.
0132:             * This method establishes APDU connection with card application,
0133:             * obtains FCI information and creates stub for initial remote
0134:             * reference.
0135:             * @param name the URL for the connection without protocol name
0136:             * @param mode the access mode (Ignored)
0137:             * @param timeouts a flag to indicate that the caller wants timeout
0138:             *                  exceptions. Ignored
0139:             * @return this connection
0140:             * @throws IOException if the connection can not be initialized
0141:             * @throws RemoteException if initial remote reference object can not be
0142:             * created
0143:             * @throws SecurityException if access is restricted by ACL
0144:             */
0145:            public Connection openPrim(String name, int mode, boolean timeouts)
0146:                    throws IOException {
0147:
0148:                AppPackage appPackage = AppPackage.getInstance();
0149:                try {
0150:                    appPackage
0151:                            .checkForPermission(SatsaPermission.JCRMI_CONNECTION);
0152:                } catch (InterruptedException ie) {
0153:                    throw new InterruptedIOException(
0154:                            "Interrupted while trying to ask the user permission");
0155:                }
0156:
0157:                int slotInfo;
0158:                // parse URL string for slot number and AID
0159:                try {
0160:                    slotInfo = parseURL(name);
0161:                } catch (NullPointerException npe) {
0162:                    throw new IllegalArgumentException("Invalid URL");
0163:                } catch (IndexOutOfBoundsException iobe) {
0164:                    throw new IllegalArgumentException("Invalid URL");
0165:                } catch (IllegalArgumentException iae) {
0166:                    throw new IllegalArgumentException("Invalid URL");
0167:                }
0168:
0169:                APDUManager.checkSlotNumber(slotInfo);
0170:                // get card application selected
0171:                APDUManager.initACL(slotInfo);
0172:                verifier = AccessControlManager.getJCRMIPermissions(slotInfo,
0173:                        APDUBuffer, appPackage.getCA());
0174:
0175:                h = APDUManager.selectApplication(APDUBuffer, slotInfo);
0176:
0177:                connectionOpen = true;
0178:
0179:                // parse FCI
0180:                byte[] FCI = h.getFCI();
0181:
0182:                byte invokeINS;
0183:
0184:                try {
0185:                    // fci_tag or application_data_tag
0186:                    if (FCI[0] != 0x6f || FCI[2] != 0x6e) {
0187:                        throw new RemoteException("Incorrect FCI format");
0188:                    }
0189:
0190:                    int index = 4;
0191:
0192:                    // skip unnecessary tag/value pairs
0193:                    while (FCI[index] != 0x5E) { // jc_rmi_data_tag
0194:                        index += 2 + (FCI[index] & 0xff);
0195:                    }
0196:
0197:                    index += 4;
0198:
0199:                    invokeINS = FCI[index++];
0200:
0201:                    if (FCI[index++] != (byte) 0x81) { // normal_tag
0202:                        throw new RemoteException("Incorrect FCI format");
0203:                    }
0204:
0205:                    response = FCI;
0206:                    r_offset = index;
0207:
0208:                    initialReference = createStub();
0209:
0210:                    if (initialReference == null) {
0211:                        throw new RemoteException();
0212:                    }
0213:                } catch (RemoteException e) {
0214:                    close();
0215:                    throw e;
0216:                } catch (Throwable e) {
0217:                    close();
0218:                    throw new RemoteException("Can't create initial reference");
0219:                }
0220:
0221:                offset = 0;
0222:                putByte(0x80 | h.channel);
0223:                putByte(invokeINS);
0224:                putShort(0x0202);
0225:
0226:                try {
0227:                    SHA = new MessageDigest("SHA-1");
0228:                } catch (NoSuchAlgorithmException e) {
0229:                    // Ignore this exception
0230:                }
0231:
0232:                return this ;
0233:            }
0234:
0235:            /**
0236:             * Closes the connection.
0237:             * @throws IOException If an I/O error occurs
0238:             */
0239:            public void close() throws IOException {
0240:                synchronized (APDUBuffer) {
0241:                    if (connectionOpen) {
0242:                        connectionOpen = false;
0243:                        APDUManager.closeConnection(h);
0244:                    }
0245:                }
0246:            }
0247:
0248:            /**
0249:             * Returns the stub object for an initial remote reference.
0250:             * @return the initial remote reference
0251:             */
0252:            public java.rmi.Remote getInitialReference() {
0253:                return initialReference;
0254:            }
0255:
0256:            /**
0257:             * Parses the URL to get the slot number and AID.
0258:             * Prepares SELECT APDU in APDUBuffer.
0259:             * @param URL contains the URL from which
0260:             * the slot information is to be extracted
0261:             * @return slot number for this connection
0262:             */
0263:            private int parseURL(String URL) {
0264:
0265:                int slotIndex = URL.indexOf(":") + 1;
0266:                int AIDIndex = URL.indexOf(";AID=");
0267:
0268:                int slotInfo = (AIDIndex == slotIndex) ? 0 : Integer.parseInt(
0269:                        URL.substring(slotIndex, AIDIndex), 16);
0270:
0271:                // prepare selection APDU
0272:                offset = 0;
0273:
0274:                // IMPL_NOTE: For JavaCard 2.1 compliant cards jcrmi emulation is used.
0275:                String jcVersion = Configuration
0276:                        .getProperty("com.sun.javacard.version");
0277:                if ((jcVersion.equals("2.1")) || (jcVersion.startsWith("2.1."))) {
0278:                    putInt(0x00a40400); // selection APDU header
0279:                } else {
0280:                    putInt(0x00a40410); // selection APDU header
0281:                }
0282:                offset++; // length
0283:
0284:                // parse for AID
0285:                int AIDLength = APDUManager.parseDottedBytes(URL
0286:                        .substring(AIDIndex + 5), APDUBuffer, offset);
0287:
0288:                if (AIDLength < 5 || AIDLength > 16)
0289:                    throw new IllegalArgumentException();
0290:
0291:                APDUBuffer[4] = (byte) AIDLength;
0292:                offset += AIDLength;
0293:                putByte(255);
0294:
0295:                return slotInfo;
0296:            }
0297:
0298:            /**
0299:             * Writes <code>param</code> value into <code>APDUBuffer</code>.
0300:             * @param param the value to be written
0301:             */
0302:            private void putByte(int param) {
0303:                APDUBuffer[offset++] = (byte) param;
0304:            }
0305:
0306:            /**
0307:             * Writes <code>param</code> value into <code>APDUBuffer</code>.
0308:             * @param param the value to be written
0309:             */
0310:            private void putShort(int param) {
0311:                putByte(param >> 8);
0312:                putByte(param);
0313:            }
0314:
0315:            /**
0316:             * Writes <code>param</code> value into <code>APDUBuffer</code>.
0317:             * @param param the value to be written
0318:             */
0319:            private void putInt(int param) {
0320:                putByte(param >> 24);
0321:                putByte(param >> 16);
0322:                putByte(param >> 8);
0323:                putByte(param);
0324:            }
0325:
0326:            /**
0327:             * Reads one byte from response APDU, zero-extends it to type
0328:             * <code>int</code>, and returns the result.
0329:             * @return the unsigned 8-bit value
0330:             */
0331:            private int getByte() {
0332:                return response[r_offset++] & 0xff;
0333:            }
0334:
0335:            /**
0336:             * Reads <code>short</code> value from response APDU
0337:             * @return <code>short</code> value
0338:             */
0339:            private short getShort() {
0340:                return (short) (getByte() << 8 | getByte());
0341:            }
0342:
0343:            /**
0344:             * Reads <code>int</code> value from response APDU.
0345:             * @return <code>int</code> value
0346:             */
0347:            private int getInt() {
0348:                return (getByte() << 24) | (getByte() << 16) | (getByte() << 8)
0349:                        | getByte();
0350:            }
0351:
0352:            /**
0353:             * Reads <code>String</code> value from response APDU.
0354:             * @return <code>String</code> value
0355:             */
0356:            private String getString() throws RemoteException {
0357:
0358:                int len = getByte();
0359:
0360:                if (len == 0) {
0361:                    return null;
0362:                }
0363:
0364:                String S;
0365:                try {
0366:                    S = new String(response, r_offset, len, Utils.utf8);
0367:                } catch (UnsupportedEncodingException e) {
0368:                    throw new RemoteException("UTF-8 encoding is not supported");
0369:                }
0370:                r_offset += len;
0371:                return S;
0372:            }
0373:
0374:            /**
0375:             * Creates stub using remote reference descriptor in
0376:             * <code>response</code> buffer at <code>r_offset </code> offset.
0377:             * @return new stub object
0378:             * @throws java.rmi.RemoteException if an error occurs
0379:             */
0380:            private Remote createStub() throws RemoteException {
0381:
0382:                short objectID = getShort();
0383:
0384:                if (objectID == (short) 0xffff) {
0385:                    return null; // null reference returned
0386:                }
0387:
0388:                // hash modifier
0389:                String hashModifier = getString();
0390:
0391:                // list of interfaces
0392:
0393:                int count = getByte();
0394:
0395:                Class stubClass = null;
0396:                String className = null;
0397:                String packageName = null;
0398:                Class[] classes = new Class[count];
0399:
0400:                for (int i = 0; i < count; i++) {
0401:
0402:                    String name = getString();
0403:                    if (name != null) {
0404:                        packageName = name.replace('/', '.');
0405:                    }
0406:
0407:                    name = packageName + "." + getString();
0408:
0409:                    try {
0410:                        classes[i] = Class.forName(name);
0411:                    } catch (ClassNotFoundException e) {
0412:                        throw new RemoteException("Class not found", e);
0413:                    }
0414:
0415:                    if (stubClass == null
0416:                            || stubClass.isAssignableFrom(classes[i])) {
0417:                        stubClass = classes[i];
0418:                        className = name;
0419:                        continue;
0420:                    }
0421:                }
0422:
0423:                for (int i = 0; i < count; i++) {
0424:                    if (!classes[i].isAssignableFrom(stubClass)) {
0425:                        throw new RemoteException(
0426:                                "Incorrect hierarchy in descriptor");
0427:                    }
0428:                }
0429:
0430:                RemoteStub stub;
0431:                try {
0432:                    stub = RemoteStubCreation.createStub(className + "_Stub");
0433:                } catch (ClassNotFoundException cnfe) {
0434:                    throw new RemoteException("Can't find stub class", cnfe);
0435:                } catch (IllegalAccessException iae) {
0436:                    throw new RemoteException("Access to stub class denied",
0437:                            iae);
0438:                } catch (InstantiationException ie) {
0439:                    throw new RemoteException("Can't create stub object", ie);
0440:                }
0441:                Reference r = new Reference(this , objectID, hashModifier,
0442:                        className);
0443:                if (internalReference == null) {
0444:                    internalReference = r;
0445:                }
0446:                stub.setRef(r);
0447:
0448:                return (Remote) stub;
0449:            }
0450:
0451:            /**
0452:             * Constant for JCRMI protocol.
0453:             */
0454:            private static final byte NormalTag = (byte) 0x81;
0455:            /**
0456:             * Constant for JCRMI protocol.
0457:             */
0458:            private static final byte ExactExceptionTag = (byte) 0x82;
0459:            /**
0460:             * Constant for JCRMI protocol.
0461:             */
0462:            private static final byte ExceptionSubclassTag = (byte) 0x83;
0463:            /**
0464:             * Constant for JCRMI protocol.
0465:             */
0466:            private static final byte ErrorTag = (byte) 0x99;
0467:
0468:            /**
0469:             * Invokes a remote method.
0470:             *
0471:             * The remote method invoked on the card can throw an exception to
0472:             * signal that an unexpected condition has been detected.<p>
0473:             *
0474:             * If the exception thrown on the card is an exception defined in
0475:             * the Java Card 2.2 API, then the same exception is thrown to the
0476:             * stub method. The client can access the reason code associated
0477:             * with Java Card-specific exceptions using the standard
0478:             * <code>getReason()</code> method.<p>
0479:             *
0480:             * If the exception thrown on the card is a subclass of an exception
0481:             * defined in the Java Card 2.2 API, then the closest exception defined
0482:             * in the API (along with the reason code, if applicable) is
0483:             * thrown to the stub method. The detail message string of the
0484:             * exception object may indicate that exception subclass was thrown
0485:             * on the card.<p>
0486:             *
0487:             * Apart from the exceptions thrown by the remote method itself,
0488:             * errors during communication, marshalling, protocol handling,
0489:             * unmarshalling, stub object instantiation, and so on, related
0490:             * to the JCRMI method invocation, results in a
0491:             * <code>RemoteException</code> being thrown to the stub method.
0492:             *
0493:             * @param ref handle for remote object
0494:             * @param method simple (not fully qualified) name of the method
0495:             *        followed by the method descriptor. Representation of a
0496:             *        method descriptor is the same as that described in The
0497:             *        Java Virtual Machine Specification (&#167 4.3.3)
0498:             * @param params the parameter list
0499:             * @return result of remote method invocation
0500:             * @exception java.lang.Exception if any exception occurs during
0501:             *            the remote method invocation
0502:             */
0503:            Object invoke(Reference ref, String method, Object[] params)
0504:                    throws Exception {
0505:
0506:                if (!connectionOpen) {
0507:                    throw new RemoteException("Connection is closed.");
0508:                }
0509:
0510:                verifier.checkPermission(ref.getClassName(), method);
0511:
0512:                synchronized (APDUBuffer) {
0513:
0514:                    try {
0515:                        marshal(ref, method, params);
0516:                    } catch (RuntimeException ai) {
0517:                        throw new RemoteException(
0518:                                "Error marshalling parameters");
0519:                    }
0520:
0521:                    try {
0522:                        response = APDUManager.exchangeAPDU(h, APDUBuffer);
0523:                    } catch (IOException e) {
0524:                        throw new RemoteException("IO error", e);
0525:                    }
0526:
0527:                    r_offset = response.length - 2;
0528:
0529:                    if (getShort() != (short) 0x9000) {
0530:                        throw new RemoteException("Incorrect status word");
0531:                    }
0532:
0533:                    r_offset = 0;
0534:
0535:                    byte tag = (byte) getByte();
0536:
0537:                    Exception ex = null;
0538:                    Object result = null;
0539:
0540:                    try {
0541:                        if (tag == ExactExceptionTag
0542:                                || tag == ExceptionSubclassTag) {
0543:                            ex = parseException(tag);
0544:                        } else if (tag == ErrorTag) {
0545:                            ex = parseError();
0546:                        } else if (tag == NormalTag) {
0547:                            result = parseResult(method);
0548:                        } else {
0549:                            throw new RemoteException("Incorrect tag value: "
0550:                                    + tag);
0551:                        }
0552:
0553:                        getShort(); // status word
0554:
0555:                    } catch (RuntimeException e) {
0556:                        throw new RemoteException(
0557:                                "Incorrect response structure");
0558:                    }
0559:
0560:                    if (ex != null) {
0561:                        throw ex;
0562:                    }
0563:
0564:                    return result;
0565:                }
0566:            }
0567:
0568:            /**
0569:             * Prepares INVOKE APDU.
0570:             * @param ref handle for remote object
0571:             * @param method simple (not fully qualified) name of the method
0572:             *        followed by the method descriptor. Representation of a
0573:             *        method descriptor is the same as that described in The
0574:             *        Java Virtual Machine Specification (&#167 4.3.3)
0575:             * @param params the parameter list
0576:             * @throws RemoteException if an error occurs
0577:             */
0578:            private void marshal(Reference ref, String method, Object[] params)
0579:                    throws RemoteException {
0580:
0581:                offset = 5;
0582:
0583:                putShort(ref.getObjectID());
0584:
0585:                String hashString = method;
0586:                String hashModifier = ref.getHashModifier();
0587:
0588:                if (hashModifier != null) {
0589:                    hashString = hashModifier + hashString;
0590:                }
0591:
0592:                byte[] buf = Utils.stringToBytes(hashString);
0593:
0594:                SHA.reset();
0595:                SHA.update(buf, 0, buf.length);
0596:                try {
0597:                    SHA.digest(APDUBuffer, offset, SHA.getDigestLength());
0598:                } catch (DigestException e) {
0599:                    throw new RemoteException("SHA1 error");
0600:                }
0601:
0602:                offset += 2;
0603:
0604:                if (params != null) {
0605:                    for (int i = 0; i < params.length; i++) {
0606:
0607:                        Object obj = params[i];
0608:
0609:                        if (obj == null) {
0610:                            putByte(0xff);
0611:                            continue;
0612:                        }
0613:
0614:                        if (obj instanceof  Byte) {
0615:                            putByte(((Byte) obj).byteValue());
0616:                            continue;
0617:                        }
0618:
0619:                        if (obj instanceof  Boolean) {
0620:                            putByte(((Boolean) obj).booleanValue() ? 1 : 0);
0621:                            continue;
0622:                        }
0623:
0624:                        if (obj instanceof  Short) {
0625:                            putShort(((Short) obj).shortValue());
0626:                            continue;
0627:                        }
0628:
0629:                        if (obj instanceof  Integer) {
0630:                            putInt(((Integer) obj).intValue());
0631:                            continue;
0632:                        }
0633:
0634:                        if (obj instanceof  byte[]) {
0635:                            byte[] param = (byte[]) obj;
0636:                            putByte(param.length);
0637:                            for (int k = 0; k < param.length; k++) {
0638:                                putByte(param[k]);
0639:                            }
0640:                            continue;
0641:                        }
0642:
0643:                        if (obj instanceof  boolean[]) {
0644:                            boolean[] param = (boolean[]) obj;
0645:                            putByte(param.length);
0646:                            for (int k = 0; k < param.length; k++) {
0647:                                putByte(param[k] ? 1 : 0);
0648:                            }
0649:                            continue;
0650:                        }
0651:
0652:                        if (obj instanceof  short[]) {
0653:                            short[] param = (short[]) obj;
0654:                            putByte(param.length);
0655:                            for (int k = 0; k < param.length; k++) {
0656:                                putShort(param[k]);
0657:                            }
0658:                            continue;
0659:                        }
0660:
0661:                        if (obj instanceof  int[]) {
0662:                            int[] param = (int[]) obj;
0663:                            putByte(param.length);
0664:                            for (int k = 0; k < param.length; k++) {
0665:                                putInt(param[k]);
0666:                            }
0667:                            continue;
0668:                        }
0669:
0670:                        throw new RemoteException("Incorrect parameter type");
0671:                    }
0672:                }
0673:                APDUBuffer[4] = (byte) (offset - 5);
0674:
0675:                putByte(255);
0676:            }
0677:
0678:            /**
0679:             * Parses response containing data about exception.
0680:             * @param tag type tag of exception
0681:             * @return the exception to be thrown to stub
0682:             * @throws RemoteException  if an error occurs during parsing
0683:             */
0684:            private Exception parseException(byte tag) throws RemoteException {
0685:
0686:                String message = (tag == ExactExceptionTag) ? "Exception is thrown on card"
0687:                        : "Exception subclass is thrown on card";
0688:
0689:                byte type = (byte) getByte();
0690:                short reason = getShort();
0691:
0692:                switch (type) {
0693:                case 0x00:
0694:                    return new Exception(message + ": java.lang.Throwable");
0695:                case 0x01:
0696:                    return new ArithmeticException(message);
0697:                case 0x02:
0698:                    return new ArrayIndexOutOfBoundsException(message);
0699:                case 0x03:
0700:                    return new ArrayStoreException(message);
0701:                case 0x04:
0702:                    return new ClassCastException(message);
0703:                case 0x05:
0704:                    return new Exception(message);
0705:                case 0x06:
0706:                    return new IndexOutOfBoundsException(message);
0707:                case 0x07:
0708:                    return new NegativeArraySizeException(message);
0709:                case 0x08:
0710:                    return new NullPointerException(message);
0711:                case 0x09:
0712:                    return new RuntimeException(message);
0713:                case 0x0A:
0714:                    return new SecurityException(message);
0715:                case 0x0B:
0716:                    return new IOException(message);
0717:                case 0x0C:
0718:                    return new RemoteException(message);
0719:                case 0x20:
0720:                    return new APDUException(reason);
0721:                case 0x21:
0722:                    return new CardException(reason);
0723:                case 0x22:
0724:                    return new CardRuntimeException(reason);
0725:                case 0x23:
0726:                    return new ISOException(reason);
0727:                case 0x24:
0728:                    return new PINException(reason);
0729:                case 0x25:
0730:                    return new SystemException(reason);
0731:                case 0x26:
0732:                    return new TransactionException(reason);
0733:                case 0x27:
0734:                    return new UserException(reason);
0735:                case 0x30:
0736:                    return new javacard.security.CryptoException(reason);
0737:                case 0x40:
0738:                    return new ServiceException(reason);
0739:                default:
0740:                    throw new RemoteException(
0741:                            "Unknown exception is thrown on card");
0742:                }
0743:            }
0744:
0745:            /**
0746:             * Parses response containing data about error.
0747:             * @return the exception to be thrown to stub
0748:             * @throws RemoteException if error code is unknown
0749:             */
0750:            private RemoteException parseError() throws RemoteException {
0751:
0752:                short code = getShort();
0753:
0754:                switch (code) {
0755:                case 1:
0756:                    return new RemoteException("Object not exported");
0757:                case 2:
0758:                    return new RemoteException("Method not found");
0759:                case 3:
0760:                    return new RemoteException("Signature mismatch");
0761:                case 4:
0762:                    return new RemoteException("Out of parameter resources");
0763:                case 5:
0764:                    return new RemoteException("Out of response resources");
0765:                case 6:
0766:                    return new RemoteException(
0767:                            "Protocol error reported by the card");
0768:                default:
0769:                    throw new RemoteException("Error reported by the card: "
0770:                            + code);
0771:                }
0772:            }
0773:
0774:            /**
0775:             * Parses the normal JCRMI response.
0776:             * @param method method name and signature
0777:             * @return the value returned by method
0778:             * @throws RemoteException if an error occurs during parsing
0779:             */
0780:            private Object parseResult(String method) throws RemoteException {
0781:
0782:                int index = method.indexOf(')') + 1;
0783:
0784:                if (index != -1) {
0785:                    switch (method.charAt(index)) {
0786:                    case 'V':
0787:                        return null;
0788:                    case 'B':
0789:                        return new Byte((byte) getByte());
0790:                    case 'Z':
0791:                        return new Boolean(getByte() == 1 ? true : false);
0792:                    case 'S':
0793:                        return new Short(getShort());
0794:                    case 'I':
0795:                        return new Integer(getInt());
0796:                    case 'L':
0797:                        return createStub();
0798:                    case '[': {
0799:
0800:                        int len = getByte();
0801:
0802:                        if (len == 255)
0803:                            return null;
0804:
0805:                        switch (method.charAt(index + 1)) {
0806:                        case 'B': {
0807:                            byte[] data = new byte[len];
0808:
0809:                            for (int i = 0; i < len; i++) {
0810:                                data[i] = (byte) getByte();
0811:                            }
0812:                            return data;
0813:                        }
0814:                        case 'Z': {
0815:                            boolean[] data = new boolean[len];
0816:
0817:                            for (int i = 0; i < len; i++) {
0818:                                data[i] = (getByte() == 1 ? true : false);
0819:                            }
0820:                            return data;
0821:                        }
0822:                        case 'S': {
0823:                            short[] data = new short[len];
0824:
0825:                            for (int i = 0; i < len; i++) {
0826:                                data[i] = getShort();
0827:                            }
0828:                            return data;
0829:                        }
0830:                        case 'I': {
0831:                            int[] data = new int[len];
0832:
0833:                            for (int i = 0; i < len; i++) {
0834:                                data[i] = getInt();
0835:                            }
0836:                            return data;
0837:                        }
0838:                        }
0839:                    }
0840:                    }
0841:                }
0842:                throw new RemoteException("Incorrect method signature");
0843:            }
0844:
0845:            /**
0846:             * Returns the card session identifier for this connection.
0847:             * @return the card session identifier
0848:             */
0849:            int getCardSessionId() {
0850:                return h.cardSessionId;
0851:            }
0852:
0853:            /**
0854:             * Returns the flag that indicates if connection is open.
0855:             * @return true if the connection is open
0856:             */
0857:            boolean isOpened() {
0858:                return connectionOpen;
0859:            }
0860:
0861:            /**
0862:             * Open and return an input stream for a connection.
0863:             * This method always throw
0864:             * <code>IllegalArgumentException</code>.
0865:             * @return An input stream
0866:             * @exception IllegalArgumentException  is thrown for all requests
0867:             */
0868:            public InputStream openInputStream() {
0869:                throw new IllegalArgumentException("Not supported");
0870:            }
0871:
0872:            /**
0873:             * Open and return a data input stream for a connection.
0874:             * This method always throw
0875:             * <code>IllegalArgumentException</code>.
0876:             * @return An input stream
0877:             * @exception IllegalArgumentException  is thrown for all requests
0878:             */
0879:            public DataInputStream openDataInputStream() {
0880:                throw new IllegalArgumentException("Not supported");
0881:            }
0882:
0883:            /**
0884:             * Open and return an output stream for a connection.
0885:             * This method always throw
0886:             * <code>IllegalArgumentException</code>.
0887:             * @return An output stream
0888:             * @exception IllegalArgumentException  is thrown for all requests
0889:             */
0890:            public OutputStream openOutputStream() {
0891:                throw new IllegalArgumentException("Not supported");
0892:            }
0893:
0894:            /**
0895:             * Open and return a data output stream for a connection.
0896:             * This method always throw
0897:             * <code>IllegalArgumentException</code>.
0898:             * @return An output stream
0899:             * @exception IllegalArgumentException  is thrown for all requests
0900:             */
0901:            public DataOutputStream openDataOutputStream() {
0902:                throw new IllegalArgumentException("Not supported");
0903:            }
0904:
0905:            /**
0906:             * A call to enterPin method pops up a UI that requests the PIN
0907:             * from the user. The pinID field indicates which PIN must be
0908:             * requested from the user. The user can either cancel the request
0909:             * or continue. If the user enters the PIN and chooses to continue,
0910:             * The implementation is responsible for
0911:             * presenting the PIN entered by the user to the card for verification.
0912:             * @param pinID the type of PIN the implementation is suppose to prompt
0913:             * the user to enter.
0914:             * @return PINENTRY_CANCELLED if the user cancelled the PIN entry
0915:             * request or the value returned by the remote method.
0916:             * @exception java.rmi.RemoteException is thrown if the PIN could
0917:             * not be communicated to the card or an exception is thrown
0918:             * by the card in response to the PIN entry.
0919:             * @exception SecurityException is thrown if the J2ME application does
0920:             * not have appropriate rights to ask for PIN verification.
0921:             */
0922:            public short enterPin(int pinID) throws java.rmi.RemoteException {
0923:                return doEnterPin(pinID, 0, ACLPermissions.CMD_VERIFY);
0924:            }
0925:
0926:            /**
0927:             * A call to <code>changePin</code> method pops up a UI that requests
0928:             * the user for an old or existing PIN value and the new PIN value to
0929:             * to change the value of the PIN. The pinID field indicates which PIN is
0930:             * to be changed. The user can either cancel the request
0931:             * or continue. If the user enters the PIN values and chooses to continue
0932:             * the implementation is responsible for presenting the
0933:             * the old and new values of the PIN to the card.
0934:             * @param pinID the type of PIN the implementation is suppose to prompt
0935:             * the user to change.
0936:             * @return PINENTRY_CANCELLED if the user cancelled the PIN entry
0937:             * request or the value returned by the remote method.
0938:             * @exception java.rmi.RemoteException is thrown if the PIN could
0939:             * not be communicated to the card or an exception is thrown
0940:             * by the card in response to the PIN entry.
0941:             * @exception SecurityException is thrown if the J2ME application does
0942:             * not have appropriate rights to ask for changing the PIN value.
0943:             */
0944:            public short changePin(int pinID) throws RemoteException {
0945:                return doEnterPin(pinID, 0, ACLPermissions.CMD_CHANGE);
0946:            }
0947:
0948:            /**
0949:             * A call to <code>disablePin</code> method pops up a UI that requests
0950:             * the user to enter the value for the PIN that is to be disabled.
0951:             * The pinID field
0952:             * indicates which PIN is to be disabled. The user can
0953:             * either cancel the request
0954:             * or continue. If the user enters the PIN and chooses to continue the
0955:             * implementation is responsible
0956:             * for presenting the PIN value to the card to disable PIN.
0957:             * @param pinID the type of PIN the implementation is required to prompt
0958:             * the user to enter.
0959:             * @return PINENTRY_CANCELLED if the user cancelled the PIN entry
0960:             * request or the value returned by the remote method.
0961:             * @exception java.rmi.RemoteException is thrown if the PIN could
0962:             * not be communicated to the card or an exception is thrown
0963:             * by the card in response to the PIN entry.
0964:             * @exception SecurityException is thrown if the J2ME application does
0965:             * not have appropriate rights to ask for disabling the PIN.
0966:             */
0967:            public short disablePin(int pinID) throws RemoteException {
0968:                return doEnterPin(pinID, 0, ACLPermissions.CMD_DISABLE);
0969:            }
0970:
0971:            /**
0972:             * A call to <code>enablePin</code> method pops up a UI that requests
0973:             * the user to enter the value for the PIN that is to be enabled.
0974:             * The pinID field
0975:             * indicates which PIN is to be enabled. The user can
0976:             * either cancel the request
0977:             * or continue. If the user enters the PIN and chooses to continue the
0978:             * implementation is responsible
0979:             * for presenting the PIN value to the card for enabling the PIN.
0980:             * @param pinID the type of PIN the implementation is required to prompt
0981:             * the user to enter.
0982:             * @return PINENTRY_CANCELLED if the user cancelled the PIN entry
0983:             * request or the value returned by the remote method.
0984:             * @exception java.rmi.RemoteException is thrown if the PIN could
0985:             * not be communicated to the card or an exception is thrown
0986:             * by the card in response to the PIN entry.
0987:             * @exception SecurityException is thrown if the J2ME application does
0988:             * not have appropriate rights to ask for enabling the PIN.
0989:             */
0990:            public short enablePin(int pinID) throws RemoteException {
0991:                return doEnterPin(pinID, 0, ACLPermissions.CMD_ENABLE);
0992:            }
0993:
0994:            /**
0995:             * This is a high-level method that lets the J2ME application
0996:             * ask the user to enter the value for an unblocking PIN,
0997:             * and the new value for the blocked PIN and send
0998:             * these to the card.
0999:             * A call to <code>unblockPin</code> method pops up a UI that requests
1000:             * the user to enter the value for the unblocking PIN and the
1001:             * new value for the blocked PIN.
1002:             * The <code>unblockingPinID</code> field indicates which unblocking
1003:             * PIN is to be
1004:             * used to unblock the blocked PIN which is indicated by the field
1005:             * <code>blockedPinId</code>.
1006:             * The unblockingPinID field indicates which PIN is to be unblocked.
1007:             * The user can either cancel the request
1008:             * or continue. If the user enters the PIN values and chooses to continue,
1009:             * the implementation is responsible
1010:             * for presenting the PIN values to the card for unblocking the
1011:             * blocked PIN.
1012:             * If padding is required for either of the PIN values, the
1013:             * implementation is responsible for providing appropriate padding.
1014:             * @param blockedPinID the Id of PIN that is to be unblocked.
1015:             * @param unblockingPinId the Id of unblocking PIN.
1016:             * @return PINENTRY_CANCELLED if the user cancelled the PIN entry
1017:             * request or the value returned by the remote method.
1018:             * @exception java.rmi.RemoteException is thrown if the PIN could
1019:             * not be communicated to the card or an exception is thrown
1020:             * by the card in response to the PIN entry.
1021:             * @exception SecurityException is thrown if the J2ME application does
1022:             * not have appropriate rights to ask for unblocking the PIN.
1023:             */
1024:            public short unblockPin(int blockedPinID, int unblockingPinId)
1025:                    throws RemoteException {
1026:                return doEnterPin(blockedPinID, unblockingPinId,
1027:                        ACLPermissions.CMD_UNBLOCK);
1028:            }
1029:
1030:            /**
1031:             * Performs PIN entry operation.
1032:             * @param pinID PIN identifier.
1033:             * @param uPinID unblocking PIN identifier.
1034:             * @param action PIN operation identifier.
1035:             * @return PINENTRY_CANCELLED if the user cancelled the PIN entry
1036:             * request or the value returned by the remote method.
1037:             * @exception java.rmi.RemoteException is thrown if the PIN could
1038:             * not be communicated to the card or an exception is thrown
1039:             * by the card in response to the PIN entry.
1040:             * @exception SecurityException is thrown if the J2ME application does
1041:             * not have appropriate rights to ask for unblocking the PIN.
1042:             */
1043:            private short doEnterPin(int pinID, int uPinID, int action)
1044:                    throws RemoteException {
1045:
1046:                if (!connectionOpen) {
1047:                    throw new RemoteException("Connection is closed.");
1048:                }
1049:
1050:                String method = null;
1051:                method = verifier.preparePIN(pinID, uPinID, action,
1052:                        internalReference.getClassName());
1053:                Object[] pins = verifier.enterPIN(action, securityToken);
1054:
1055:                if (pins == null) {
1056:                    return PINENTRY_CANCELLED;
1057:                }
1058:
1059:                try {
1060:                    Short r = (Short) invoke(internalReference, method, pins);
1061:                    return r.shortValue();
1062:                } catch (Exception e) {
1063:                    throw new RemoteException("" + e);
1064:                }
1065:            }
1066:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.