Back to index

lightning-sunbird  0.9+nobinonly
p12plcy.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 
00038 #include "p12plcy.h"
00039 #include "secoid.h"
00040 #include "secport.h"
00041 #include "secpkcs5.h" 
00042 
00043 #define PKCS12_NULL  0x0000
00044 
00045 typedef struct pkcs12SuiteMapStr {
00046     SECOidTag        algTag;
00047     unsigned int     keyLengthBits;       /* in bits */
00048     unsigned long    suite;
00049     PRBool           allowed;
00050     PRBool           preferred;
00051 } pkcs12SuiteMap;
00052 
00053 static pkcs12SuiteMap pkcs12SuiteMaps[] = {
00054     { SEC_OID_RC4,          40,    PKCS12_RC4_40,              PR_FALSE,     PR_FALSE},
00055     { SEC_OID_RC4,          128,   PKCS12_RC4_128,             PR_FALSE,     PR_FALSE},
00056     { SEC_OID_RC2_CBC,             40,    PKCS12_RC2_CBC_40,   PR_FALSE,     PR_TRUE},
00057     { SEC_OID_RC2_CBC,             128,   PKCS12_RC2_CBC_128,  PR_FALSE,     PR_FALSE},
00058     { SEC_OID_DES_CBC,             64,    PKCS12_DES_56,              PR_FALSE,     PR_FALSE},
00059     { SEC_OID_DES_EDE3_CBC,    192,       PKCS12_DES_EDE3_168, PR_FALSE,     PR_FALSE},
00060     { SEC_OID_UNKNOWN,              0,    PKCS12_NULL,         PR_FALSE,     PR_FALSE},
00061     { SEC_OID_UNKNOWN,              0,    0L,                  PR_FALSE,     PR_FALSE}
00062 };
00063 
00064 /* determine if algid is an algorithm which is allowed */
00065 PRBool 
00066 SEC_PKCS12DecryptionAllowed(SECAlgorithmID *algid)
00067 {
00068     unsigned int keyLengthBits;
00069     SECOidTag algId;
00070     int i;
00071    
00072     algId = SEC_PKCS5GetCryptoAlgorithm(algid);
00073     if(algId == SEC_OID_UNKNOWN) {
00074        return PR_FALSE;
00075     }
00076     
00077     keyLengthBits = (unsigned int)(SEC_PKCS5GetKeyLength(algid) * 8);
00078 
00079     i = 0;
00080     while(pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
00081        if((pkcs12SuiteMaps[i].algTag == algId) && 
00082           (pkcs12SuiteMaps[i].keyLengthBits == keyLengthBits)) {
00083 
00084            return pkcs12SuiteMaps[i].allowed;
00085        }
00086        i++;
00087     }
00088 
00089     return PR_FALSE;
00090 }
00091 
00092 /* is any encryption allowed? */
00093 PRBool
00094 SEC_PKCS12IsEncryptionAllowed(void)
00095 {
00096     int i;
00097 
00098     i = 0;
00099     while(pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
00100        if(pkcs12SuiteMaps[i].allowed == PR_TRUE) {
00101            return PR_TRUE;
00102        } 
00103        i++;
00104     }
00105 
00106     return PR_FALSE;
00107 }
00108 
00109 /* get the preferred algorithm.
00110  */
00111 SECOidTag
00112 SEC_PKCS12GetPreferredEncryptionAlgorithm(void)
00113 {
00114     int i;
00115 
00116     i = 0;
00117     while(pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
00118        if((pkcs12SuiteMaps[i].preferred == PR_TRUE) && 
00119           (pkcs12SuiteMaps[i].allowed == PR_TRUE)) {
00120            return SEC_PKCS5GetPBEAlgorithm(pkcs12SuiteMaps[i].algTag,
00121                                        pkcs12SuiteMaps[i].keyLengthBits);
00122        }
00123        i++;
00124     }
00125 
00126     return SEC_OID_UNKNOWN;
00127 }
00128 
00129 /* return the strongest algorithm allowed */
00130 SECOidTag
00131 SEC_PKCS12GetStrongestAllowedAlgorithm(void)
00132 {
00133     int i, keyLengthBits = 0;
00134     SECOidTag algorithm = SEC_OID_UNKNOWN;
00135 
00136     i = 0;
00137     while(pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
00138        if((pkcs12SuiteMaps[i].allowed == PR_TRUE) && 
00139           (pkcs12SuiteMaps[i].keyLengthBits > (unsigned int)keyLengthBits) &&
00140           (pkcs12SuiteMaps[i].algTag != SEC_OID_RC4)) {
00141            algorithm = pkcs12SuiteMaps[i].algTag;
00142            keyLengthBits = pkcs12SuiteMaps[i].keyLengthBits;
00143        }
00144        i++;
00145     }
00146 
00147     if(algorithm == SEC_OID_UNKNOWN) {
00148        return SEC_OID_UNKNOWN;
00149     }
00150 
00151     return SEC_PKCS5GetPBEAlgorithm(algorithm, keyLengthBits);
00152 }
00153 
00154 SECStatus
00155 SEC_PKCS12EnableCipher(long which, int on) 
00156 {
00157     int i;
00158 
00159     i = 0;
00160     while(pkcs12SuiteMaps[i].suite != 0L) {
00161        if(pkcs12SuiteMaps[i].suite == (unsigned long)which) {
00162            if(on) {
00163               pkcs12SuiteMaps[i].allowed = PR_TRUE;
00164            } else {
00165               pkcs12SuiteMaps[i].allowed = PR_FALSE;
00166            }
00167            return SECSuccess;
00168        }
00169        i++;
00170     }
00171 
00172     return SECFailure;
00173 }
00174 
00175 SECStatus
00176 SEC_PKCS12SetPreferredCipher(long which, int on)
00177 {
00178     int i;
00179     PRBool turnedOff = PR_FALSE;
00180     PRBool turnedOn = PR_FALSE;
00181 
00182     i = 0;
00183     while(pkcs12SuiteMaps[i].suite != 0L) {
00184        if(pkcs12SuiteMaps[i].preferred == PR_TRUE) {
00185            pkcs12SuiteMaps[i].preferred = PR_FALSE;
00186            turnedOff = PR_TRUE;
00187        }
00188        if(pkcs12SuiteMaps[i].suite == (unsigned long)which) {
00189            pkcs12SuiteMaps[i].preferred = PR_TRUE;
00190            turnedOn = PR_TRUE;
00191        }
00192        i++;
00193     }
00194 
00195     if((turnedOn) && (turnedOff)) {
00196        return SECSuccess;
00197     }
00198 
00199     return SECFailure;
00200 }
00201