1 /*
2  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package sun.security.x509;
26 
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.math.BigInteger;
31 import java.util.Enumeration;
32 import java.util.Random;
33 
34 import sun.security.util.*;
35 
36 /**
37  * This class defines the SerialNumber attribute for the Certificate.
38  *
39  * @author Amit Kapoor
40  * @author Hemma Prafullchandra
41  * @see CertAttrSet
42  */
43 public class CertificateSerialNumber implements CertAttrSet<String> {
44     /**
45      * Identifier for this attribute, to be used with the
46      * get, set, delete methods of Certificate, x509 type.
47      */
48     public static final String IDENT = "x509.info.serialNumber";
49 
50     /**
51      * Sub attributes name for this CertAttrSet.
52      */
53     public static final String NAME = "serialNumber";
54     public static final String NUMBER = "number";
55 
56     private SerialNumber        serial;
57 
58     /**
59      * Default constructor for the certificate attribute.
60      *
61      * @param num the serial number for the certificate.
62      */
CertificateSerialNumber(BigInteger num)63     public CertificateSerialNumber(BigInteger num) {
64       this.serial = new SerialNumber(num);
65     }
66 
67     /**
68      * Default constructor for the certificate attribute.
69      *
70      * @param num the serial number for the certificate.
71      */
CertificateSerialNumber(int num)72     public CertificateSerialNumber(int num) {
73       this.serial = new SerialNumber(num);
74     }
75 
76     /**
77      * Create the object, decoding the values from the passed DER stream.
78      *
79      * @param in the DerInputStream to read the serial number from.
80      * @exception IOException on decoding errors.
81      */
CertificateSerialNumber(DerInputStream in)82     public CertificateSerialNumber(DerInputStream in) throws IOException {
83         serial = new SerialNumber(in);
84     }
85 
86     /**
87      * Create the object, decoding the values from the passed stream.
88      *
89      * @param in the InputStream to read the serial number from.
90      * @exception IOException on decoding errors.
91      */
CertificateSerialNumber(InputStream in)92     public CertificateSerialNumber(InputStream in) throws IOException {
93         serial = new SerialNumber(in);
94     }
95 
96     /**
97      * Create the object, decoding the values from the passed DerValue.
98      *
99      * @param val the DER encoded value.
100      * @exception IOException on decoding errors.
101      */
CertificateSerialNumber(DerValue val)102     public CertificateSerialNumber(DerValue val) throws IOException {
103         serial = new SerialNumber(val);
104     }
105 
106     /**
107      * Return the serial number as user readable string.
108      */
toString()109     public String toString() {
110         if (serial == null) return "";
111         return (serial.toString());
112     }
113 
114     /**
115      * Encode the serial number in DER form to the stream.
116      *
117      * @param out the DerOutputStream to marshal the contents to.
118      * @exception IOException on errors.
119      */
encode(OutputStream out)120     public void encode(OutputStream out) throws IOException {
121         DerOutputStream tmp = new DerOutputStream();
122         serial.encode(tmp);
123 
124         out.write(tmp.toByteArray());
125     }
126 
127     /**
128      * Set the attribute value.
129      */
set(String name, Object obj)130     public void set(String name, Object obj) throws IOException {
131         if (!(obj instanceof SerialNumber)) {
132             throw new IOException("Attribute must be of type SerialNumber.");
133         }
134         if (name.equalsIgnoreCase(NUMBER)) {
135             serial = (SerialNumber)obj;
136         } else {
137             throw new IOException("Attribute name not recognized by " +
138                                 "CertAttrSet:CertificateSerialNumber.");
139         }
140     }
141 
142     /**
143      * Get the attribute value.
144      */
get(String name)145     public SerialNumber get(String name) throws IOException {
146         if (name.equalsIgnoreCase(NUMBER)) {
147             return (serial);
148         } else {
149             throw new IOException("Attribute name not recognized by " +
150                                 "CertAttrSet:CertificateSerialNumber.");
151         }
152     }
153 
154     /**
155      * Delete the attribute value.
156      */
delete(String name)157     public void delete(String name) throws IOException {
158         if (name.equalsIgnoreCase(NUMBER)) {
159             serial = null;
160         } else {
161             throw new IOException("Attribute name not recognized by " +
162                                 "CertAttrSet:CertificateSerialNumber.");
163         }
164     }
165 
166     /**
167      * Return an enumeration of names of attributes existing within this
168      * attribute.
169      */
getElements()170     public Enumeration<String> getElements() {
171         AttributeNameEnumeration elements = new AttributeNameEnumeration();
172         elements.addElement(NUMBER);
173 
174         return (elements.elements());
175     }
176 
177     /**
178      * Return the name of this attribute.
179      */
getName()180     public String getName() {
181         return (NAME);
182     }
183 
184     /**
185      * Generates a new random serial number.
186      */
newRandom64bit(Random rand)187     public static CertificateSerialNumber newRandom64bit(Random rand) {
188         while (true) {
189             BigInteger b = new BigInteger(64, rand);
190             if (b.signum() != 0) {
191                 return new CertificateSerialNumber(b);
192             }
193         }
194     }
195 }
196