001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.security.provider.crypto;
019:
020: import java.security.ProviderException;
021: import java.security.AccessController;
022:
023: import org.apache.harmony.security.internal.nls.Messages;
024:
025: /**
026: * The static class providing access on Windows platform
027: * to system means for generating true random bits. <BR>
028: *
029: * It uses a native method to get the random bits from CryptGenRandom.
030: * If the required library is not installed
031: * the provider shouldn't register the algorithm.
032: */
033:
034: public class RandomBitsSupplier implements SHA1_Data {
035:
036: /**
037: * specification for native library
038: */
039: private static native boolean getWindowsRandom(byte[] bytes,
040: int numBytes);
041:
042: /**
043: * static field is "true" only if native library is linked
044: */
045: private static boolean serviceAvailable;
046:
047: static {
048: try {
049: AccessController
050: .doPrivileged(new java.security.PrivilegedAction() {
051: public Object run() throws UnsatisfiedLinkError {
052: System.loadLibrary(LIBRARY_NAME);
053: return null;
054: }
055: });
056: } catch (UnsatisfiedLinkError e) {
057: serviceAvailable = false;
058: }
059: serviceAvailable = true;
060: }
061:
062: /**
063: * The method is called by provider to determine if a device is available.
064: */
065: static boolean isServiceAvailable() {
066: return serviceAvailable;
067: }
068:
069: /**
070: * The method returns byte array containing random bits.
071: *
072: * @param
073: * numBytes - length of bytes requested
074: * @return
075: * byte array
076: * @throws
077: * InvalidArgumentException - if numBytes <= 0 <BR>
078: * ProviderException - if some problem related to native library is discovered <BR>
079: */
080: public static synchronized byte[] getRandomBits(int numBytes) {
081:
082: if (numBytes <= 0) {
083: throw new IllegalArgumentException(Messages.getString(
084: "security.195", numBytes)); //$NON-NLS-1$
085: }
086:
087: if (!serviceAvailable) {
088: throw new ProviderException(Messages
089: .getString("security.197")); //$NON-NLS-1$
090: }
091:
092: byte[] myBytes = new byte[numBytes];
093:
094: if (!getWindowsRandom(myBytes, numBytes)) {
095:
096: // it is unexpected result
097: throw new ProviderException(Messages
098: .getString("security.198")); //$NON-NLS-1$
099: }
100:
101: return myBytes;
102: }
103: }
|