Return to signature_params.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / credentials / keys |
1.1 misho 1: /* 2: * Copyright (C) 2017 Tobias Brunner 3: * HSR Hochschule fuer Technik Rapperswil 4: * 5: * This program is free software; you can redistribute it and/or modify it 6: * under the terms of the GNU General Public License as published by the 7: * Free Software Foundation; either version 2 of the License, or (at your 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 9: * 10: * This program is distributed in the hope that it will be useful, but 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13: * for more details. 14: */ 15: 16: #include "signature_params.h" 17: 18: #include <asn1/oid.h> 19: #include <asn1/asn1_parser.h> 20: 21: /* 22: * Described in header 23: */ 24: bool rsa_pss_params_set_salt_len(rsa_pss_params_t *params, size_t modbits) 25: { 26: size_t hash_len; 27: 28: if (params->salt_len < 0) 29: { 30: hash_len = hasher_hash_size(params->hash); 31: if (!hash_len) 32: { 33: return FALSE; 34: } 35: 36: switch (params->salt_len) 37: { 38: case RSA_PSS_SALT_LEN_DEFAULT: 39: params->salt_len = hash_len; 40: break; 41: case RSA_PSS_SALT_LEN_MAX: 42: if (modbits) 43: { 44: /* emBits = modBits - 1 */ 45: modbits -= 1; 46: /* emLen = ceil(emBits/8) */ 47: modbits = (modbits+7) / BITS_PER_BYTE; 48: /* account for 0x01 separator in DB, 0xbc trailing byte */ 49: params->salt_len = max(0, (ssize_t)(modbits - hash_len - 2)); 50: break; 51: } 52: return FALSE; 53: default: 54: return FALSE; 55: } 56: } 57: return TRUE; 58: } 59: 60: /** 61: * Compare two signature schemes and their parameters 62: */ 63: static bool compare_params(signature_params_t *a, signature_params_t *b, 64: bool strict) 65: { 66: if (!a && !b) 67: { 68: return TRUE; 69: } 70: if (!a || !b) 71: { 72: return FALSE; 73: } 74: if (a->scheme != b->scheme) 75: { 76: return FALSE; 77: } 78: if (!a->params && !b->params) 79: { 80: return TRUE; 81: } 82: if (a->params && b->params) 83: { 84: switch (a->scheme) 85: { 86: case SIGN_RSA_EMSA_PSS: 87: { 88: rsa_pss_params_t *pss_a = a->params, *pss_b = b->params; 89: 90: return pss_a->hash == pss_b->hash && 91: pss_a->mgf1_hash == pss_b->mgf1_hash && 92: (!strict || pss_a->salt_len == pss_b->salt_len); 93: } 94: default: 95: break; 96: } 97: } 98: return FALSE; 99: } 100: 101: /* 102: * Described in header 103: */ 104: bool signature_params_equal(signature_params_t *a, signature_params_t *b) 105: { 106: return compare_params(a, b, TRUE); 107: } 108: 109: /* 110: * Described in header 111: */ 112: bool signature_params_comply(signature_params_t *c, signature_params_t *s) 113: { /* the salt is variable, so it does not necessarily have to be the same */ 114: return compare_params(c, s, FALSE); 115: } 116: 117: /* 118: * Described in header 119: */ 120: signature_params_t *signature_params_clone(signature_params_t *this) 121: { 122: signature_params_t *clone; 123: 124: if (!this) 125: { 126: return NULL; 127: } 128: 129: INIT(clone, 130: .scheme = this->scheme, 131: ); 132: if (this->params) 133: { 134: switch (this->scheme) 135: { 136: case SIGN_RSA_EMSA_PSS: 137: { 138: rsa_pss_params_t *pss, *pss_clone; 139: 140: pss = this->params; 141: INIT(pss_clone, 142: .hash = pss->hash, 143: .mgf1_hash = pss->mgf1_hash, 144: .salt_len = pss->salt_len, 145: /* ignore salt as only used for unit tests */ 146: ); 147: clone->params = pss_clone; 148: break; 149: } 150: default: 151: break; 152: } 153: } 154: return clone; 155: } 156: 157: /* 158: * Described in header 159: */ 160: void signature_params_destroy(signature_params_t *this) 161: { 162: if (this) 163: { 164: free(this->params); 165: free(this); 166: } 167: } 168: 169: /* 170: * Described in header 171: */ 172: void signature_params_clear(signature_params_t *this) 173: { 174: if (this) 175: { 176: free(this->params); 177: this->params = NULL; 178: this->scheme = SIGN_UNKNOWN; 179: } 180: } 181: 182: /* 183: * Described in header 184: */ 185: bool signature_params_parse(chunk_t asn1, int level0, 186: signature_params_t *params) 187: { 188: chunk_t parameters = chunk_empty; 189: int oid; 190: 191: oid = asn1_parse_algorithmIdentifier(asn1, level0, ¶meters); 192: params->scheme = signature_scheme_from_oid(oid); 193: switch (params->scheme) 194: { 195: case SIGN_UNKNOWN: 196: return FALSE; 197: case SIGN_RSA_EMSA_PSS: 198: { 199: rsa_pss_params_t *pss = malloc_thing(rsa_pss_params_t); 200: 201: if (!rsa_pss_params_parse(parameters, level0+1, pss)) 202: { 203: DBG1(DBG_IKE, "failed parsing RSASSA-PSS parameters"); 204: free(pss); 205: return FALSE; 206: } 207: params->params = pss; 208: break; 209: } 210: default: 211: params->params = NULL; 212: break; 213: } 214: return TRUE; 215: } 216: 217: /* 218: * Described in header 219: */ 220: bool signature_params_build(signature_params_t *params, chunk_t *asn1) 221: { 222: chunk_t parameters = chunk_empty; 223: int oid; 224: 225: oid = signature_scheme_to_oid(params->scheme); 226: if (oid == OID_UNKNOWN) 227: { 228: return FALSE; 229: } 230: if (params->scheme == SIGN_RSA_EMSA_PSS && 231: !rsa_pss_params_build(params->params, ¶meters)) 232: { 233: return FALSE; 234: } 235: if (parameters.len) 236: { 237: *asn1 = asn1_algorithmIdentifier_params(oid, parameters); 238: } 239: else 240: { 241: *asn1 = asn1_algorithmIdentifier(oid); 242: } 243: return TRUE; 244: } 245: 246: /** 247: * ASN.1 definition of RSASSA-PSS-params 248: */ 249: static const asn1Object_t RSASSAPSSParamsObjects[] = { 250: { 0, "RSASSA-PSS-params", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ 251: { 1, "DEFAULT SHA-1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 1 */ 252: { 2, "hashAlgorithm", ASN1_EOC, ASN1_RAW }, /* 2 */ 253: { 1, "DEFAULT MGF1SHA1", ASN1_CONTEXT_C_1, ASN1_DEF }, /* 3 */ 254: { 2, "maskGenAlgorithm",ASN1_EOC, ASN1_RAW }, /* 4 */ 255: { 1, "DEFAULT 20", ASN1_CONTEXT_C_2, ASN1_DEF }, /* 5 */ 256: { 2, "saltLength", ASN1_INTEGER, ASN1_BODY }, /* 6 */ 257: { 1, "DEFAULT 1", ASN1_CONTEXT_C_3, ASN1_DEF }, /* 7 */ 258: { 2, "trailerField", ASN1_INTEGER, ASN1_BODY }, /* 8 */ 259: { 0, "exit", ASN1_EOC, ASN1_EXIT } 260: }; 261: #define RSASSA_PSS_PARAMS_HASH_ALG 2 262: #define RSASSA_PSS_PARAMS_MGF_ALG 4 263: #define RSASSA_PSS_PARAMS_SALT_LEN 6 264: #define RSASSA_PSS_PARAMS_TRAILER 8 265: 266: /* 267: * Described in header 268: */ 269: bool rsa_pss_params_parse(chunk_t asn1, int level0, rsa_pss_params_t *params) 270: { 271: asn1_parser_t *parser; 272: chunk_t object; 273: int objectID, alg; 274: bool success = FALSE; 275: 276: params->hash = HASH_SHA1; 277: params->mgf1_hash = HASH_SHA1; 278: params->salt_len = HASH_SIZE_SHA1; 279: 280: parser = asn1_parser_create(RSASSAPSSParamsObjects, asn1); 281: parser->set_top_level(parser, level0); 282: 283: while (parser->iterate(parser, &objectID, &object)) 284: { 285: u_int level = parser->get_level(parser)+1; 286: 287: switch (objectID) 288: { 289: case RSASSA_PSS_PARAMS_HASH_ALG: 290: if (object.len) 291: { 292: alg = asn1_parse_algorithmIdentifier(object, level, NULL); 293: params->hash = hasher_algorithm_from_oid(alg); 294: if (params->hash == HASH_UNKNOWN) 295: { 296: goto end; 297: } 298: } 299: break; 300: case RSASSA_PSS_PARAMS_MGF_ALG: 301: if (object.len) 302: { 303: chunk_t hash = chunk_empty; 304: 305: alg = asn1_parse_algorithmIdentifier(object, level, &hash); 306: if (alg != OID_MGF1) 307: { 308: goto end; 309: } 310: if (!hash.len) 311: { 312: goto end; 313: } 314: alg = asn1_parse_algorithmIdentifier(hash, level+1, NULL); 315: params->mgf1_hash = hasher_algorithm_from_oid(alg); 316: if (params->mgf1_hash == HASH_UNKNOWN) 317: { 318: goto end; 319: } 320: } 321: break; 322: case RSASSA_PSS_PARAMS_SALT_LEN: 323: if (object.len) 324: { 325: params->salt_len = (size_t)asn1_parse_integer_uint64(object); 326: } 327: break; 328: case RSASSA_PSS_PARAMS_TRAILER: 329: if (object.len && (object.len != 1 || *object.ptr != 1)) 330: { 331: goto end; 332: } 333: break; 334: default: 335: break; 336: } 337: } 338: success = parser->success(parser); 339: 340: end: 341: parser->destroy(parser); 342: return success; 343: } 344: 345: /* 346: * Described in header 347: */ 348: bool rsa_pss_params_build(rsa_pss_params_t *params, chunk_t *asn1) 349: { 350: chunk_t hash = chunk_empty, mgf = chunk_empty, slen = chunk_empty; 351: int alg; 352: 353: if (params->hash != HASH_SHA1) 354: { /* with SHA-1 we MUST omit the field */ 355: alg = hasher_algorithm_to_oid(params->hash); 356: if (alg == OID_UNKNOWN) 357: { 358: return FALSE; 359: } 360: hash = asn1_algorithmIdentifier(alg); 361: } 362: if (params->mgf1_hash != HASH_SHA1) 363: { /* with MGF1-SHA1 we MUST omit the field */ 364: alg = hasher_algorithm_to_oid(params->mgf1_hash); 365: if (alg == OID_UNKNOWN) 366: { 367: chunk_free(&hash); 368: return FALSE; 369: } 370: mgf = asn1_algorithmIdentifier_params(OID_MGF1, 371: asn1_algorithmIdentifier(alg)); 372: } 373: if (params->salt_len < 0) 374: { 375: chunk_free(&hash); 376: chunk_free(&mgf); 377: return FALSE; 378: } 379: else if (params->salt_len != HASH_SIZE_SHA1) 380: { 381: slen = asn1_integer("m", asn1_integer_from_uint64(params->salt_len)); 382: } 383: *asn1 = asn1_wrap(ASN1_SEQUENCE, "mmm", 384: hash.len ? asn1_wrap(ASN1_CONTEXT_C_0, "m", hash) : chunk_empty, 385: mgf.len ? asn1_wrap(ASN1_CONTEXT_C_1, "m", mgf) : chunk_empty, 386: slen.len ? asn1_wrap(ASN1_CONTEXT_C_2, "m", slen) : chunk_empty); 387: return TRUE; 388: }