• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <objmng/drm_decoder.h>
18 
19 /* global variables */
20 static const uint8_t * base64_alphabet = (const uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
21 
22 #define SKIP_CRLF(p) while('\r' == *(p) || '\n' == *(p)) \
23                          p++
24 
get_alphabet_index(int8_t ch)25 static int8_t get_alphabet_index(int8_t ch)
26 {
27     uint8_t * tmp;
28 
29     if ('=' == ch)
30         return 64;
31 
32     tmp = (uint8_t *)strchr((const char *)base64_alphabet, ch);
33     if (NULL == tmp)
34         return -1;
35 
36     return (int8_t)(tmp - base64_alphabet);
37 }
38 
39 /* See drm_decoder.h */
drm_decodeBase64(uint8_t * dest,int32_t destLen,uint8_t * src,int32_t * srcLen)40 int32_t drm_decodeBase64(uint8_t * dest, int32_t destLen, uint8_t * src, int32_t * srcLen)
41 {
42     int32_t maxDestSize, i, maxGroup;
43     uint8_t *pDest, *pSrc;
44     int8_t tpChar;
45 
46     if (NULL == src || NULL == srcLen || *srcLen <= 0 || destLen < 0)
47         return -1;
48 
49     maxDestSize = (*srcLen) * 3/4;
50     if (NULL == dest || 0 == destLen)
51         return maxDestSize;
52 
53     if (destLen < maxDestSize)
54         maxDestSize = destLen;
55     maxGroup = maxDestSize/3;
56 
57     pDest = dest;   /* start to decode src to dest */
58     pSrc = src;
59     for (i = 0; i < maxGroup && *srcLen - (pSrc - src) >= 4; i++) {
60         SKIP_CRLF(pSrc);
61         if (pSrc - src >= *srcLen)
62             break;
63         tpChar = get_alphabet_index(*pSrc);       /* to first byte */
64         if (-1 == tpChar || 64 == tpChar)
65             return -1;
66         pDest[0] = tpChar << 2;
67         pSrc++;
68         SKIP_CRLF(pSrc);
69         tpChar = get_alphabet_index(*pSrc);
70         if (-1 == tpChar || 64 == tpChar)
71             return -1;
72         pDest[0] |= (tpChar >> 4);
73         pDest[1] = tpChar << 4;                     /* to second byte */
74         pSrc++;
75         SKIP_CRLF(pSrc);
76         tpChar = get_alphabet_index(*pSrc);
77         if (-1 == tpChar)
78             return -1;
79         if (64 == tpChar)           /* end */
80             return pDest - dest + 1;
81         pDest[1] |= (tpChar >> 2);
82         pDest[2] = tpChar << 6;                     /* to third byte */
83         pSrc++;
84         SKIP_CRLF(pSrc);
85         tpChar = get_alphabet_index(*pSrc);
86         if (-1 == tpChar)
87             return -1;
88         if (64 == tpChar)           /* end */
89             return pDest - dest + 2;
90         pDest[2] |= tpChar;
91         pDest += 3;
92         pSrc++;
93     }
94     *srcLen = pSrc - src;
95     return pDest - dest;
96 }
97